"""
Typhon Plotting Interface
"""
############
# Standard #
############
import random
import os.path
import logging
from functools import partial

###############
# Third Party #
###############
from pydm.PyQt import uic
from pydm.PyQt.QtGui import QApplication, QWidget, QBrush
from pydm.PyQt.QtCore import Qt, pyqtSlot

##########
# Module #
##########
from .utils import (ui_dir, channel_from_signal, clean_attr, random_color,
                    clean_name)

logger = logging.getLogger(__name__)

class ChannelDisplay(QWidget):
    """
    Display for a PyDM PlotCurveItem

    Parameters
    ----------
    name : str
        Alias of channel

    color: QColor
        Color of curve in plot
    """
    def __init__(self, name, color, parent=None):
        super().__init__(parent=parent)
        self.ui = uic.loadUi(os.path.join(ui_dir, 'plotitem.ui'), self)
        self.ui.name.setText(name)
        self.ui.color.brush = QBrush(color, Qt.SolidPattern)

class TyphonTimePlot(QWidget):
    """
    Generalized widget for plotting Ophyd signals

    This widget initializes a blank ``PyDMTimePlot`` with a small interface to
    configure the plotted signals. The list of signals available to the
    operator can be controlled via :meth:`.add_available_signal`. Shortcuts can
    be added to the plot itself via :meth:`.add_curve` or the
    :meth:`.creation_requested` ``pyqtSlot`` which takes the current status of
    the requested combinations

    Parameters
    ----------
    parent: QWidget
    """
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        # Load generated user interface file
        self.ui = uic.loadUi(os.path.join(ui_dir, 'plot.ui'), self)
        # Connect create button
        self.create_button.clicked.connect(self.creation_requested)
        # Data structure for name / ChannelDisplay mapping
        self.channel_map = dict()

    def add_available_signal(self, signal, name):
        """
        Add an Ophyd signal to the list of available channels

        If the Signal is not an EPICS Signal object you are responsible for
        registering this yourself, if not already done.

        Parameters
        ----------
        signal: ophyd.Signal

        name: str
            Alias for signal to display in QComboBox
        """
        self.ui.signal_combo.addItem(name, channel_from_signal(signal))

    def add_curve(self, channel, name=None, color=None):
        """
        Add a curve to the plot

        Parameters
        ----------
        channel : str
            PyDMChannel address

        name : str, optional
            Name of TimePlotCurveItem. If None is given, the ``channel`` is
            used.

        color: QColor, optional
            Color to display line in plot. If None is given, a QColor will be
            chosen randomly
        """
        name = name or channel
        # Do not allow duplicate channels
        if name in self.channel_map:
            logger.error("%r already has been added to the plot", name)
            return
        logger.debug("Adding %s to plot ...", channel)
        # Create a random color if None is supplied
        if not color:
            color = random_color()
        # Add to plot
        self.ui.timeplot.addYChannel(y_channel=channel, color=color,
                                     name=name, lineStyle=Qt.SolidLine,
                                     lineWidth=2, symbol=None)
        # Add a display to the LiveChannel display
        ch_display = ChannelDisplay(name, color)
        self.ui.live_channels.layout().insertWidget(0, ch_display)
        self.channel_map[name] = ch_display
        # Connect the removal button to the slot
        ch_display.remove_button.clicked.connect(partial(self.remove_curve,
                                                         name))
        # Establish connections for new instance
        pydm_app = QApplication.instance()
        pydm_app.establish_widget_connections(self)
        # Select new random color
        self.ui.color.brush = QBrush(random_color(), Qt.SolidPattern)

    @pyqtSlot()
    def remove_curve(self, name):
        """
        Remove a curve from the plot

        Parameters
        ----------
        name: str
            Name of the curve to remove. This should match the name given
            during the call of :meth:`.add_curve`
        """
        if name in self.channel_map:
            logger.debug("Removing %s from DeviceTimePlot ...", name)
            self.ui.timeplot.removeCurveWithName(name)
            # Remove ChannelDisplay
            ch_display = self.channel_map.pop(name)
            self.ui.live_channels.layout().removeWidget(ch_display)
            # Destroy ChannelDisplay
            ch_display.deleteLater()
        else:
            logger.error("Curve %r was not found in DeviceTimePlot", name)

    @pyqtSlot()
    def creation_requested(self):
        """
        Reaction to ``create_button`` press

        Observes the state of the selection widgets and makes the appropriate
        call to :meth:`.add_curve`
        """
        # Find requested channel
        name = self.ui.signal_combo.currentText()
        idx = self.ui.signal_combo.currentIndex()
        channel = self.ui.signal_combo.itemData(idx)
        # Add to the plot
        self.add_curve(channel, name=name, color=self.ui.color.brush.color())

class DeviceTimePlot(TyphonTimePlot):
    """
    TyphonTimePlot auto-populated by a Device

    The device is inspected for all scalar signals and are made available for
    the operator to select. Device hints are automatically added to the plot.

    Parameters
    ----------
    device : ophyd.Device

    parent: QWidget, object
    """
    def __init__(self, device, parent=None):
        super().__init__(parent=parent)
        self.device = device
        # Seed so that our colors are consistent
        random.seed(54321343)
        # Sort through components
        devices = [self.device] + [getattr(device, sub)
                                   for sub in device._sub_devices]
        for device in devices:
            for component in device.component_names:
                # Find all signals
                if component not in device._sub_devices:
                    try:
                        sig = getattr(device, component)
                        # Only include scalars
                        if sig.describe()[sig.name]['dtype'] in ('integer',
                                                                 'number'):
                            # Make component name
                            name = clean_attr(component)
                            if device != self.device:
                                name = ' '.join((clean_name(device), name))
                            # Add to list of available signals
                            self.add_available_signal(sig, name)
                            # Automatically plot if in Device hints
                            if sig.name in device.hints.get('fields', []):
                                self.add_curve(channel_from_signal(sig),
                                               name=name)
                    except Exception as exc:
                        logger.exception("Unable to add %s to "
                                         "plot-able signals",
                                         component)


"""
Assignment 2: Decision Trees
Part 2

@author: Divyam Jain
         17HS20047
"""

#Importing some essential libraries

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math

#Importing the dataset

words = np.loadtxt('words.txt', dtype='str')

traindata = np.loadtxt('traindata.txt')
trainlabel = np.loadtxt('trainlabel.txt')
testdata = np.loadtxt('testdata.txt')
testlabel = np.loadtxt('testlabel.txt')

dataset_train = np.zeros((len(trainlabel),len(words)+1),dtype=int)
dataset_train[:,-1] = trainlabel[:]-1
for i in range(len(traindata)):
    dataset_train[int(traindata[i,0])-1,int(traindata[i,1])-1]+=1

dataset_test = np.zeros((len(testlabel),len(words)+1),dtype=int)
dataset_test[:,-1] = testlabel[:]-1
for i in range(len(testdata)):
    dataset_test[int(testdata[i,0])-1,int(testdata[i,1])-1]+=1

#Calculating Information Gain

def info_gain (df):

    mat=np.zeros((2,2))
    for i in range(len(df)):
        mat[df[i,0],df[i,1]]+=1

    x = np.sum(mat,axis=0)
    entropy_before =  -x[0]/(x[0]+x[1])*math.log2(x[0]/(x[0]+x[1]))-x[1]/(x[0]+x[1])*math.log2(x[1]/(x[0]+x[1]))

    val=0
    for i in range(len(mat)):
        a=mat[i,0]
        b=mat[i,1]

        if a!=0 and b!=0:
            val = val-a*(math.log2(a/(a+b)))-b*(math.log2(b/(a+b)))

    entropy_after = val/len(df)

    return entropy_before-entropy_after

#Spliting Dataset

def split (feature, dataset):

    B = []
    for j in [0,1]:
        B.append(dataset[dataset[:,feature]==j])

    return B

#Making Decison Tree using Information Gain

def best_split_info(feature_set, data, level, temp, depth):

    if(len(data[data[:,-1]==0])==len(data)):
        print(':alt.atheism', end='')
        temp['label'] = 0
    elif(len(data[data[:,-1]==1])==len(data)):
        print(':comp.graphics', end='')
        temp['label'] = 1

    elif level==depth:
        if(len(data)>0):
            count_0 = len(data[data[:,-1]==0])
            if count_0 >= len(data)-count_0:
                print(':alt.atheism', end='')
                temp['label'] = 0
            else:
                print(':comp.graphics', end='')
                temp['label'] = 1
    elif len(data)==0:
        pass

    else:

        A =[]
        for i in feature_set:
            A.append(info_gain(data[:,[i,-1]]))

        best_feature = A.index(max(A))
        B = split(best_feature, data)

        temp[best_feature] = {}
        temp = temp[best_feature]

        #feature_set.remove(best_feature)

        for i in [0,1]:

            if level>=1:
                if len(B[i])!=0:
                    print('\n')
                    for j in range(1,level):
                        print('\t', end ='')
                    print('|', end='')
                    print(best_feature,'=',sep='', end='')
                    print(i, end='')
                    temp[i]={}

            else:
                if len(B[i])!=0:
                    print('\n')
                    print(best_feature,'=',sep='', end='')
                    print(i, end='')
                    temp[i]={}

            best_split_info(feature_set, B[i], level+1, temp[i], depth)

#Predicting labels of Data

def predict (row, tree):
    while(list(tree.keys())[0]!='label'):
        x=row[list(tree.keys())[0]]
        tree = tree[list(tree.keys())[0]]
        tree = tree[x]
    return tree['label']

#Using Information Gain

dep = int(input('What is the required depth? '))

print('\n\n---Decision Tree using Information Gain---', end='')
model = {}
temp=model
feature_set=np.arange(0,len(words))
best_split_info(feature_set, dataset_train, 0, temp, dep)

#Getting Accuracies for varied depths

max_depth = 25
acc_train=[]
acc_test=[]

for j in range(1,max_depth):

    print('\n\n---Decision Tree using Information Gain---  max_depth =',j, end='')
    best_split_info(feature_set, dataset_train, 0, temp, j)

    #Finding Training Data accuracy

    pred = []

    for k in range(len(dataset_train)):
        pred.append(predict(dataset_train[k,:-1],model))

    count = 0
    for i in range(len(pred)):
        if dataset_train[i,-1]==pred[i]:
            count+=1
    accuracy = count/len(pred)*100

    acc_train.append(accuracy)

    #Finding Test Data accuracy

    pred = []

    for k in range(len(dataset_test)):
        pred.append(predict(dataset_test[k,:-1],model))

    count = 0
    for i in range(len(pred)):
        if dataset_test[i,-1]==pred[i]:
            count+=1
    accuracy = count/len(pred)*100

    acc_test.append(accuracy)

#Plotting graphs

plt.plot(np.arange(1,max_depth), acc_train, color = 'blue')
plt.plot(np.arange(1,max_depth), acc_test, color = 'red')
plt.title('Training(Blue) and Test(Red) Accuracy for various maximum depths')
plt.xlabel('Maximium Depth')
plt.ylabel('Accuracies')
plt.show()

#Using Scikit Learn

from sklearn.tree import DecisionTreeClassifier

classifier = DecisionTreeClassifier(criterion='entropy',random_state=0)
classifier.fit(dataset_train[:,:-1],dataset_train[:,-1])

scipred = classifier.predict(dataset_test[:,:-1])

count = 0
for i in range(len(scipred)):
    if dataset_test[i,-1]==scipred[i]:
        count+=1
sciaccuracy = count/len(scipred)*100

Assignment 2 - Decision Tree/Part2_A2.py


#!/usr/bin/python3

from API_Caller import CallAPI
import hashlib
import os
import platform
import datetime
import math
import sys
from requests_toolbelt import MultipartEncoder

class Upload:

    def __init__(self, Credentials, filename='', full_path=''):
        self.AppKey = Credentials.AppKey
        self.AccessToken = Credentials.AccessToken
        self.AsUser = Credentials.AsUser
        self.filename = filename
        self.max_chunk_size = 5242880
        if platform.system() == 'Windows':
            separator = '\\'
        else:
            separator = '/'
        self.full_path = full_path + separator + self.filename

    def read_in_chunks(self, file_object):
        while True:
            data = file_object.read(self.max_chunk_size)
            if not data:
                break
            yield data

    def creation_date(self):
        if platform.system() == 'Windows':
            return datetime.datetime.fromtimestamp(os.path.getctime(self.full_path)).isoformat()
        else:
            stat = os.stat(self.full_path)
            try:
                return datetime.datetime.fromtimestamp(stat.st_ctime).isoformat()
            except AttributeError:
                return datetime.datetime.fromtimestamp(stat.st_mtime).isoformat()

    def Upload(self, Syncpoint_ID, Path):
        Method = "POST"
        creation_date = self.creation_date()
        last_write_time = datetime.datetime.fromtimestamp(os.path.getmtime(self.full_path)).isoformat()
        url = "saveFile.php?filepath=" + Path
        login_headers = {'As-User': '%s' % self.AsUser, "User-Agent": "API_Application"}
        file_size = os.path.getsize(self.full_path)
        if file_size < self.max_chunk_size:
            login_headers["Content-Range"] = "0-*/*"
            multipart_body = [('fileData', ('%s' % self.filename, open('%s' % self.full_path, 'rb'),
                                            'application/octet-stream')),
                              ('sha256', (None, hashlib.sha256(self.full_path.encode('utf-8')).hexdigest(), None)),
                              ('sessionKey', (None, 'Bearer ' + self.AccessToken, None)),
                              ('virtualFolderId', (None, '%s' % Syncpoint_ID, None)),
                              ('creationTimeUtc', (None, creation_date, None)),
                              ('lastWriteTimeUtc', (None, last_write_time, None)),
                              ('fileDone', (None, '', None))]
            request = CallAPI(url, self.AppKey, self.AccessToken, Method, login_headers, data='',
                              file=multipart_body, base_url="https://data.syncplicity.com/").MakeRequest()
            return request

        else:
                first_call_headers = {'As-User': '%s' % self.AsUser,
                                      "User-Agent": "API_Application",
                                      'Content-Range': "*/*"}
                first_call_body = MultipartEncoder({'sessionKey': (None, 'Bearer ' + self.AccessToken, None)})
                first_call_headers['Content-Type'] = first_call_body.content_type
                first_call_response = CallAPI(url, self.AppKey, self.AccessToken, Method, first_call_headers,
                                              data=first_call_body,
                                              base_url="https://data.syncplicity.com/").MakeRequest()
                if first_call_response.status_code == 308:
                    login_headers['If-Match'] = first_call_response.headers['ETag']
                else:
                    sys.exit('Failed to create session for chunked upload')
                chunk_count = math.ceil(file_size / self.max_chunk_size)
                f = open(self.full_path, 'rb')

                content_range_index = 0
                sent_chunk_count = 1

                for chunk in self.read_in_chunks(f):
                    login_headers['Content-Range'] = '%s-*/*' % content_range_index
                    content_range_index += self.max_chunk_size
                    if sent_chunk_count == chunk_count:
                        multipart_body = MultipartEncoder({'fileData': (self.filename, chunk,
                                                                        'application/octet-stream'),
                                                           'sha256': (None, hashlib.sha256(chunk).hexdigest(), None),
                                                           'sessionKey': (None, 'Bearer ' + self.AccessToken, None),
                                                           'virtualFolderId': (None, '%s' % Syncpoint_ID, None),
                                                           'creationTimeUtc': (None, creation_date, None),
                                                           'lastWriteTimeUtc': (None, last_write_time, None),
                                                           'fileDone': (None, '', None)})
                    else:
                        multipart_body = MultipartEncoder({'fileData': (self.filename, chunk,
                                                                        'application/octet-stream'),
                                                           'sha256': (None, hashlib.sha256(chunk).hexdigest(), None),
                                                           'sessionKey': (None, 'Bearer ' + self.AccessToken, None),
                                                           'virtualFolderId': (None, '%s' % Syncpoint_ID, None),
                                                           'creationTimeUtc': (None, creation_date, None),
                                                           'lastWriteTimeUtc': (None, last_write_time, None)})
                    login_headers['Content-Type'] = multipart_body.content_type
                    sent_chunk_count += 1
                    request = CallAPI(url, self.AppKey, self.AccessToken, Method, login_headers,
                                      data=multipart_body, base_url="https://data.syncplicity.com/").MakeRequest()
                    if request.status_code == 308:
                        login_headers['If-Match'] = request.headers['ETag']
                    else:
                        f.close()
                        return request


from __future__ import print_function, division

from ..basis import spin_basis_1d as _default_basis
from ..basis import isbasis as _isbasis

from ._make_hamiltonian import make_static

from . import hamiltonian_core

# need linear algebra packages
import scipy.sparse.linalg as _sla
import scipy.linalg as _la
import scipy.sparse as _sp
import numpy as _np

import functools
from six import iteritems,itervalues,viewkeys

__all__=["quantum_operator","isquantum_operator"]

# function used to create Linearquantum_operator with fixed set of parameters.
def _quantum_operator_dot(op,pars,v):
	return op.dot(v,pars=pars,check=False)

class quantum_operator(object):
	"""Constructs parameter-dependent (hermitian and nonhermitian) operators.

		The `quantum_operator` class maps quantum operators to keys of a dictionary. When calling various methods
		of `quantum_operator`, it allows one to 'dynamically' specify the pre-factors of these operators.

		Examples
		---------

		It is often required to be able to handle a parameter-dependent Hamiltonian :math:`H(\\lambda)=H_1 + \\lambda H_2`, e.g.

		.. math::
			H_1=\sum_j J_{zz}S^z_jS^z_{j+1} + h_xS^x_j, \\qquad H_2=\\sum_j S^z_j

		The following code snippet shows how to use the `quantum_operator` class to vary the parameter :math:`\\lambda`
		without having to re-build the Hamiltonian every time.

		.. literalinclude:: ../../doc_examples/quantum_operator-example.py
			:linenos:
			:language: python
			:lines: 7-

	"""
	def __init__(self,input_dict,N=None,basis=None,shape=None,copy=True,check_symm=True,check_herm=True,check_pcon=True,dtype=_np.complex128,**basis_args):
		"""Intializes the `quantum_operator` object (parameter dependent quantum quantum_operators).

		Parameters
		-----------
		input_dict : dict
			The `values` of this dictionary contain quantum_operator lists, in the same format as the `static_list`
			argument of the `hamiltonian` class.

			The `keys` of this dictionary correspond to the parameter values, e.g. :math:`J_{zz},h_x`, and are
			used to specify the coupling strength during calls of the `quantum_operator` class methods.

			>>> # use "Jzz" and "hx" keys to specify the zz and x coupling strengths, respectively
			>>> input_dict = { "Jzz": [["zz",Jzz_bonds]], "hx" : [["x" ,hx_site ]] }

		N : int, optional
			Number of lattice sites for the `hamiltonian` object.
		dtype : 'type'
			Data type (e.g. numpy.float64) to construct the quantum_operator with.
		shape : tuple, optional
			Shape to create the `hamiltonian` object with. Default is `shape = None`.
		copy: bool, optional
			If set to `True`, this option creates a copy of the input array.
		check_symm : bool, optional
			Enable/Disable symmetry check on `static_list` and `dynamic_list`.
		check_herm : bool, optional
			Enable/Disable hermiticity check on `static_list` and `dynamic_list`.
		check_pcon : bool, optional
			Enable/Disable particle conservation check on `static_list` and `dynamic_list`.
		kw_args : dict
			Optional additional arguments to pass to the `basis` class, if not already using a `basis` object
			to create the quantum_operator.

		"""
		self._is_dense = False
		self._ndim = 2
		self._basis = basis

		if not (dtype in hamiltonian_core.supported_dtypes):
			raise TypeError('hamiltonian does not support type: '+str(dtype))
		else:
			self._dtype=dtype

		opstr_dict = {}
		other_dict = {}
		self._quantum_operator = {}
		if isinstance(input_dict,dict):
			for key,op in input_dict.items():
				if type(key) is not str:
					raise ValueError("keys to input_dict must be strings.")

				if type(op) not in [list,tuple]:
					raise ValueError("input_dict must contain values which are lists/tuples.")
				opstr_list = []
				other_list = []
				for ele in op:
					if hamiltonian_core._check_static(ele):
						opstr_list.append(ele)
					else:
						other_list.append(ele)

				if opstr_list:
					opstr_dict[key] = opstr_list
				if other_list:
					other_dict[key] = other_list
		elif isinstance(input_dict,quantum_operator):
			other_dict = {key:[value] for key,value in input_dict._quantum_operator_dict.items()}
		else:
			raise ValueError("input_dict must be dictionary or another quantum_operator quantum_operators")

		if opstr_dict:
			# check if user input basis

			if basis is not None:
				if len(basis_args) > 0:
					wrong_keys = set(basis_args.keys())
					temp = ", ".join(["{}" for key in wrong_keys])
					raise ValueError(("unexpected optional argument(s): "+temp).format(*wrong_keys))

			# if not
			if basis is None:
				if N is None: # if L is missing
					raise Exception('if opstrs in use, argument N needed for basis class')

				if type(N) is not int: # if L is not int
					raise TypeError('argument N must be integer')

				basis=_default_basis(N,**basis_args)

			elif not _isbasis(basis):
				raise TypeError('expecting instance of basis class for argument: basis')

			static_opstr_list = []
			for key,opstr_list in iteritems(opstr_dict):
				static_opstr_list.extend(opstr_list)

			if check_herm:
				basis.check_hermitian(static_opstr_list, [])

			if check_symm:
				basis.check_symm(static_opstr_list,[])

			if check_pcon:
				basis.check_pcon(static_opstr_list,[])

			self._shape=(basis.Ns,basis.Ns)

			for key,opstr_list in iteritems(opstr_dict):
				self._quantum_operator[key]=make_static(basis,opstr_list,dtype)

		if other_dict:
			if not hasattr(self,"_shape"):
				found = False
				if shape is None: # if no shape argument found, search to see if the inputs have shapes.
					for key,O_list in iteritems(other_dict):
						for O in O_list:
							try: # take the first shape found
								shape = O.shape
								found = True
								break
							except AttributeError:
								continue
				else:
					found = True

				if not found:
					raise ValueError('no dictionary entries have shape attribute.')
				if shape[0] != shape[1]:
					raise ValueError('quantum_operator must be square matrix')

				self._shape=shape

			for key,O_list in iteritems(other_dict):
				for i,O in enumerate(O_list):
					if _sp.issparse(O):
						self._mat_checks(O)
						if i == 0:
							self._quantum_operator[key] = O
						else:
							try:
								self._quantum_operator[key] += O
							except NotImplementedError:
								self._quantum_operator[key] = self._quantum_operator[key] + O

					elif O.__class__ is _np.ndarray:
						self._mat_checks(O)
						self._is_dense=True
						if i == 0:
							self._quantum_operator[key] = O
						else:
							try:
								self._quantum_operator[key] += O
							except NotImplementedError:
								self._quantum_operator[key] = self._quantum_operator[key] + O

					elif O.__class__ is _np.matrix:
						self._mat_checks(O)
						self._is_dense=True
						if i == 0:
							self._quantum_operator[key] = O
						else:
							try:
								self._quantum_operator[key] += O
							except NotImplementedError:
								self._quantum_operator[key] = self._quantum_operator[key] + O

					else:
						O = _np.asanyarray(O)
						self._mat_checks(O)
						if i == 0:
							self._quantum_operator[key] = O
						else:
							try:
								self._quantum_operator[key] += O
							except NotImplementedError:
								self._quantum_operator[key] = self._quantum_operator[key] + O

		else:
			if not hasattr(self,"_shape"):
				if shape is None:
					# check if user input basis
					basis=basis_args.get('basis')

					# if not
					if basis is None:
						if N is None: # if N is missing
							raise Exception("argument N or shape needed to create empty hamiltonian")

						if type(N) is not int: # if L is not int
							raise TypeError('argument N must be integer')

						basis=_default_basis(N,**basis_args)

					elif not _isbasis(basis):
						raise TypeError('expecting instance of basis class for argument: basis')

					shape = (basis.Ns,basis.Ns)

				else:
					basis=basis_args.get('basis')
					if not basis is None:
						raise ValueError("empty hamiltonian only accepts basis or shape, not both")

				if len(shape) != 2:
					raise ValueError('expecting ndim = 2')
				if shape[0] != shape[1]:
					raise ValueError('hamiltonian must be square matrix')

				self._shape=shape

		if basis is not None:
			self._basis = basis

		self._Ns = self._shape[0]

	@property
	def basis(self):
		""":obj:`basis`: basis used to build the `hamiltonian` object. Defaults to `None` if quantum_operator has
		no basis (i.e. was created externally and passed as a precalculated array).

		"""
		if self._basis is not None:
			return self._basis
		else:
			raise AttributeError("object has no attribute 'basis'")

	@property
	def ndim(self):
		"""int: number of dimensions, always equal to 2. """
		return self._ndim

	@property
	def Ns(self):
		"""int: number of states in the (symmetry-reduced) Hilbert space spanned by `basis`."""
		return self._Ns

	@property
	def get_shape(self):
		"""tuple: shape of the `quantum_operator` object, always equal to `(Ns,Ns)`."""
		return self._shape

	@property
	def is_dense(self):
		"""bool: `True` if the quantum_operator contains a dense matrix as a componnent of either
		the static or dynamic lists.

		"""
		return self._is_dense

	@property
	def dtype(self):
		"""type: data type of `quantum_operator` object."""
		return _np.dtype(self._dtype).name

	@property
	def T(self):
		""":obj:`quantum_operator`: transposes the operator matrix: :math:`H_{ij}\\mapsto H_{ji}`."""
		return self.transpose()

	@property
	def H(self):
		""":obj:`quantum_operator`: transposes and conjugates the operator matrix: :math:`H_{ij}\\mapsto H_{ji}^*`."""
		return self.getH()

	### state manipulation/observable routines

	def matvec(self,x):
		"""Matrix-vector multiplication.

		Performs the operation y=A*x where A is an MxN linear operator and x is a column vector or 1-d array.

		Notes
		-----
		This matvec wraps the user-specified matvec routine or overridden _matvec method to ensure that y has the correct shape and type.

		Parameters
		----------
		x : {matrix, ndarray}
			An array with shape (N,) or (N,1).

		Returns
		-------
		y : {matrix, ndarray}
			A matrix or ndarray with shape (M,) or (M,1) depending on the type and shape of the x argument.

		"""

		return self.dot(x)

	def rmatvec(self,x):
		"""Adjoint matrix-vector multiplication.

		Performs the operation y = A^H * x where A is an MxN linear operator and x is a column vector or 1-d array.

		Notes
		-----
		This rmatvec wraps the user-specified rmatvec routine or overridden _rmatvec method to ensure that y has the correct shape and type.

		Parameters
		----------
		x : {matrix, ndarray}
			An array with shape (M,) or (M,1).

		Returns
		-------
		y : {matrix, ndarray}
			A matrix or ndarray with shape (N,) or (N,1) depending on the type and shape of the x argument.

		"""
		return self.H.dot(x)

	def matmat(self,X):
		"""Matrix-matrix multiplication.

		Performs the operation y=A*X where A is an MxN linear operator and X dense N*K matrix or ndarray.

		Notes
		-----
		This matmat wraps any user-specified matmat routine or overridden _matmat method to ensure that y has the correct type.

		Parameters
		----------
		X : {matrix, ndarray}
			An array with shape (N,K).

		Returns
		-------
		Y : {matrix, ndarray}
			A matrix or ndarray with shape (M,K) depending on the type of the X argument.

		"""
		return self.dot(X)

	def dot(self,V,pars={},check=True):
		"""Matrix-vector multiplication of `quantum_operator` quantum_operator for parameters `pars`, with state `V`.

		.. math::
			H(t=\\lambda)|V\\rangle

		Notes
		-----
		It is faster to multiply the individual (static, dynamic) parts of the Hamiltonian first, then add all those
		vectors together.

		Parameters
		-----------
		V : numpy.ndarray
			Vector (quantums tate) to multiply the `quantum_operator` quantum_operator with.
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		check : bool, optional
			Whether or not to do checks for shape compatibility.

		Returns
		--------
		numpy.ndarray
			Vector corresponding to the `quantum_operator` quantum_operator applied on the state `V`.

		Examples
		---------
		>>> B = H.dot(A,pars=pars,check=True)

		corresponds to :math:`B = HA`.

		"""

		if self.Ns <= 0:
			return _np.asarray([])

		pars = self._check_scalar_pars(pars)

		if not check:
			result_dtype = _np.result_type(V,self._dtype)
			V_dot = _np.zeros(V.shape,dtype=result_dtype)
			for key,J in pars.items():
				V_dot += J*self._quantum_operator[key].dot(V)
			return V_dot

		if V.ndim > 2:
			raise ValueError("Expecting V.ndim < 3.")

		if V.__class__ is _np.ndarray:
			if V.shape[0] != self._shape[1]:
				raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V.shape,self._shape))

			result_dtype = _np.result_type(V,self._dtype)
			V_dot = _np.zeros(V.shape,dtype=result_dtype)
			for key,J in pars.items():
				V_dot += J*self._quantum_operator[key].dot(V)

		elif _sp.issparse(V):
			if V.shape[0] != self._shape[1]:
				raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V.shape,self._shape))

			result_dtype = _np.result_type(V,self._dtype)
			V_dot = _np.zeros(V.shape,dtype=result_dtype)
			for key,J in pars.items():
				V_dot += J*self._quantum_operator[key].dot(V)

		elif V.__class__ is _np.matrix:
			if V.shape[0] != self._shape[1]:
				raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V.shape,self._shape))

			result_dtype = _np.result_type(V,self._dtype)
			V_dot = _np.zeros(V.shape,dtype=result_dtype)
			for key,J in pars.items():
				V_dot += J*self._quantum_operator[key].dot(V)

		else:
			V = _np.asanyarray(V)
			if V.ndim not in [1,2]:
				raise ValueError("Expecting 1 or 2 dimensional array")

			if V.shape[0] != self._shape[1]:
				raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V.shape,self._shape))

			result_dtype = _np.result_type(V,self._dtype)
			V_dot = _np.zeros(V.shape,dtype=result_dtype)
			for key,J in pars.items():
				V_dot += J*self._quantum_operator[key].dot(V)

		return V_dot

	def rdot(self,V,pars={},check=False):
		"""Vector-matrix multiplication of `quantum_operator` quantum_operator for parameters `pars`, with state `V`.

		.. math::
			\\langle V]H(t=\\lambda)

		Parameters
		-----------
		V : numpy.ndarray
			Vector (quantums tate) to multiply the `quantum_operator` quantum_operator with.
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		check : bool, optional
			Whether or not to do checks for shape compatibility.

		Returns
		--------
		numpy.ndarray
			Vector corresponding to the `quantum_operator` quantum_operator applied on the state `V`.

		Examples
		---------
		>>> B = H.dot(A,pars=pars,check=True)

		corresponds to :math:`B = AH`.

		"""
		try:
			V = V.transpose()
		except AttributeError:
			V = _np.asanyarray(V)
			V = V.transpose()
		return (self.transpose().dot(V,pars=pars,check=check)).transpose()

	def matrix_ele(self,Vl,Vr,pars={},diagonal=False,check=True):
		"""Calculates matrix element of `quantum_operator` quantum_operator for parameters `pars` in states `Vl` and `Vr`.

		.. math::
			\\langle V_l|H(\\lambda)|V_r\\rangle

		Notes
		-----
		Taking the conjugate or transpose of the state `Vl` is done automatically.

		Parameters
		-----------
		Vl : numpy.ndarray
			Vector(s)/state(s) to multiple with on left side.
		Vl : numpy.ndarray
			Vector(s)/state(s) to multiple with on right side.
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		diagonal : bool, optional
			When set to `True`, returs only diagonal part of expectation value. Default is `diagonal = False`.
		check : bool,

		Returns
		--------
		float
			Matrix element of `quantum_operator` quantum_operator between the states `Vl` and `Vr`.

		Examples
		---------
		>>> H_lr = H.expt_value(Vl,Vr,pars=pars,diagonal=False,check=True)

		corresponds to :math:`H_{lr} = \\langle V_l|H(\\lambda=0)|V_r\\rangle`.

		"""
		if self.Ns <= 0:
			return _np.array([])

		pars = self._check_scalar_pars(pars)

		Vr=self.dot(Vr,pars=pars,check=check)

		if not check:
			if diagonal:
				return _np.einsum("ij,ij->j",Vl.conj(),Vr)
			else:
				return Vl.T.conj().dot(Vr)

		if Vl.__class__ is _np.ndarray:
			if Vl.ndim == 1:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

				return Vl.conj().dot(Vr)
			elif Vl.ndim == 2:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

				if diagonal:
					return _np.einsum("ij,ij->j",Vl.conj(),Vr)
				else:
					return Vl.T.conj().dot(Vr)
			else:
				raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

		elif Vl.__class__ is _np.matrix:
			if Vl.ndim == 1:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

				return Vl.conj().dot(Vr)
			elif Vl.ndim == 2:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

				if diagonal:
					return _np.einsum("ij,ij->j",Vl.conj(),Vr)
				else:
					return Vl.H.dot(Vr)
			else:
				raise ValueError('Expecting Vl to have ndim < 3')

		elif _sm.issparse(Vl):
			if Vl.ndim == 2:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError('dimension mismatch')
				if diagonal:
					return Vl.H.dot(Vr).diagonal()
				else:
					return Vl.H.dot(Vr)
			else:
				raise ValueError('Expecting Vl to have ndim < 3')

		else:
			Vl = _np.asanyarray(Vl)
			if Vl.ndim == 1:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))
				if diagonal:
					return _np.einsum("ij,ij->j",Vl.conj(),Vr)
				else:
					return Vl.conj().dot(Vr)
			elif Vl.ndim == 2:
				if Vl.shape[0] != self._shape[1]:
					raise ValueError("matrix dimension mismatch with shapes: {0} and {1}.".format(V1.shape,self._shape))

				return Vl.T.conj().dot(Vr)
			else:
				raise ValueError('Expecting Vl to have ndim < 3')

	### Diagonalisation routines

	def eigsh(self,pars={},**eigsh_args):
		"""Computes SOME eigenvalues of hermitian `quantum_operator` quantum_operator using SPARSE hermitian methods.

		This function method solves for eigenvalues and eigenvectors, but can only solve for a few of them accurately.
		It calls `scipy.sparse.linalg.eigsh <https://docs.scipy.org/doc/scipy/reference/generated/generated/scipy.sparse.linalg.eigsh.html>`_, which is a wrapper for ARPACK.

		Notes
		-----
		Assumes the quantum_operator is hermitian! If the flat `check_hermiticity = False` is used, we advise the user
		to reassure themselves of the hermiticity properties before use.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		eigsh_args :
			For all additional arguments see documentation of `scipy.sparse.linalg.eigsh <https://docs.scipy.org/doc/scipy/reference/generated/generated/scipy.sparse.linalg.eigsh.html>`_.

		Returns
		--------
		tuple
			Tuple containing the `(eigenvalues, eigenvectors)` of the `quantum_operator` quantum_operator.

		Examples
		---------
		>>> eigenvalues,eigenvectors = H.eigsh(pars=pars,**eigsh_args)

		"""
		if self.Ns == 0:
			return _np.array([]),_np.array([[]])

		return _sla.eigsh(self.tocsr(pars),**eigsh_args)

	def eigh(self,pars={},**eigh_args):
		"""Computes COMPLETE eigensystem of hermitian `quantum_operator` quantum_operator using DENSE hermitian methods.

		This function method solves for all eigenvalues and eigenvectors. It calls
		`numpy.linalg.eigh <https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.linalg.eigh.html>`_,
		and uses wrapped LAPACK functions which are contained in the module py_lapack.

		Notes
		-----
		Assumes the quantum_operator is hermitian! If the flat `check_hermiticity = False` is used, we advise the user
		to reassure themselves of the hermiticity properties before use.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		eigh_args :
			For all additional arguments see documentation of `numpy.linalg.eigh <https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.linalg.eigh.html>`_.

		Returns
		--------
		tuple
			Tuple containing the `(eigenvalues, eigenvectors)` of the `quantum_operator` quantum_operator.

		Examples
		---------
		>>> eigenvalues,eigenvectors = H.eigh(pars=pars,**eigh_args)

		"""
		eigh_args["overwrite_a"] = True

		if self.Ns <= 0:
			return _np.asarray([]),_np.asarray([[]])

		# fill dense array with hamiltonian
		H_dense = self.todense(pars=pars)
		# calculate eigh
		E,H_dense = _la.eigh(H_dense,**eigh_args)
		return E,H_dense

	def eigvalsh(self,pars={},**eigvalsh_args):
		"""Computes ALL eigenvalues of hermitian `quantum_operator` quantum_operator using DENSE hermitian methods.

		This function method solves for all eigenvalues. It calls
		`numpy.linalg.eigvalsh <https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.linalg.eigvalsh.html#numpy.linalg.eigvalsh>`_,
		and uses wrapped LAPACK functions which are contained in the module py_lapack.

		Notes
		-----
		Assumes the quantum_operator is hermitian! If the flat `check_hermiticity = False` is used, we advise the user
		to reassure themselves of the hermiticity properties before use.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		eigvalsh_args :
			For all additional arguments see documentation of `numpy.linalg.eigvalsh <https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.linalg.eigvalsh.html#numpy.linalg.eigvalsh>`_.

		Returns
		--------
		numpy.ndarray
			Eigenvalues of the `quantum_operator` quantum_operator.

		Examples
		---------
		>>> eigenvalues = H.eigvalsh(pars=pars,**eigvalsh_args)

		"""

		if self.Ns <= 0:
			return _np.asarray([])

		H_dense = self.todense(pars=pars)
		E = _np.linalg.eigvalsh(H_dense,**eigvalsh_args)
		#eigvalsh_args["overwrite_a"] = True
		#E = _la.eigvalsh(H_dense,**eigvalsh_args)
		return E

	### routines to change object type

	def tocsr(self,pars={}):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a `scipy.sparse.csr_matrix`.

		Casts the `quantum_operator` object as a
		`scipy.sparse.csr_matrix <https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html>`_
		object.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		:obj:`scipy.sparse.csr_matrix`

		Examples
		---------
		>>> H_csr=H.tocsr(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)

		H = _sp.csr_matrix(self.get_shape,dtype=self._dtype)

		for key,J in pars.items():
			try:
				H += J*_sp.csr_matrix(self._quantum_operator[key])
			except:
				H = H + J*_sp.csr_matrix(self._quantum_operator[key])

		return H

	def tocsc(self,pars={}):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a `scipy.sparse.csc_matrix`.

		Casts the `quantum_operator` object as a
		`scipy.sparse.csc_matrix <https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csc_matrix.html>`_
		object.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		:obj:`scipy.sparse.csc_matrix`

		Examples
		---------
		>>> H_csc=H.tocsc(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)

		H = _sp.csc_matrix(self.get_shape,dtype=self._dtype)

		for key,J in pars.items():
			try:
				H += J*_sp.csc_matrix(self._quantum_operator[key])
			except:
				H = H + J*_sp.csc_matrix(self._quantum_operator[key])

		return H

	def todense(self,pars={},out=None):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a dense array.

		This function can overflow memory if not used carefully!

		Notes
		-----
		If the array dimension is too large, scipy may choose to cast the `quantum_operator` quantum_operator as a
		`numpy.matrix` instead of a `numpy.ndarray`. In such a case, one can use the `quantum_operator.toarray()`
		method.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		out : numpy.ndarray
			Array to fill in with the output.

		Returns
		--------
		obj
			Depending of size of array, can be either one of

			* `numpy.ndarray`.
			* `numpy.matrix`.

		Examples
		---------
		>>> H_dense=H.todense(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)

		if out is None:
			out = _np.zeros(self._shape,dtype=self.dtype)
			out = _np.asmatrix(out)

		for key,J in pars.items():
			out += J * self._quantum_operator[key]

		return out

	def toarray(self,pars={},out=None):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a dense array.

		This function can overflow memory if not used carefully!

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.
		out : numpy.ndarray
			Array to fill in with the output.

		Returns
		--------
		numpy.ndarray
			Dense array.

		Examples
		---------
		>>> H_dense=H.toarray(pars=pars)

		"""

		pars = self._check_scalar_pars(pars)

		if out is None:
			out = _np.zeros(self._shape,dtype=self.dtype)

		for key,J in pars.items():
			out += J * self._quantum_operator[key]

		return out

	def aslinearoperator(self,pars={}):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a `scipy.sparse.linalg.Linearquantum_operator`.

		Casts the `quantum_operator` object as a
		`scipy.sparse.linalg.Linearquantum_operator <https://docs.scipy.org/doc/scipy-0.16.0/reference/generated/scipy.sparse.linalg.Linearquantum_operator.html>`_
		object.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		:obj:`scipy.sparse.linalg.Linearquantum_operator`

		Examples
		---------
		>>> H_aslinop=H.aslinearquantum_operator(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)
		matvec = functools.partial(_quantum_operator_dot,self,pars)
		rmatvec = functools.partial(_quantum_operator_dot,self.H,pars)
		return _sla.LinearOperator(self.get_shape,matvec,rmatvec=rmatvec,matmat=matvec,dtype=self._dtype)

	def tohamiltonian(self,pars={}):
		"""Returns copy of a `quantum_operator` object for parameters `pars` as a `hamiltonian` object.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		:obj:`hamiltonian`

		Examples
		---------
		>>> H_aslinop=H.tohamiltonian(pars=pars)

		"""
		pars = self._check_hamiltonian_pars(pars)

		static=[]
		dynamic=[]

		for key,J in pars.items():
			if type(J) is tuple and len(J) == 2:
				dynamic.append([self._quantum_operator[key],J[0],J[1]])
			else:
				if J == 1.0:
					static.append(self._quantum_operator[key])
				else:
					static.append(J*self._quantum_operator[key])

		return hamiltonian_core.hamiltonian(static,dynamic,dtype=self._dtype)

	### algebra operations

	def transpose(self,copy=False):
		"""Transposes `quantum_operator` quantum_operator.

		Notes
		-----
		This function does NOT conjugate the quantum_operator.

		Returns
		--------
		:obj:`quantum_operator`
			:math:`H_{ij}\\mapsto H_{ji}`

		Examples
		---------

		>>> H_tran = H.transpose()

		"""
		new_dict = {key:op.transpose() for key,op in iteritems(self._quantum_operator)}
		return quantum_operator(new_dict,basis=self._basis,dtype=self._dtype,copy=copy)

	def conjugate(self):
		"""Conjugates `quantum_operator` quantum_operator.

		Notes
		-----
		This function does NOT transpose the quantum_operator.

		Returns
		--------
		:obj:`quantum_operator`
			:math:`H_{ij}\\mapsto H_{ij}^*`

		Examples
		---------

		>>> H_conj = H.conj()

		"""
		new_dict = {key:op.conjugate() for key,op in iteritems(self._quantum_operator)}
		return quantum_operator(new_dict,basis=self._basis,dtype=self._dtype,copy=False)

	def conj(self):
		"""Conjugates `quantum_operator` quantum_operator.

		Notes
		-----
		This function does NOT transpose the quantum_operator.

		Returns
		--------
		:obj:`quantum_operator`
			:math:`H_{ij}\\mapsto H_{ij}^*`

		Examples
		---------

		>>> H_conj = H.conj()

		"""
		return self.conjugate()

	def getH(self,copy=False):
		"""Calculates hermitian conjugate of `quantum_operator` quantum_operator.

		Parameters
		-----------
		copy : bool, optional
			Whether to return a deep copy of the original object. Default is `copy = False`.

		Returns
		--------
		:obj:`quantum_operator`
			:math:`H_{ij}\\mapsto H_{ij}^*`

		Examples
		---------

		>>> H_herm = H.getH()

		"""
		return self.conj().transpose(copy=copy)

	### lin-alg operations

	def diagonal(self,pars={}):
		""" Returns diagonal of `quantum_operator` quantum_operator for parameters `pars`.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		numpy.ndarray
			array containing the diagonal part of the operator :math:`diag_j = H_{jj}(\\lambda)`.

		Examples
		---------

		>>> H_diagonal = H.diagonal(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)
		diag = _np.zeros(self.Ns,dtype=self._dtype)
		for key,value in iteritems(self._quantum_operator_dict):
			diag += pars[key] * value.diagonal()
		return diag

	def trace(self,pars={}):
		""" Calculates trace of `quantum_operator` quantum_operator for parameters `pars`.

		Parameters
		-----------
		pars : dict, optional
			Dictionary with same `keys` as `input_dict` and coupling strengths as `values`. Any missing `keys`
			are assumed to be set to inity.

		Returns
		--------
		float
			Trace of quantum_operator :math:`\\sum_{j=1}^{Ns} H_{jj}(\\lambda)`.

		Examples
		---------

		>>> H_tr = H.trace(pars=pars)

		"""
		pars = self._check_scalar_pars(pars)
		tr = 0.0
		for key,value in iteritems(self._quantum_operator_dict):
			try:
				tr += pars[key] * value.trace()
			except AttributeError:
				tr += pars[key] * value.diagonal().sum()
		return tr

	def astype(self,dtype):
		""" Changes data type of `quantum_operator` object.

		Parameters
		-----------
		dtype : 'type'
			The data type (e.g. numpy.float64) to cast the Hamiltonian with.

		Returns
		`quantum_operator`
			quantum_operator with altered data type.

		Examples
		---------
		>>> H_cpx=H.astype(np.complex128)

		"""
		if dtype not in hamiltonian_core.supported_dtypes:
			raise ValueError("quantum_operator can only be cast to floating point types")

		if dtype == self._dtype:
			return quantum_operator(self._quantum_operator_dict,basis=self._basis,dtype=dtype,copy=False)
		else:
			return quantum_operator(self._quantum_operator_dict,basis=self._basis,dtype=dtype,copy=True)

	def copy(self,deep=False):
		"""Returns a deep copy of `quantum_operator` object."""
		return quantum_operator(self._quantum_operator_dict,basis=self._basis,dtype=self._dtype,copy=deep)

	def __call__(self,**pars):
		pars = self._check_scalar_pars(pars)
		if self.is_dense:
			return self.todense(pars)
		else:
			return self.tocsr(pars)

	def __neg__(self):
		return self.__imul__(-1)

	def __iadd__(self,other):
		self._is_dense = self._is_dense or other._is_dense
		if isinstance(other,quantum_operator):
			for key,value in iteritems(other._quantum_operator_dict):
				if key in self._quantum_operator_dict:
					self._quantum_operator_dict[key] = self._quantum_operator_dict[key] + value
				else:
					self._quantum_operator_dict[key] = value
			return self
		elif other == 0:
			return self
		else:
			return NotImplemented

	def __add__(self,other):
		new_type = _np.result_type(self._dtype, other.dtype)
		new = self.astype(new_type)
		new += other
		return new

	def __isub__(self,other):
		self._is_dense = self._is_dense or other._is_dense
		if isinstance(other,quantum_operator):
			for key,values in iteritems(other._quantum_operator_dict):
				if key in self._quantum_operator_dict:
					self._quantum_operator_dict[key] = self._quantum_operator_dict[key] - value
				else:
					self._quantum_operator_dict[key] = -value
			return self
		elif other == 0:
			return self
		else:
			return NotImplemented

	def __sub__(self,other):
		new_type = _np.result_type(self._dtype, other.dtype)
		new = self.astype(new_type)
		new -= other
		return new

	def __imul__(self,other):
		if not _np.isscalar(other):
			return NotImplemented
		else:
			for op in itervalues(self._quantum_operator_dict):
				op *= other

			return self

	def __mul__(self,other):
		new_type = _np.result_type(self._dtype, other.dtype)
		new = self.astype(new_type)
		new *= other
		return new

	def __idiv__(self,other):
		if not _np.isscalar(other):
			return NotImplemented
		else:
			for op in itervalues(self._quantum_operator_dict):
				op /= other

			return self

	def __div__(self,other):
		new_type = _np.result_type(self._dtype, other.dtype)
		new = self.astype(new_type)
		new /= other
		return new

	def _check_hamiltonian_pars(self,pars):

		if not isinstance(pars,dict):
			raise ValueError("expecing dictionary for parameters.")

		extra = set(pars.keys()) - set(self._quantum_operator.keys())
		if extra:
			raise ValueError("unexpected couplings: {}".format(extra))

		missing = set(self._quantum_operator.keys()) - set(pars.keys())
		for key in missing:
			pars[key] = _np.array(1,dtype=_np.int32)

		for key,J in pars.items():
			if type(J) is tuple:
				if len(J) != 2:
					raise ValueError("expecting parameters to be either scalar or tuple of function and arguements of function.")
			else:
				J = _np.array(J)
				if J.ndim > 0:
					raise ValueError("expecting parameters to be either scalar or tuple of function and arguements of function.")

		return pars

	def _check_scalar_pars(self,pars):

		if not isinstance(pars,dict):
			raise ValueError("expecing dictionary for parameters.")

		extra = set(pars.keys()) - set(self._quantum_operator.keys())
		if extra:
			raise ValueError("unexpected couplings: {}".format(extra))

		missing = set(self._quantum_operator.keys()) - set(pars.keys())
		for key in missing:
			pars[key] = _np.array(1,dtype=_np.int32)

		for J in pars.values():
			J = _np.array(J)
			if J.ndim > 0:
				raise ValueError("expecting parameters to be either scalar or tuple of function and arguements of function.")

		return pars

	# checks
	def _mat_checks(self,other,casting="same_kind"):
		try:
			if other.shape != self._shape: # only accepts square matricies
				raise ValueError('shapes do not match')
			if not _np.can_cast(other.dtype,self._dtype,casting=casting):
				raise ValueError('cannot cast types')
		except AttributeError:
			if other._shape != self._shape: # only accepts square matricies
				raise ValueError('shapes do not match')
			if not _np.can_cast(other.dtype,self._dtype,casting=casting):
				raise ValueError('cannot cast types')

def isquantum_operator(obj):
	"""Checks if instance is object of `quantum_operator` class.

	Parameters
	-----------
	obj :
		Arbitraty python object.

	Returns
	--------
	bool
		Can be either of the following:

		* `True`: `obj` is an instance of `quantum_operator` class.
		* `False`: `obj` is NOT an instance of `quantum_operator` class.

	"""
	return isinstance(obj,quantum_operator)


"""
    This module acts like an AdminController
"""
from django.http import HttpResponse, JsonResponse, HttpResponseBadRequest, HttpResponseForbidden
from utils.models import TrafficEvent, TerroristEvent, Event, EventTransactionLog, Operator, Singapore, CrisisTransactionLog, Haze
from .tabview import AdminTabViews
from utils.views import render_tab_view, is_operator, is_admin
from utils.districts.districts import DistrictManager, CrisisManager
from utils.dispatchers.pmodispatcher import PMODispatcher
from django.template.defaulttags import register
import json
import requests
from utils.crisiscalculation.calculation import CrisisCalculator
from django.contrib.auth.decorators import login_required

# def healthCheck(request):
#     return HttpResponse('It\'s all good! Admin UI works :)')

def get_transaction_log(request):
    """
        Get the transaction log from the database
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    tabs = AdminTabViews()
    tabs.set_active_tab('log')
    event_type_dict = {}
    return render_tab_view(request, tabs, {
        'eventTransactionLog': EventTransactionLog.objects.all(),
        'crisisLogDatabase': CrisisTransactionLog.objects.all(),
    })

@login_required
def get_crisis_view(request):
    """
        Set crisis manager as active tab
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    tabs = AdminTabViews()
    tabs.set_active_tab('crisis')
    crises = CrisisCalculator().check_crisis()
    print(crises)
    return render_tab_view(request, tabs, data={'crises': crises})

@register.filter(name='type')
def get_event_type(log):
    """
        Choose an event type as active tab
    """
    if (TrafficEvent.objects.filter(event=log.event).exists() == True):
        return 'Traffic'
    if (TerroristEvent.objects.filter(event=log.event).exists() == True):
        return 'Terrorist'
    return None

@register.filter(name='address')
def get_address_from_lat_long(latlong):
    """
        Take the location address from given lattitude, longitude
    """
    url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=%s,%s&sensor=false" % (
        latlong.y, latlong.x)
    r = requests.get(url)
    result = r.json()
    address = ""
    if (len(result.get('results')) > 0):
        for x in result.get('results')[0].get('address_components'):
            address += x.get('long_name') + ', '
        return address[:-2]
    else:
        return ""

@register.filter(name='tran')
def get_long_transaction_type(log):
    """
        Display the transaction type
    """
    return log.get_transaction_type_display()

@register.filter(name='adminop')
def get_admin_or_operator(log):
    """
        Choose admin or operator as active tab
    """
    if log.operator is not None:
        return log.operator
    if log.admin is not None:
        return log.admin
    return '-'

def get_districts(request):
    """
        Return the districts data
    """
    return JsonResponse(DistrictManager().return_geo_json(), safe=False)

@login_required
def set_crisis(request):
    """
        Set crisis level
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    CrisisManager().set_crisis_level(
        request.GET.get('district'), request.GET.get('newcrisis'), None)

    return HttpResponse("Success", content_type="text/plain")

def map_events(request):
    """
        Display events on the map
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    tabs = AdminTabViews()
    tabs.set_active_tab('map')
    return render_tab_view(request, tabs, {'haze': Haze.objects.all()})

@login_required
def list_events(request):
    """
        Return a list of events
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    tabs = AdminTabViews()
    tabs.set_active_tab('list')
    return render_tab_view(request, tabs, {
        'trafficevents': TrafficEvent.objects.all(),
        'terroristevents': TerroristEvent.objects.all()
    })

@login_required
def delete_event(request):
    """
        Method to delete an event
    """
    if not is_admin(request.user):
        return HttpResponseForbidden()
    if request.method == 'GET':
        event_id = request.GET.get('eventid')
        event_type = request.GET.get('eventtype')
        if (event_type == 'traffic'):
            t = TrafficEvent.objects.get(id=event_id)
            e = Event.objects.get(id=t.event.id)
            e.delete()
        elif (event_type == 'terrorist'):
            t = TerroristEvent.objects.get(id=event_id)
            print(t.event.id)
            e = Event.objects.get(id=t.event.id)
            e.delete()
        return HttpResponse("Success", content_type="text/plain")

# @login_required
# def crisis_calculator(request):
#     """
#         Show suggested crisis
#     """
#     if not is_admin(request.user):
#         return HttpResponseForbidden()
#     tabs = AdminTabViews()
#     tabs.set_active_tab('crisis')
#     crises = CrisisCalculator().check_crisis()
#     print(crises)
#     return render_tab_view(request, tabs, data={'crises': crises})

@login_required
def report_manager(request):
    tabs = AdminTabViews()
    tabs.set_active_tab('reportmanager')
    return render_tab_view(request, tabs)

def send_report(request):
    PMODispatcher().dispatch(False)
    return JsonResponse({'success': True})


from rest_framework import serializers

from remotes.models import Message

class MessageSerializer(serializers.Serializer):

    id = serializers.CharField()
    response_to = serializers.CharField(required=False, allow_null=True)
    command = serializers.CharField()
    body = serializers.DictField()
    extra = serializers.DictField(required=False, allow_null=True)  # not-persisted data
    origin = serializers.CharField()
    created_at = serializers.DateTimeField()

    def validate_response_to(self, value):
        value = (value or "").strip()
        if not value:
            return None
        if not Message.objects.filter(id=value).exists():
            return None
        return value

    def create(self, validated_data):
        data = {**validated_data, "exchange": self.context["exchange"]}
        response_to = data.pop("response_to", None)
        id = data.pop("id")
        extra = data.pop("extra", None)
        message, _ = Message.objects.update_or_create(id=id, defaults=data)
        if response_to is not None:
            message.response.add(Message.objects.filter(id=response_to).first())
        message.extra = extra or {}
        return message

    @staticmethod
    def serialize_message(message):
        serializer = MessageSerializer(message)
        response_to = message.request.first()
        return {
            **serializer.data,
            "extra": getattr(message, "extra", None) or {},
            "response_to": response_to.id
            if response_to is not None
            else None,
        }


import json
from api.database import engine
from sqlalchemy import  MetaData
from sqlalchemy.orm import  sessionmaker
from api.models import gitaChapter, gitaVerse

Session = sessionmaker(bind=engine)
session = Session()

# meta = MetaData()

with open('data/verse.json','r',encoding='utf8') as file:

    li = []
    data = json.loads(file.read().encode('utf-8'))

    for i in data:
        li.append(gitaVerse(
            externalId=i.get('externalId'),
            title=i.get('title'),
            verse_order = i.get('verse_order'),
            verse_number = i.get('verse_number'),
            chapter_number = i.get('chapter_number'),
            text = i.get('text'),

        ))
    session.add_all(li)
    session.commit()


import sys

def calculate_position(p, k, c):
    result = 0
    for i in range(c):
        result += p * (k ** i)
    return result

def run_test(case_number, generator):
    k, c, s = (int(x) for x in next(generator).split())
    result = [str(calculate_position(x, k, c) + 1) for x in range(k)]
    print('Case #%d: %s' % (case_number, ' '.join(result)))

def main():
    generator = get_file()
    number_of_tests = int(next(generator))
    for test in range(1, number_of_tests + 1):
        run_test(test, generator)

def get_file():
    for line in sys.stdin:
        yield line

if __name__ == '__main__':
    main()


import re

STOPSTATE = "STOP"
EMPTYSYMBOL = "B"

def getRulesFromFile(file_rools = None):
    if not file_rools:
        file_rules = 'rules.txt'
    f = open(file_rules, 'r')
    lines = f.readlines()
    f.close()

    regExp = '^(.)q(\d+)->(.)(q(\d+)(.)|STOP)$'
    #key = (fromSymbol, fromState)
    #value = (toSymbol, toState, +/-1)
    rules = {}

    for line in lines:
        ruleLine = line.strip()
        matchObj = re.match(regExp, ruleLine)
        if matchObj:
            g = matchObj.groups()
            print(g)
            fromSymbol = g[0]
            fromState = g[1]
            toSymbol = g[2]
            toState = STOPSTATE if g[3] == STOPSTATE else int(g[4])
            move = 1 if g[5] == 'R' else -1

            if toState == STOPSTATE:
                rules[(fromSymbol, fromState)] = (toSymbol, toState, None)
            else:
                rules[(fromSymbol, fromState)] = (toSymbol, toState, move)
    return rules

def getInputFromFile(filename = None):
    if not filename:
        filename = 'input.txt'
    f = open(filename, 'r')
    return f.readline().strip()

def emulateTuringMachine(rules, inputData):
    tape = list(inputData) + [EMPTYSYMBOL]*10
    print(tape)

    currentState = 1
    currentInd = 0

    while currentState != STOPSTATE:
        currentSymbol = tape[currentInd]
        if (currentSymbol, currentState) not in rules:
            print("Error!!!")
            return
        else:
            toSymbol, toState, move = rules[(currentSymbol, currentState)]
            if toState == STOPSTATE:
                tape[currentInd] = toSymbol
                print(''.join(tape))
                return
            else:
                tape[currentInd] = toSymbol
                currentState = toState
                currentInd += move
                print(''.join(tape))

emulateTuringMachine(getRulesFromFile(), getInputFromFile())


# -*- encoding: utf-8 -*-
from __future__ import unicode_literals, division, print_function
import os
import requests
from fmi.observation import Observation
from bs4 import BeautifulSoup

class FMI(object):
    apikey = None
    api_endpoint = 'http://data.fmi.fi/fmi-apikey/{apikey}/wfs'

    def __init__(self, apikey=None, place=None):
        self.apikey = os.environ.get('FMI_APIKEY', apikey)
        self.place = os.environ.get('FMI_PLACE', place)
        if self.apikey is None:
            raise AttributeError('FMI API key is not set.')
        if self.place is None:
            raise AttributeError('FMI place is not set.')

    def _parse_identifier(self, x):
        identifier = x['gml:id'].split('-')[-1].lower()
        if identifier in ['t2m', 'temperature']:
            return 'temperature', 1
        if identifier in ['ws_10min', 'windspeedms']:
            return 'wind_speed', 1
        if identifier in ['wg_10min', 'windgust']:
            return 'wind_gust', 1
        if identifier in ['wd_10min', 'winddirection']:
            return 'wind_direction', 1
        if identifier in ['r_1h', 'precipitation1h']:
            return 'precipitation_1h', 1
        if identifier in ['ri_10min', 'precipitationamount']:
            return 'precipitation', 1
        if identifier in ['rh', 'humidity']:
            return 'relative_humidity', 1
        if identifier in ['n_man', 'totalcloudcover']:
            return 'cloud_coverage', 12.5 if identifier == 'n_man' else 1
        if identifier in ['p_sea', 'pressure']:
            return 'pressure', 1
        if identifier in ['td', 'dewpoint']:
            return 'dew_point', 1
        if identifier in ['weathersymbol3']:
            return 'weather_symbol', 1
        return None, 1

    def _parse_response(self, r):
        bs = BeautifulSoup(r.text)

        d = {}
        # Loop over all measurement timeseries
        for mts in bs.find_all('wml2:measurementtimeseries'):
            # Try to parse identifier as "human readable", get multiplier also (mainly for cloud coverage)
            identifier, multiplier = self._parse_identifier(mts)
            if identifier is None:
                continue

            # Loop through all the measurement points
            for p in mts.find_all('wml2:point'):
                # Find timestamp
                timestamp = p.find('wml2:time').text
                # Find value and multiply if by multiplier given in _parse_identifier()
                value = float(p.find('wml2:value').text) * multiplier

                # If timestamp isn't already initialized, initialize as dictionary
                if timestamp not in d.keys():
                    d[timestamp] = {}

                d[timestamp][identifier] = value

        return sorted([Observation(k, v) for k, v in d.items()], key=lambda x: x.time)

    def get(self, storedquery_id, **params):
        query_params = {
            'place': self.place,
            'request': 'getFeature',
            'storedquery_id': storedquery_id,
        }
        query_params.update(params)

        return self._parse_response(requests.get(self.api_endpoint.format(apikey=self.apikey), params=query_params))

    def observations(self):
        return self.get('fmi::observations::weather::timevaluepair', maxlocations=1)

    def forecast(self):
        return self.get('fmi::forecast::hirlam::surface::point::timevaluepair', maxlocations=1)


# Copyright 2018 Ursula Searle
#!/usr/bin/env python3

########################
# Roller for FATE dice #
########################

import random
from Rollers.DiceRoller import show_menu, selection
def fateroller():
    pool = int(input("How many dice are you rolling? "))
    rollagain = "Y"
    while str.upper(rollagain) == "Y":
        try:
            sides = 6

            if pool < 1:
                print("Silly human")

            # Dice roll resolution
            i = 0
            while i < (pool):
                roll = random.randint(1, sides)
                i = i + 1
                if roll == (1 or 2):
                    print("[+]", end=",")
                elif roll == (3 or 4):
                    print("[-]", end=",")
                else:
                    print("[ ]", end=",")

            rollagain = input("Do you want to roll the same again? Enter Y or N: ")

        except (NameError, TypeError, ValueError):

            print("Sorry, try something else!")
            show_menu()
            menu_choice = input("Please enter your choice: ")
            selection(menu_choice)
    else:
        show_menu()
        menu_choice = input("Please enter your choice: ")
        selection(menu_choice)


"""Shelving Filter Cascade with Adjustable Transition Slope and Bandwidth
Frank Schultz, Nara Hahn, Sascha Spors
In: Proc. of 148th AES Convention, Virtual Vienna, May 2020, Paper 10339
http://www.aes.org/e-lib/browse.cfm?elib=20756

slide 4/12

"""

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import MultipleLocator
from scipy.signal import sos2zpk
from util import low_shelving_2nd_cascade, shelving_filter_parameters,\
                 shelving_slope_parameters, sosfreqs, db, set_rcparams,\
                 set_outdir

set_rcparams()
outdir = set_outdir()

w0 = 1
BWd = 3
Q = 1 / np.sqrt(2)
Gd = 10 * np.log10(0.5) * BWd
biquad_per_octave = 1
slope = shelving_slope_parameters(BWd=BWd, Gd=Gd)[0]
wl, wh = w0 * 2**(-BWd), w0

# Frequency-domain evaluation
wmin, wmax, num_w = 2**-9.5, 2**4.5, 1000
w = np.logspace(np.log10(wmin), np.log10(wmax), num=num_w)

# Filter design
num_biquad, Gb, G = shelving_filter_parameters(
        biquad_per_octave=biquad_per_octave, Gd=Gd, BWd=BWd)
Hmag = np.clip(np.log2(w/w0) * slope, G, 0)  # desired response
sos = low_shelving_2nd_cascade(w0, Gb, num_biquad, biquad_per_octave)
H_biquads = np.stack([sosfreqs(sosi[np.newaxis, :], worN=w)[1]
                      for sosi in sos])
H = sosfreqs(sos, worN=w)[1]

# Plots
Glim = -9.5, 1
wlim = wmin, wmax
wticks = 2**(np.arange(np.ceil(np.log2(w)[0]/2)*2,
                       np.floor(np.log2(w[-1])/2)*2 + 2, 2))
kw = dict(lw=2, alpha=1, basex=2)
kw_dotted = dict(color='gray', linestyle=':', linewidth=1)
kw_artist = dict(edgecolor='gray', linestyle=':', linewidth=1)
colors = cm.get_cmap('Blues')

# frequency response
fig, ax = plt.subplots(figsize=(10, 4), ncols=2, gridspec_kw={'wspace': 0.1})
ax[0].semilogx(w, db(H_biquads.T), c='gray', **kw, zorder=2)
ax[0].semilogx(w, Hmag, 'k:', **kw)
ax[0].semilogx(w, db(H), c='C0', **kw, zorder=3)

ax[1].plot([-1, 0], [1, 0], 'C7:', lw=1)

# Pole zero plot
kw_z = dict(c='C0', marker='o', ms=9, ls='none', mew=1, mfc='none', alpha=1)
kw_p = dict(c='k', marker='x', ms=9, ls='none', mew=1)
kw_dot = dict(marker='.', ms=10)
ylim = ax[0].get_ylim()
for n, sosi in enumerate(sos):
    z, p, _ = sos2zpk(sosi[np.newaxis, :])
    z, p = z[0], p[0]
    wc = np.abs(np.sqrt(z * p))

    ax[0].plot((wc, wc), (-3, 0), **kw_dotted)
    ax[0].plot(wc, Gb/2, c='gray', zorder=2, **kw_dot)
    ax[1].plot(wc * -np.cos(np.pi/4), wc * np.sin(np.pi/4), c='gray', **kw_dot)
    ax[1].plot(np.real(p), np.imag(p), **kw_p)
    ax[1].plot(np.real(z), np.imag(z), **kw_z)
    circle = plt.Circle(xy=(0, 0), radius=wc, facecolor='none', **kw_artist)
    ax[1].add_artist(circle)
ax[0].plot(np.sqrt(wh * wl), G/2, 'C0', **kw_dot)

# desired slope
wc = 2**-2
w1 = wc * 2**(-0.2)
w2 = wc * 2**(+0.2)
Gc = Gd / 2
G1 = Gc + slope * -0.2
G2 = Gc + slope * +0.2
pc = ax[0].transData.transform_point((wc, Gc))
p1 = ax[0].transData.transform_point((w1, G1))
p2 = ax[0].transData.transform_point((w2, G2))
angle = np.rad2deg(np.arctan2(*(p2-p1)[::-1]))
dx, dy = -8, 0
xoffset = (dx * np.cos(np.deg2rad(angle)),
           dx * np.sin(np.deg2rad(angle)))
yoffset = (dy * -np.sin(np.deg2rad(angle)),
           dy * np.cos(np.deg2rad(angle)))
inv = ax[0].transData.inverted()
(wt, Gt) = inv.transform(pc + xoffset + yoffset)
ax[0].annotate('{:+0.2f} dB/oct'.format(np.round(slope, decimals=2)),
               (wt, Gt), ha='center', va='center', rotation=angle, fontsize=10)

# decorations
ax[0].set_xlim(wmin, wmax)
ax[0].set_ylim(Glim)
ax[0].set_xticks(wticks)
ax[0].grid(True)
ax[0].yaxis.set_major_locator(MultipleLocator(3))
ax[0].yaxis.set_minor_locator(MultipleLocator(1))
ax[0].set_xlabel(r'$\omega$ / $\omega_\textrm{\footnotesize u}$')
ax[0].set_ylabel('Level in dB')
ax[0].text(2**(-2.5), 0.5,
           r'upper cutoff frequency $\omega_\mathrm{u}$',
           fontsize=10, ha='center', va='center')

ax[1].axis([-0.75, 0., -0., 0.75])
ax[1].grid(True)
ax[1].set_xticks(-2.**-np.arange(3) * 10**(Gb/20))
ax[1].set_yticks(2.**-np.arange(3) * 10**(Gb/20))
ax[1].set_xticklabels(['$-2^{-1/2}$', '$-2^{-3/2}$', '$-2^{-5/2}$'])
ax[1].set_yticklabels(['$2^{-1/2}$', '$2^{-3/2}$', '$2^{-5/2}$'])
ax[1].yaxis.tick_right()
ax[1].set_aspect('equal')
ax[1].set_ylabel(r'$\Im (s\,/\,\omega_\textrm{\footnotesize u})$')
ax[1].set_xlabel(r'$\Re (s\,/\,\omega_\textrm{\footnotesize u})$')
ax[1].text(-2**(-2/2), 2**(-6/2),
           r'upper left $s$-plane', fontsize=10, ha='center', va='center')

plt.savefig(outdir + 'biquad-and-pzmap_slides.pdf', bbox_inches='tight')


from collections import defaultdict
import re
import json
import random
import time
import os
import Pubnub as PB

PUB_KEY = os.environ["PUB_KEY"]
SUB_KEY = os.environ["SUB_KEY"]
SEC_KEY = os.environ["SEC_KEY"]
CHANNEL_NAME = os.environ["CHANNEL_NAME"]

pubnub = PB.Pubnub(
    publish_key = PUB_KEY,
    subscribe_key = SUB_KEY,
    secret_key = SEC_KEY,
    cipher_key = '',
    ssl_on = False,
)

def random_text():
    "generate a random string with a random length"
    out = []
    while random.random() > 0.03:
        out.append(random.choice("abcefghijklmnopqrstuvwxyz"))
    return "".join(out)

if __name__ == "__main__":
    while True:
        pubnub.publish(
            channel=CHANNEL_NAME,
            message=random_text(),
        )
        time.sleep(4)


#####TP 1 exercice7
##BOURDON Antoine-Alexis L1MI
'''Module Menu Principal
Fonctions:
 - affiche_menu()
 - afficher_les_codes(dict_codes)
 - ajouter_un_code(dict_codes)
 - crypter_un_texte(dict_codes)
 - decrypter_un_texte(dict_codes)
'''
__author__ = 'Antoine-Alexis BOURDON <antoine-alexis_bourdon@ens.univ-artois.fr>'
__date__ = '24 janvier 2018'

#Modules:
import exercice3
import exercice4
import exercice5
import exercice6

def affiche_menu():
	'''affiche toutes les options du menu principal et
	retourne le choix de l’utilisateur.
	Argument:
		None
	Retour:
		- choix : int
	'''
	choix="12"
	while choix not in ('0,1,2,3,4'):
		print('''
		1 : Liste des codes disponibles.
		2 : Creer un nouveau code.
		3 : Crypter un texte.
		4 : Decrypter un texte.
		0 : Quitter l’application.

		Votre choix : ''',end="")
		choix = str(input())
	return int(choix)

def afficher_les_codes(dict_codes):
	'''à partir d’un dictionnaire qui, à un
	nom, associe un code, affiche tous les codes disponibles.
	Argument:
		Dict
	Retour:
		None
	'''
	for nom in dict_codes.keys():
		print(nom, ':', dict_codes[nom])

def ajouter_un_code(dict_codes):
	'''qui prend en paramètre le dictionnaire de
	tous les codes et en créé un nouveau
	'''
	nom = input('Donnez le nom de votre nouveau code : ')
	while nom in dict_codes:
		nom = input('Donnez le nom de votre nouveau code : ')
	dict_codes[nom]=exercice3.dictPerm()

def crypter_un_texte(dict_codes):
	'''Fonction qui crypte le texte de l'utilisateur à l'aide du dictionnaire de permutation choisi.
        Argument:
                dict_codes : --dict(str : (str : str)).
        Retour:
                None.
	'''
	afficher_les_codes(dict_codes)
	dico_choix = input('Nom du code choisi : ')
	while dico_choix  not in dict_codes.keys():
		dico_choix = input('Nom du code choisi : ')
	texte_origine = input('Texte à crypter : ')
	print('Le texte crypté est : \n',exercice4.crypte(texte_origine, dict_codes[dico_choix]))

def decrypter_un_texte(dict_codes):
	'''Fonction qui décrypte le texte de l'utilisateur à l'aide du dictionnaire de permuattion choisi.
	Argument:
		dict_codes : --dict(str : (str : str)).
	Retour:
		None.
	'''
	afficher_les_codes(dict_codes)
	dico_choix = input('Nom du code choisi : ')
	while dico_choix not in dict_codes.keys():
		dico_choix = input('Nom du code choisi : ')
	texte_crypt = input('Texte à décrypter : ')
	print('Le texte décrypté est : \n',exercice6.decrypt(texte_crypt,dict_codes[dico_choix]))


from user import User
from privileges import Privileges
class Admin(User):
    """Simple class to model an admin."""

    def __init__(self, first_name, last_name, username='', date_of_birth='',
        user_aggreement='', last_visit='', privileges=''):
        super().__init__(first_name, last_name, username='', date_of_birth='',
            user_aggreement='', last_visit='')
        self.privileges = Privileges()

my_admin = Admin('Chris', 'Cox', privileges=['can add post','can delete post',
'can ban user'])

my_admin.describe_user()
my_admin.privileges.show_privileges()


import math
import os

def main():
    #escribe tu código abajo de esta línea

    os.system('clear')

    catetoA = float(input("Valor CatetoA:"))
    catetoB = float(input("Valor CatetoB:"))
    hipotenusa = math.pow(catetoA,2)+math.pow(catetoB,2)

    print(f"El cuadrado de la hipotenusa {hipotenusa} ")

    print(f"Los valores de los catetos son CatetoA {catetoA} CatetoB {catetoB} ")
    print("LA RAIZ CUADRADA")
    numero=float(input("Numero "))
    raizC=math.sqrt(numero)
    print(f"LA RAIZ CUADRADA DE {numero} es {raizC} ")

    print("===========================")
    print("VOLUMEN Y ÁREA DE UNA ESFERA")
    radio=float(input("Radio de la Esfera ="))
    area=4*math.pi*math.pow(radio,2)
    volumen=(4*math.pi*math.pow(radio,3))/3
    print(f" Area = {area},  Volumen = {volumen}  ")

if __name__=='__main__':
    main()


import ast
dict_filename = "/home/hm-tlacherm/qlm_notebooks/notebooks_1.2.1/notebooks/master_thesis_qaoa/ibm/measurements/data/max_cuts_dict_3_reg.dict"
def get_dict():
    f = open(dict_filename, 'r')
    contents = f.read()
    dictionary = ast.literal_eval(contents)
    f.close()
    return dictionary

def get_max_cut(graph):
    dic = get_dict()
    return dic[graph]


from typing import List, Dict

import torch

from ._encoder_base import Encoder
from .utils import get_mlp

@Encoder.register('mlp_encoder')
class MlpEncoder(Encoder):
    def __init__(self,
                 encode_dims: List[int],
                 activation: str = 'relu',
                 dropout: float = 0.
                 ):
        super().__init__()

        self.mlp = get_mlp(encode_dims, activation=activation, dropout=dropout)
        self.output_dim = encode_dims[-1]

        self.metrics = {}

    def get_output_dim(self) -> int:
        return self.output_dim

    def forward(self, x: torch.Tensor, **kwargs) -> Dict[str, torch.Tensor]:
        latent_feature = self.mlp(x)
        output_dict = {"latent_feature": latent_feature}

        return output_dict


leds = [pyb.LED(i) for i in range(1,5)]
for l in leds:
    l.off()

n = 0
intensity = 0
blue = 4
try:
   while True:
      n = (n + 1) % 4
      if n == blue:
        ntensity = (intensity + 1) % 255
        leds[blue].intensity(intensity)
        pyb.delay(20)
      leds[n].toggle()
      pyb.delay(50)
finally:
    for l in leds:
        l.off()


import os

location = r"D:\scharati\myProjects\github\learnings\udacity-fullstack-web\prank"

contents = os.listdir(location)

print(contents)

def rename_file(file_name):
    return file_name.translate(None,"0123456789")

for file in contents:
    renamed_file_name = rename_file(file)
    src_path = os.path.join(location,file)
    dest_path = os.path.join(location,renamed_file_name)
    os.rename(src_path,dest_path)


import keyboard as kb
import time

userid = input(' Enter the School User ID: ')
startmonth = input(' Enter the starting month for the hack. this should be 0 if you want it to run through every month: ')
startingnumber=(int(startmonth)*29)+1

def iteration (passcode):
    time.sleep(0.01)
    #time.sleep(1.3)
    kb.press_and_release('tab')
    kb.write(userid)
    kb.press_and_release('tab')
    kb.write(passcode)
    kb.press_and_release('enter')

def Finddate(DAY, YEAR):
    DAY = int(DAY)
    YEAR = float(YEAR)
    if (YEAR//400 == YEAR/400):
        Y=1
    elif (YEAR//4 == YEAR/4) and (YEAR//100 != YEAR/100):
        Y=1
    else:
        Y=0
    MONTH_LEN   = [31,28,31,30,31,30,31,31,30,31,30,31]
    if Y==0:
        MONTH_LEN=MONTH_LEN
    else:
        MONTH_LEN[1]+=1
    if Y == 0 and (DAY > 365 or DAY < 1):
        import sys
        sys.exit(str(int(YEAR))+" Not a leap year. Day value is greater than 365 or less than 1")
    if Y == 1 and (DAY > 366 or DAY < 1):
        import sys
        sys.exit(str(int(YEAR))+" Leap year. Day value greater than 366 or less than 1")
    for N, M in enumerate(MONTH_LEN):
        if DAY > M:
            DAY = DAY-M
        else:
            M_NUM = N+1
            break
    if len(str(DAY)) == 1:
        DAY = '0' + str(DAY)
    else:
        DAY = str(DAY)
    if len(str(M_NUM)) == 1:
        M_NUM = '0' + str(M_NUM)
    else:
        M_NUM = str(M_NUM)
    return str(int(YEAR)) + M_NUM + DAY

while startingnumber < 367:
    kb.wait('esc')
    date = Finddate(startingnumber,2004)
    print(date)
    iteration(date)
    startingnumber+=1


import os

# Question 1
def getComponentCountByProject(projectID):
    result = ()
    proj_dict = makeDic('projects.txt', {}, None)
    if projectID not in proj_dict:
        return None

    comp_list = []
    for cir_ID in proj_dict[projectID]:
        fname = "./Circuits/circuit_" + cir_ID + ".txt"
        comp_str = fread(fname)
        comp_list = list(set(comp_list + comp_str[4].split(', ')))

    result = countComp(comp_list, result)
    return result

# Question 2
def getComponentCountByStudent(studentName):
    result = ()
    stu_dict = makeDic(('students.txt'), {}, '|')
    if studentName not in stu_dict:
        return None
    stu_ID = stu_dict[studentName]

    comp_list = []
    folder = os.listdir("Circuits")
    for file in folder:
        comp_str = fread("./Circuits/" + file)
        if stu_ID[0] in comp_str[1]:
            comp_list = list(set(comp_list + comp_str[4].split(', ')))
    result = countComp(comp_list, result)
    return result

# Question 3
def getParticipationByStudent(studentName):
    result = set()
    dict = makeDic('students.txt', {}, '|')
    dict = makeDic('projects.txt', dict, None)
    if studentName not in dict:
        return None
    stu_ID = dict[studentName]

    folder = os.listdir("Circuits")
    for file in folder:
        student_info = fread("./Circuits/" + file)
        if stu_ID[0] in student_info[1]:
            circuit_ID = file[8:13]
            for proj_ID in dict[circuit_ID]:
                result.add(proj_ID)
    return result

# Question 4
def getParticipationByProject(projectID):
    result = set()
    dict = makeDic('students.txt', {}, '|')
    dict = makeDic('projects.txt', dict, None)
    if projectID not in dict:
        return None

    stu_IDs = []
    for cir_ID in dict[projectID]:
        fname = "./Circuits/circuit_" + cir_ID + ".txt"
        circuit = fread(fname)
        stu_IDs = stu_IDs + circuit[1].strip().split(', ')

    stu_IDs = list(set(stu_IDs))
    for stu_ID in stu_IDs:
        if stu_ID not in dict:
            return None
        else:
            stu_name = dict[stu_ID][0]
            result.add(stu_name)
    return result

# Question 5 Check
def getProjectByComponent(components):
    result_set = set()
    result_dic = {}
    dict = makeDic('projects.txt', {}, None)
    for comp in components:
        result_set = set()
        folder = os.listdir("Circuits")
        for file in folder:
            comp_info = fread("./Circuits/" + file)[4]
            if comp in comp_info:
                cir_ID = file[8:13]
                for proj_ID in dict[cir_ID]:
                    result_set.add(proj_ID)
        result_dic[comp] = result_set
    return result_dic

# Question 6 Check
def getStudentByComponent(components):
    result_set = set()
    result_dic = {}
    dict = makeDic('students.txt', {}, '|')
    for comp in components:
        result_set = set()
        folder = os.listdir("Circuits")
        for file in folder:
            info = fread("./Circuits/" + file)
            comp_info = info[4]
            if comp in comp_info:
                stu_IDs = info[1].strip().split(', ')
                for stu_ID in stu_IDs:
                    result_set.add(dict[stu_ID][0])
        result_dic[comp] = result_set
    return result_dic

# Question 7
def getComponentByStudent(studentNames):
    result_set = set()
    result_dic = {}
    dict = makeDic('students.txt', {}, '|')
    for studentName in studentNames:
        result_set = set()
        folder = os.listdir("Circuits")
        for file in folder:
            info = fread("./Circuits/" + file)
            if dict[studentName][0] in info[1]:
                comp_info = info[4].strip().split(', ')
                for comp in comp_info:
                    result_set.add(comp)
            result_dic[studentName] = result_set
    return result_dic

# Question 8
def getCommonByProject(projectID1, projectID2):
    dict = makeDic('projects.txt', {}, None)
    if projectID1 not in dict or projectID2 not in dict:
        return None
    result_list = comp_list_1 = comp_list_2 = []
    folder = os.listdir("Circuits")
    for cir_ID in dict[projectID1]:
        comp_info = fread("./Circuits/circuit_" + cir_ID + ".txt")[4].strip().split(', ')
        comp_list_1 = comp_list_1 + comp_info
    for cir_ID in dict[projectID2]:
        comp_info = fread("./Circuits/circuit_" + cir_ID + ".txt")[4].strip().split(', ')
        comp_list_2 = comp_list_2 + comp_info

    for comp in comp_list_1:
        if comp in comp_list_2:
            result_list.append(comp)
    result_list = list(set(result_list))
    return result_list

# Question 9
def getCommonByStudent(studentName1, studentName2):
    dict = makeDic('students.txt', {}, '|')
    if studentName1 not in dict or studentName2 not in dict:
        return None
    result_list = comp_list_1 = comp_list_2 = []
    folder = os.listdir("Circuits")
    for file in folder:
        info = fread("./Circuits/" + file)
        stu_IDs = info[1]
        if dict[studentName1][0] in stu_IDs:
            comp_list_1 = comp_list_1 + info[4].strip().split(', ')
        if dict[studentName2][0] in stu_IDs:
            comp_list_2 = comp_list_2 + info[4].strip().split(', ')

    for comp in comp_list_1:
        if comp in comp_list_2:
            result_list.append(comp)
    return result_list

# Question 10
def getProjectByCircuit():
    dict = makeDic('projects.txt', {}, None)
    result_dict = {}
    cir_IDs = fread('projects.txt')[2:]
    for cir_ID in cir_IDs:
        cir_ID = cir_ID.strip().split()[0]
        result_dict[cir_ID] = sorted(dict[cir_ID])
    return result_dict

# Question 11
def getCircuitByStudent():
    dict = makeDic('students.txt', {}, '|')
    result_dict = {}
    stu_infos = fread('students.txt')[2:]
    folder = os.listdir("Circuits")
    for stu_info in stu_infos:
        stu_name = stu_info.split('|')[0].strip()
        result_dict[stu_name] = []
    for file in folder:
        cir_ID = file[8:13]
        for stu_info in stu_infos:
            stu_name = stu_info.split('|')[0].strip()
            stu_id = stu_info.split('|')[1].strip()
            if stu_id in fread('./Circuits/' + file)[1]:
                result_dict[stu_name].append(cir_ID)
                result_dict[stu_name] = sorted(list(set(result_dict[stu_name])))
    return result_dict

# Question 12
def getCircuitByStudentPartial(studentName):
    dict = getCircuitByStudent()
    result_dict = {}
    stu_infos = fread('students.txt')[2:]
    exist = True
    for stu_info in stu_infos:
        stu_name = stu_info.split('|')[0].strip()
        if studentName in stu_name:
            result_dict[stu_name] = dict[stu_name]
    if not result_dict:
        return None
    return result_dict

# Make the information in a string in to a dictionary
def makeDic(fname, dict, delim):
    new_info = fread(fname)
    new_info = new_info[2:]
    new_list = []
    for info in new_info:
        info = info.split(delim)
        info[0] = info[0].strip()
        info[1] = info[1].strip()
        if info[0] in dict:
            dict[info[0]].append(info[1])
            list(set(dict[info[0]]))
        else:
            dict[info[0]] = [info[1]]
        if info[1] in dict:
            dict[info[1]].append(info[0])
            list(set(dict[info[1]]))
        else:
            dict[info[1]] = [info[0]]
    return dict

# Read all file information into a list of lines
def fread(fname):
    lines = []
    with open(fname, 'r') as myFile:
        lines = myFile.readlines()
    return lines

# Count the component with a given circuit
def countComp(comp_list, result):
    if not result:
        result = (0, 0, 0, 0)
    comp_dic = {'R':0, 'L':0, 'C':0, 'T':0}
    for comp in comp_list:
        comp_dic[comp[0]] = comp_dic[comp[0]] + 1
    R = comp_dic['R']
    L = comp_dic['L']
    C = comp_dic['C']
    T = comp_dic['T']
    r, l, c, t = result
    r = r + R
    l = l + L
    c = c + C
    t = t + T
    result = r, l, c, t
    if r == l == c == t == 0:
        result = ()
    return result

if __name__ == "__main__":
    print('Test 1: getComponentCountByProject')
    print(getComponentCountByProject('082D6241-40EE-432E-A635-65EA8AA374B6'))
    ids = fread('projects.txt')[2:]
    for id in ids:
        id = id.split()
        print(getComponentCountByProject(id[1]))
    print(getComponentCountByProject("Does not exist"))
    print('Test 2: getComponentCountByStudent')
    names = fread('students.txt')[2:]
    for name in names:
        name = name.split('|')
        name[0] = name[0].strip()
        name[1] = name[1].strip()
        print(getComponentCountByStudent(name[0]))
    print(getComponentCountByStudent("Does not exist"))
    print('Test 3: getParticipationByStudent')
    names = fread('students.txt')[2:]
    for name in names:
        name = name.split('|')
        name[0] = name[0].strip()
        name[1] = name[1].strip()
        print(getParticipationByStudent(name[0]))
    print(getParticipationByStudent("Does not exist"))
    print('Test 4: getParticipationByProject')
    ids = fread('projects.txt')[2:]
    for id in ids:
        id = id.split()
        print(getParticipationByProject(id[1]))
    print(getParticipationByProject('Does not exist'))
    print('Test 5: getProjectByComponent')
    comp_list = []
    folder = os.listdir("Circuits")
    for file in folder:
        comp_list = comp_list + fread("./Circuits/" + file)[4].strip().split(', ')
    set(comp_list)
    print(getProjectByComponent(comp_list))
    print(getProjectByComponent({'L617.377', 'T119.763', 'C421.132'}))
    print('Test 6: getStudentByComponent')
    comp_list = []
    folder = os.listdir("Circuits")
    for file in folder:
        comp_list = comp_list + fread("./Circuits/" + file)[4].strip().split(', ')
    set(comp_list)
    print(getStudentByComponent(comp_list))
    print(getStudentByComponent({'L617.377', 'T119.763', 'C421.132'}))
    print('Test 7: getComponentByStudent')
    names = fread('students.txt')[2:]
    name_list = []
    for name in names:
        name = name.split('|')
        name[0] = name[0].strip()
        name[1] = name[1].strip()
        name_list.append(name[0])
    print(getComponentByStudent(name_list))
    print(getComponentByStudent({'Adams, Keith', 'Alexander, Carlos', 'Butler, Julia'}))
    print('Test 8: getCommonByProject')
    print(getCommonByProject('082D6241-40EE-432E-A635-65EA8AA374B6', '90BE0D09-1438-414A-A38B-8309A49C02EF'))
    print('Test 9: getCommonByStudent')
    print(getCommonByStudent('Adams, Keith', 'Bennett, Nancy'))
    print('Test 10: getProjectByCircuit')
    print(getProjectByCircuit())
    print('Test 11: getCircuitByStudent')
    print(getCircuitByStudent())
    print('Test 12: getCircuitByStudentPartial')
    print(getCircuitByStudentPartial('Shawn'))
    print(getComponentCountByProject('082D6241-40EE-432E-A635-65EA8AA374B6'))
    print(getComponentCountByStudent('Adams, Keith'))
    print(getParticipationByStudent("Adams, Keith"))
    print(getParticipationByProject('082D6241-40EE-432E-A635-65EA8AA374B6'))
    print(getProjectByComponent({'T475.274', 'C471.636'}))
    print(getStudentByComponent({'T475.274', 'C471.636'}))
    print(getComponentByStudent({'Adams, Keith', 'Alexander, Carlos'}))
    print(len(getCommonByProject('082D6241-40EE-432E-A635-65EA8AA374B6', '90BE0D09-1438-414A-A38B-8309A49C02EF'))) # check 95
    print(getCommonByStudent('Adams, Keith', 'Alexander, Carlos'))
    print(getProjectByCircuit())
    print(getCircuitByStudent())
    print(getCircuitByStudentPartial('Howard'))


import re
import random
import sys

import torch
import torch.nn as nn
from torch import optim
import torch.nn.functional as F

import data
import model

import timeit

totalt = 0
def evaluate(encoder, classifier, sentence1, sentence2, device):
    global totalt
    with torch.no_grad():
        input1_tensor = [encoder.prepareInput(e, device) for e in sentence1]
        input2_tensor = [encoder.prepareInput(e, device) for e in sentence2]

        input1_length = len(input1_tensor)
        input2_length = len(input2_tensor)

        encoder_hidden = encoder.initHidden(device)
        for ei in range(input1_length):
            _, encoder_hidden = encoder(input1_tensor[ei], encoder_hidden)
        encoded1_tensor = encoder_hidden[-1]

        encoder_hidden = encoder.initHidden(device)
        for ei in range(input2_length):
            _, encoder_hidden = encoder(input2_tensor[ei], encoder_hidden)
        encoded2_tensor = encoder_hidden[-1]

        start = timeit.default_timer()

        classifier_output = classifier(encoded1_tensor, encoded2_tensor)

        stop = timeit.default_timer()
        totalt += stop - start

        return classifier_output

def evaluateRandomly(dataset, encoder, classifier, device):
    correct = 0
    totalWith = {0:0, 1:0}
    correctWith = {0:0, 1:0}
    for pair in dataset:
        #print('>', pair[0])
        #print('>', pair[1])
        output = evaluate(encoder, classifier, pair[0], pair[1], device)
        topv, topi = output.data.topk(1)
        prediction = int(topi.view(1)[0])
        #print('=', pair[2], '|', prediction)
        #print('<',output)
        totalWith[pair[2]] += 1
        if prediction==pair[2]:
            correctWith[pair[2]] += 1
            correct += 1
    print( 'Accuracy: %f' % (float(correct)/float(len(dataset))) )
    print( 'Accuracy 0: %f' % (float(correctWith[0])/float(totalWith[0])),  totalWith[0])
    print( 'Accuracy 1: %f' % (float(correctWith[1])/float(totalWith[1])),  totalWith[1])

if __name__=='__main__':

  #device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  device = torch.device("cpu")
  print('Loading data')
  print('Including:',sys.argv[2:])
  entries = data.load(sys.argv[1],include=sys.argv[2:])

  #n_iters = 250000
  #dataset = data.balanced(entries, n_iters)
  dataset=entries

  print('Testing')

  encoder1 = torch.load('encoder.pt')
  classifier1 = torch.load('classifier.pt')

  evaluateRandomly(dataset, encoder1, classifier1, device)
  print(totalt)


for i in range(int(input())):
	n = int(input())
	s = input()
	for k in s:
		if k == 'I':
			ans = "INDIAN"
			break
		elif k == 'Y':
			ans = "NOT INDIAN"
			break
		else:
			ans = "NOT SURE"
	print(ans)