import numpy as np
import scipy.integrate as si
from numpy.ma import log, exp
from scipy.constants import K2C, C2K
from ..package_tools import Exporter
from ..constants import epsilon, kappa, P0, Rd, Lv, Cp_d

exporter = Exporter(globals())

sat_pressure_0c = 6.112  # mb

@exporter.export
def potential_temperature(pressure, temperature):
    r'''Calculate the potential temperature.

    Uses the Poisson equation to calculation the potential temperature
    given `pressure` and `temperature`.

    Parameters
    ----------
    pressure : array_like
        The total atmospheric pressure in mb
    temperature : array_like
        The temperature in Kelvin

    Returns
    -------
    array_like
        The potential temperature corresponding to the the temperature and
        pressure.

    See Also
    --------
    dry_lapse

    Notes
    -----
    Formula:

    .. math:: \Theta = T (P_0 / P)^\kappa

    Examples
    --------
    >>> metpy.calc.potential_temperature(800., 273.)
    290.9814150577374

    '''

    # Factor of 100 converts mb to Pa. Really need unit support here.
    return temperature * (P0 / (pressure * 100))**kappa

# Dividing P0 by 100 converts to mb
@exporter.export
def dry_lapse(pressure, temperature, starting_pressure=P0 / 100):
    r'''Calculate the temperature at a level assuming only dry processes
    operating from the starting point.

    This function lifts a parcel starting at `temperature` and
    `starting_pressure` to the level given by `pressure`, conserving potential
    temperature.

    Parameters
    ----------
    pressure : array_like
        The atmospheric pressure level of interest in mb
    temperature : array_like
        The starting temperature in Kelvin
    starting_pressure : array_like
        The pressure at the starting point. Defaults to P0 (1000 mb).

    Returns
    -------
    array_like
       The resulting parcel temperature, in Kelvin, at level `pressure`

    See Also
    --------
    moist_lapse : Calculate parcel temperature assuming liquid saturation
                  processes
    parcel_profile : Calculate complete parcel profile
    potential_temperature
    '''

    return temperature * (pressure / starting_pressure)**kappa

@exporter.export
def moist_lapse(pressure, temperature):
    r'''
    Calculate the temperature at a level assuming liquid saturation processes
    operating from the starting point.

    This function lifts a parcel starting at `temperature`
    this is calculating moist pseudo-adiabats. The starting pressure should be
    the first item in the `pressure` array.

    Parameters
    ----------
    pressure : array_like
        The atmospheric pressure level of interest in mb
    temperature : array_like
        The starting temperature in Kelvin

    Returns
    -------
    array_like
       The temperature corresponding to the the starting temperature and
       pressure levels, with the shape determined by numpy broadcasting rules.

    See Also
    --------
    dry_lapse : Calculate parcel temperature assuming dry adiabatic processes
    parcel_profile : Calculate complete parcel profile

    Notes
    -----
    This function is implemented by integrating the following differential
    equation:

    .. math:: \frac{dT}{dP} = \frac{1}{P} \frac{R_d T + L_v r_s}
                                {C_{pd} + \frac{L_v^2 r_s \epsilon}{R_d T^2}}

    This equation comes from [1]_.

    References
    ----------

    .. [1] Bakhshaii, A. and R. Stull, 2013: Saturated Pseudoadiabats--A
           Noniterative Approximation. J. Appl. Meteor. Clim., 52, 5-15.
    '''

    # Factor of 100 converts mb to Pa. Really need unit support here.
    def dt(t, p):
        rs = mixing_ratio(saturation_vapor_pressure(K2C(t)), p)
        return (1. / p) * ((Rd * t + Lv * rs) /
                           (Cp_d + (Lv * Lv * rs * epsilon / (Rd * t * t))))
    return si.odeint(dt, np.atleast_1d(temperature).squeeze(),
                     pressure.squeeze()).T.squeeze()

@exporter.export
def lcl(pressure, temperature, dewpt, max_iters=50, eps=1e-2):
    r'''Calculate the lifted condensation level (LCL) using from the starting
    point.

    The starting state for the parcel is defined by `temperature`, `dewpoint`,
    and `pressure`.

    Parameters
    ----------
    pressure : array_like
        The starting atmospheric pressure in mb
    temperature : array_like
        The starting temperature in Kelvin
    dewpt : array_like
        The dew point in Kelvin

    Returns
    -------
    array_like
        The LCL in mb.

    Other Parameters
    ----------------
    max_iters : int, optional
        The maximum number of iterations to use in calculation, defaults to 50.
    eps : float, optional
        The desired absolute error in the calculated value, defaults to 1e-2.

    See Also
    --------
    parcel_profile

    Notes
    -----
    This function is implemented using an iterative approach to solve for the
    LCL. The basic algorithm is:
    1. Find the dew point from the LCL pressure and starting mixing ratio
    2. Find the LCL pressure from the starting temperature and dewpoint
    3. Iterate until convergence

    The function is guaranteed to finish by virtue of the `maxIters` counter.
    '''

    w = mixing_ratio(saturation_vapor_pressure(K2C(dewpt)), pressure)
    p = pressure
    while max_iters:
        td = C2K(dewpoint(vapor_pressure(p, w)))
        new_p = pressure * (td / temperature) ** (1. / kappa)
        if np.abs(new_p - p).max() < eps:
            break
        p = new_p
        max_iters -= 1
    return new_p

@exporter.export
def parcel_profile(pressure, temperature, dewpt):
    r'''Calculate the profile a parcel takes through the atmosphere, lifting
    from the starting point.

    The parcel starts at `temperature`, and `dewpt`, lifed up
    dry adiabatically to the LCL, and then moist adiabatically from there.
    `pressure` specifies the pressure levels for the profile.

    Parameters
    ----------
    pressure : array_like
        The atmospheric pressure in mb. The first entry should be the starting
        point pressure.
    temperature : array_like
        The temperature in Kelvin
    dewpt : array_like
        The dew point in Kelvin

    Returns
    -------
    array_like
        The parcel temperatures at the specified pressure levels.

    See Also
    --------
    lcl, moist_lapse, dry_lapse
    '''

    # Find the LCL
    l = np.atleast_1d(lcl(pressure[0], temperature, dewpt))

    # Find the dry adiabatic profile, *including* the LCL
    press_lower = np.concatenate((pressure[pressure > l], l))
    t1 = dry_lapse(press_lower, temperature, pressure[0])

    # Find moist pseudo-adiabatic profile starting at the LCL
    t2 = moist_lapse(np.concatenate((l, pressure[pressure < l])), t1[-1])

    # Return LCL *without* the LCL point
    return np.concatenate((t1[:-1], t2[1:]))

@exporter.export
def vapor_pressure(pressure, mixing):
    r'''Calculate water vapor (partial) pressure

    Given total `pressure` and water vapor `mixing` ratio, calculates the
    partial pressure of water vapor.

    Parameters
    ----------
    pressure : array_like
        total atmospheric pressure
    mixing : array_like
        dimensionless mass mixing ratio

    Returns
    -------
    array_like
        The ambient water vapor (partial) pressure in the same units as
        `pressure`.

    See Also
    --------
    saturation_vapor_pressure, dewpoint
    '''

    return pressure * mixing / (epsilon + mixing)

@exporter.export
def saturation_vapor_pressure(temperature):
    r'''Calculate the saturation water vapor (partial) pressure

    Parameters
    ----------
    temperature : array_like
        The temperature in degrees Celsius.

    Returns
    -------
    array_like
        The saturation water vapor (partial) presure in mb.

    See Also
    --------
    vapor_pressure, dewpoint

    Notes
    -----
    Instead of temperature, dewpoint may be used in order to calculate
    the actual (ambient) water vapor (partial) pressure.

    The formula used is that from Bolton 1980 [2] for T in degrees Celsius:

    .. math:: 6.112 e^\frac{17.67T}{T + 243.5}

    References
    ----------
    .. [2] Bolton, D., 1980: The Computation of Equivalent Potential
           Temperature. Mon. Wea. Rev., 108, 1046-1053.
    '''

    return sat_pressure_0c * exp(17.67 * temperature / (temperature + 243.5))

@exporter.export
def dewpoint_rh(temperature, rh):
    r'''Calculate the ambient dewpoint given air temperature and relative
    humidity.

    Parameters
    ----------
    temperature : array_like
        Temperature in degrees Celsius
    rh : array_like
        Relative humidity expressed as a ratio in the range [0, 1]

    Returns
    -------
    array_like
        The dew point temperature in degrees Celsius, with the shape
        of the result being determined using numpy's broadcasting rules.

    See Also
    --------
    dewpoint, saturation_vapor_pressure
    '''

    return dewpoint(rh * saturation_vapor_pressure(temperature))

@exporter.export
def dewpoint(e):
    r'''Calculate the ambient dewpoint given the vapor pressure.

    Parameters
    ----------
    e : array_like
        Water vapor partial pressure in mb

    Returns
    -------
    array_like
        Dew point temperature in degrees Celsius.

    See Also
    --------
    dewpoint_rh, saturation_vapor_pressure, vapor_pressure

    Notes
    -----
    This function inverts the Bolton 1980 [3] formula for saturation vapor
    pressure to instead calculate the temperature. This yield the following
    formula for dewpoint in degrees Celsius:

    .. math:: T = \frac{243.5 log(e / 6.112)}{17.67 - log(e / 6.112)}

    References
    ----------
    .. [3] Bolton, D., 1980: The Computation of Equivalent Potential
           Temperature. Mon. Wea. Rev., 108, 1046-1053.
    '''

    val = log(e / sat_pressure_0c)
    return 243.5 * val / (17.67 - val)

@exporter.export
def mixing_ratio(part_press, tot_press):
    r'''Calculates the mixing ratio of gas given its partial pressure
    and the total pressure of the air.

    There are no required units for the input arrays, other than that
    they have the same units.

    Parameters
    ----------
    part_press : array_like
        Partial pressure of the constituent gas
    tot_press : array_like
        Total air pressure

    Returns
    -------
    array_like
        The (mass) mixing ratio, unitless (e.g. Kg/Kg or g/g)

    See Also
    --------
    vapor_pressure
    '''

    return epsilon * part_press / (tot_press - part_press)


def largest_prime(n):
    "Output the largest prime factor of a number"

    i = 2
    while n != 1:
        for i in range(2,n+1):
            if n%i == 0:
                n = int(n/i)
                p = i
                break
            else:
                pass

    return p

#The following function is unncessary and only here to confirm if the previous function output is prime
def is_prime(n):
    "Determine if a number is a prime number or not"
    for i in range(2,n+1):
        if n%i == 0:
            if i != n:
                return "Not Prime"
            else:
                return "Prime"

assert largest_prime(13195) == 29
assert largest_prime(100) == 5
print(largest_prime(600851475143))


#
# Copyright (c) 2006-2009 Advanced Micro Devices, Inc. All Rights Reserved.
# This software is subject to the Apache v2.0 License.
#

# Class module for Framewave's object files

import glob
import os
from string import replace
from os.path import *

import sys
sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-0.97'),
             join(sys.prefix, 'Lib', 'site-packages', 'scons'),
             join(sys.prefix, 'scons-0.97'), join(sys.prefix, 'scons')] + sys.path

from SCons.Script import *
from fwflags import *
from fwutil  import *
from fwbuildexceptions import dctGlobalExceptionsList

class fwObject:

    # This function will create a list of all the factors that may effect our build
    # These currently include:
    # . src filename
    # . variant, libtype, bitness
    # . toolset (msvc, gcc, suncc)
    # . path building for
    #
    # Additional build factors can be added here
    def getBuildFactors( self, oEnv ):
        # retrieve the fwvars object from the associated environment
        oFWVARS = oEnv['FWVARS']

        # Get variant, libtype and bitness
        variant = oFWVARS['variant']
        libtype = oFWVARS['libtype']
        bitness = oFWVARS['bitness']

        # Set debug information build factor
        if oFWVARS['debuginfo'] == 'off': debuginfo = None
        else:                             debuginfo = 'debuginfo'

        if   oFWVARS['wincrt']=='mt' : wincrt = 'wincrtmt'
        elif oFWVARS['wincrt']=='mtd': wincrt = 'wincrtmtd'
        elif oFWVARS['wincrt']=='md' : wincrt = 'wincrtmd'
        elif oFWVARS['wincrt']=='mdd': wincrt = 'wincrtmdd'

        # Get platform building on
        # Since there is no cross building yet
        # we can assume that the platform we're
        # building on is also the target platform
        platform = sys.platform

        # Get toolset name
        toolset = oFWVARS['toolset']

        # We could be building a single pass object, so check if path even exists
        if self.oPath:
            lstBuildFactors = [self.pthSrc, variant, libtype, bitness, platform, toolset, debuginfo, wincrt, self.oPath['OPT_LEVEL']]
        else:
            # Set the path to the single pass canary token
            lstBuildFactors = [self.pthSrc, variant, libtype, bitness, platform, toolset, debuginfo, wincrt, 'SiPC']

        lstBuildFactors = removeNones(lstBuildFactors)

        return lstBuildFactors

    def getEnvForObject( self, oEnv ):
        lstBuildFactors = self.getBuildFactors(oEnv)

        oExceptFlags = None
        toolset = oEnv['FWVARS']['toolset']
        # Check if there is any special handling for this object
        if dctGlobalExceptionsList.has_key(toolset):
            for r in dctGlobalExceptionsList[toolset]:
                if allInList(r[0], lstBuildFactors):
                    oExceptFlags = r[1]
                    # Check if we even should build this object at all
                    if oExceptFlags == None: return None

        # Make an object local copy of the environment
        oNewEnv = oEnv.Clone()

        # Initialize a flags object based on our current environment
        # and build factors; at the end of this function, our flags
        # would have been applied onto the environment object passed in

        # If there was a hit for a special flags handler in the exception list
        # instantiate that instance. The exception rules should make sure that
        # this handler is appropriate and the correct one for the given toolset
        if oExceptFlags: oFlags = oExceptFlags(oNewEnv, lstBuildFactors, "object")
        # Otherwise, there is no special handling;
        # call the appropriate flags handler
        else:            oFlags = fwFlags    (oNewEnv, lstBuildFactors, "object")

        # Return our environment; Flags should not have been applied
        return oNewEnv

    # This function will create one fwObject
    def __init__ ( self, oEnv, pthTarget, pthSrc, oPath=None ):
        self.pthSrc = pthSrc
        self.pthTarget = pthTarget # REMEMBER: do not use this path till prefix has been prepended
        self.oPath   = oPath
        self.oEnv   = self.getEnvForObject(oEnv)

        # In case we shouldn't be building this object
        if not self.oEnv:
            # Set our saved build object to None and return
            self.oObject = None
            return

        # Pull the libtype from the FWVARS object associated
        # with this enviroment, set the build function based on it
        libtype = self.oEnv['FWVARS']['libtype']
        if (libtype == 'shared'): fObjectCreate = self.oEnv.SharedObject
        else:                     fObjectCreate = self.oEnv.StaticObject # exe's use static objects

        # Get the target name (basicaly original target named prefixed with path prefix)
        self.pthTarget = applyPrefixToFilename(self.pthTarget, oPath)

        # Final step; create the build object in this environment
        # (flags have already been applied) and save that object
        self.oObject = fObjectCreate(self.pthTarget, self.pthSrc)

    def getObject( self ):
        if self.oObject: return [self.oObject]
        else:            return []

class fwMPObject:
    def __init__ ( self, oEnv, pthTarget, pthSrc):
        self.oEnv = oEnv
        self.pthSrc = pthSrc
        self.pthTarget = pthTarget
        lstPathObjects = []

        # Scan file to get paths (has to the be first line of the file)
        lstPaths = getPaths(pthSrc)

        # If no paths are present, compile for single pass
        if not lstPaths:
            lstPathObjects += [fwObject(self.oEnv, pthTarget, pthSrc)]
        else:
            # Interate over all paths. Create an object for paths for which we have markers
            for pth in oOptimizationLevels[:maxImplementedOptimizationLevel]:
                if pth['MARKER'] in lstPaths:
                    # Create an fwObject for this path and store it in the objects list
                    # These need to be created from the object list passed onto us
                    lstPathObjects += [fwObject(self.oEnv, pthTarget, pthSrc, pth)]

        # Save away the list of individual path specific objects
        self.lstPathObjects = lstPathObjects

    def getObjects( self ):
        lstObjects = []
        for po in self.lstPathObjects:
            # If the build object exists
            if po.getObject():
                # only then add it to the return list
                lstObjects += [po.getObject()[0]]

        return lstObjects


from entities.rover import Rover
from command import comproc

rov = Rover(x=0,y=1,heading='N')

command = """5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM
1 1 N
MMLMRMM
"""

c = comproc()
c.read(command)
while len(c.command_list) != 0 :
    rovData = c.getRovData()
    rov = Rover(x=int(rovData[0][0]),y=int(rovData[0][1]),heading=rovData[0][2])
    rovMoves = rovData[1]
    for i in rovMoves:
        if(i=='M'):
            rov.move()
        else:
            rov.turn(i)

    print(rov.x , rov.y, rov.heading)


import sys
from django.db import IntegrityError, transaction
from django.contrib.auth.models import User
from django.core.management.base import NoArgsCommand
from emailusernames.utils import _email_to_username

class Command(NoArgsCommand):
    def handle_noargs(self, **options):
        """Upgrade the existing User table to be usable by django-email-as-username.

        This is specifically designed for versions 1.3 and above of the package."""

        title = "Upgrading User table for django-email-as-username"
        sys.stdout.write("=====\n" + title + "\n=====\n")
        sys.stdout.flush()

        total = User.objects.count()
        failed = 0

        for user in User.objects.all():
            user.username = _email_to_username(user.email)
            try:
                sid = transaction.savepoint()
                user.save()
                transaction.savepoint_commit(sid)
            except IntegrityError:
                failed += 1
                sys.stdout.write(
                    "Could not convert user with username '%s' because the email "
                    "<%s> is already taken.\n" % (user.username, user.email)
                    )
                sys.stdout.flush()
                transaction.savepoint_rollback(sid)

        sys.stdout.write("Converted %d of %d users (%d failed).\n" % (total - failed, total, failed))


import praw

class Redditor(object):
    """
    Facade class for getting reddit posts
    """
    def __init__(self, client_id, client_secret, user_agent):
        """
        Initialize Redditor
        :param client_id: client id provided by Reddit
        :param client_secret: client secret provided by Reddit
        :param user_agent: user agent
        """
        self.reddit = praw.Reddit(client_id=client_id,
                                  client_secret=client_secret,
                                  user_agent=user_agent)

    def hot_submissions(self, limit, subreddit, *args):
        """
        Gets a random hot not stickied submission
        :param limit: Max amount of hot posts to add
        :param subreddit: First subreddit to look up the submissions
        :param args: Additional subreddits to look up the submissions
        :return: List of hot submissions from selected subreddits
        """
        submissions = []  # list of submissions

        # add non-stickied submissions from subreddit
        for submission in self.reddit.subreddit(subreddit).hot(limit=limit):
            if not submission.stickied:
                submissions.append(submission)

        # add non-stickied submissions from additional subreddits
        for sub in args:
            for submission in self.reddit.subreddit(sub).hot(limit=limit):
                if not submission.stickied:
                    submissions.append(submission)

        return submissions

    def random_hot(self, limit, subreddit, *args):
        """
        Retrieve random hot post from subreddit and additional subreddits specified in *args
        :param limit: The amount of hot posts to look up from subreddit
        :param subreddit: First subreddit to look up the submissions
        :param args: Additional subreddits to look up the submissions
        :return: Random hot submission
        """
        from random import choice
        return choice(self.hot_submissions(limit, subreddit, *args))


#!env python
import sys
import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui

class SliderWindow(QtGui.QWidget):
    count = 0
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent=parent)

        self.sliders = QtGui.QWidget(parent=self)
        self.locater = QtGui.QWidget(parent=self)
        self.TextEdit = QtGui.QTextEdit(parent=self)

        self.init_sliders()

        self.locater.setFixedSize(300,300)
        self.locater.setGeometry(0, 0, 280, 270)

        layout1 = QtGui.QHBoxLayout()
        layout1.addWidget(self.locater)
        layout1.addWidget(self.sliders)

        layout = QtGui.QVBoxLayout()
        layout.addLayout(layout1)
        layout.addWidget(self.TextEdit)

        self.setLayout(layout)

    def init_sliders(self):
        self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)

        self.Param = {'count':0, 'rad1': 0, 'rad2':50, 'dia':50, 'space':0}
        self.timerId = self.startTimer(5)

        slider_layout = QtGui.QVBoxLayout()

        slider_rad1 = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        #slider_rad1.setFocusPolicy(QtCore.Qt.NoFocus)
        slider_rad1.valueChanged.connect(self.changeValue_rad1)

        slider_rad2 = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        slider_rad2.valueChanged.connect(self.changeValue_rad2)

        slider_diam = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        slider_diam.valueChanged.connect(self.changeValue_diam)

        slider_space = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        slider_space.valueChanged.connect(self.changeValue_space)

        self.label_rad1 = QtGui.QLabel(self)
        self.label_rad1.setText('rad1: '+'0')
        self.label_rad2 = QtGui.QLabel(self)
        self.label_rad2.setText('rad2: '+'0')
        self.label_diam = QtGui.QLabel(self)
        self.label_diam.setText('diam: '+'0')
        self.label_space = QtGui.QLabel(self)
        self.label_space.setText('space: '+'0')
        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(self.label_rad1)
        hbox1.addWidget(slider_rad1)
        hbox2 = QtGui.QHBoxLayout()
        hbox2.addWidget(self.label_rad2)
        hbox2.addWidget(slider_rad2)
        hbox3 = QtGui.QHBoxLayout()
        hbox3.addWidget(self.label_diam)
        hbox3.addWidget(slider_diam)
        hbox4 = QtGui.QHBoxLayout()
        hbox4.addWidget(self.label_space)
        hbox4.addWidget(slider_space)
        slider_layout.addLayout(hbox1)
        slider_layout.addLayout(hbox2)
        slider_layout.addLayout(hbox3)
        slider_layout.addLayout(hbox4)

        self.sliders.setLayout(slider_layout)

        self.repaint()

    def changeValue_rad1(self, value):
        self.label_rad1.setText('rad1: '+str(value))
        self.Param['rad1'] = value
        self.generateRMCode()
        self.repaint()

    def changeValue_rad2(self, value):
        self.label_rad2.setText('rad2: '+str(value))
        self.Param['rad2'] = value
        self.generateRMCode()
        self.repaint()

    def changeValue_diam(self, value):
        self.label_diam.setText('diam: '+str(value))
        self.Param['dia'] = value
        self.generateRMCode()
        self.repaint()

    def changeValue_space(self, value):
        self.label_space.setText('space: '+str(value))
        self.Param['space'] = value
        self.generateRMCode()
        self.repaint()

    def generateRMCode(self):
        self.TextEdit.setText(self.gen_TeamSpacingModifier() + self.gen_PlaceCircular() + self.gen_PlacementSection())

    def gen_TeamSpacingModifier(self):
        f_to = 1
        f_from = 0
        prm = round(self.Param['space']/100.0 * (f_to - f_from) + f_from, 2)
        return '   rmSetTeamSpacingModifier('+str(prm)+');\n'

    def gen_PlacementSection(self):
        f_to = 1.0
        f_from = 0.0
        cprm1 = round(self.Param['rad1']/100.0 * (f_to - f_from) + f_from, 2)
        cprm2 = round(self.Param['rad2']/100.0 * (f_to - f_from) + f_from, 2)
        prm_2_1 = cprm1
        prm_2_2 = cprm2
        prm_4_1 = cprm1 - 0.025
        prm_4_2 = cprm2 + 0.025
        prm_6_1 = cprm1 - 0.05
        prm_6_2 = cprm2 + 0.05

        return '''    if ( cNumberNonGaiaPlayers < 3){
        rmSetPlacementSection('''+str(prm_2_1)+ ', '+str(prm_2_2)+''');
    }else if (cNumberNonGaiaPlayers < 5){
        rmSetPlacementSection('''+str(prm_4_1)+ ', '+str(prm_4_2)+''');
    }else{
        rmSetPlacementSection('''+str(prm_6_1)+ ', '+str(prm_6_2)+''');
    }\n'''

    def gen_PlaceCircular(self):
        f_to = 0.5
        f_from = 0.1
        prm = round(self.Param['dia']/100.0 * (f_to - f_from) + f_from, 2)
        return '    rmPlacePlayersCircular('+str(prm)+', '+str(prm)+', 0);\n'

    def paintEvent(self, event):
        painter = QtGui.QPainter()
        painter.begin(self)
        self.locater.paintEvent(event)
        self.draw_locater(event, painter)
        painter.end()

    def draw_locater(self, event, painter):
        h = self.locater.height()
        w = self.locater.width()
        csize = 230 * ( self.Param['dia'] / 200.0  + 0.5 )
        psize = 20

        # draw initialising
        brush = QtGui.QBrush(QtGui.QColor(0,120,0)) #green
        painter.translate(QtCore.QPoint(h/2, h/2))
        painter.setPen(QtGui.QPen(brush , 1))
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.save()
        painter.drawEllipse(-csize/2, -csize/2, csize, csize)

        # Blue Team 1
        brush = QtGui.QBrush(QtGui.QColor(0,0,self.grow(120,255)))
        painter.setPen(QtGui.QPen(brush , 1))
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.rotate(-45.0)
        painter.rotate(self.Param['rad1'] * 360 / 100.0)
        rot1 = 40 * self.Param['space'] /100.0
        for i in range(3):
            painter.drawEllipse((-csize-psize)/2, (-psize)/2, psize, psize)
            painter.rotate(rot1)

        # Red Team 2
        painter.restore()
        painter.save()
        brush = QtGui.QBrush(QtGui.QColor(self.grow(120,255),0,0))
        painter.setPen(QtGui.QPen(brush , 1))
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.rotate(135.0)
        painter.rotate(self.Param['rad2'] * 360 / 100.0)
        rot2 = 40 * self.Param['space'] /100.0
        for i in range(3):
            painter.drawEllipse((-csize-psize)/2, (-psize)/2, psize, psize)
            painter.rotate(rot2)

        # picture background
        painter.restore()
        brush = QtGui.QBrush(QtGui.QColor(200,200,200))
        painter.setPen(QtGui.QPen(brush , 0.5))
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.rotate(self.Param['rad1'] * 7 % 360)
        rot = 0
        while rot < 360.0:
            painter.drawEllipse(-125, -40, 150, 80)
            painter.rotate(5.0)
            rot += 5.0

    # TODO: draw grow() with lambda
    def grow(self, minv, maxv):
        dev = self.count % (2 * (maxv-minv))
        if dev > (maxv - minv):
            return 2 * (maxv - minv) - dev + minv
        else:
            return dev + minv

    def timerEvent(self, event):
        self.count = self.count + 1
        self.repaint()

def main():
    app = QtGui.QApplication(sys.argv)

    panel = QtGui.QWidget()

    slider_widget = SliderWindow(parent=panel)

    panel_layout = QtGui.QVBoxLayout()
    panel_layout.addWidget(slider_widget)
    panel.setLayout(panel_layout)
    panel.setFixedSize(600, 600)

    main_window = QtGui.QMainWindow()
    main_window.setWindowTitle("AoE3 Random Map Tool")
    main_window.setCentralWidget(panel)

    main_window.show()

    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""
/***************************************************************************
 DigCrossSection
                                 A QGIS plugin
 Dig the cross section
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2021-02-04
        git sha              : $Format:%H$
        copyright            : (C) 2021 by Yu Shen
        email                : t106340103@ntut.org.tw
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from sys import flags
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction

# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from qgis.core import *
from qgis.gui import QgisInterface
from qgis.utils import iface
from .Dig_CrossSection_dialog import DigCrossSectionDialog
import os.path
import os,sys
import gdal
import numpy as np
import time
import processing
from PyQt5 import QtWidgets,QtCore,QtGui
from PyQt5.QtWidgets import QApplication,QPushButton,QLabel,QComboBox,QFileDialog
from qgis.gui import QgsFileWidget

class DigCrossSection:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'DigCrossSection_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&DigCrossSection')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('DigCrossSection', message)

    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/Dig_CrossSection/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Dig cross section'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = False

        self.dlg = DigCrossSectionDialog()
        self.dlg.pushButton_difference.clicked.connect(self.select_output_file_difference)
        self.dlg.pushButton_merge.clicked.connect(self.select_output_file_merge)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&DigCrossSection'),
                action)
            self.iface.removeToolBarIcon(action)

    def select_output_file_difference(self):
        filename = QFileDialog.getSaveFileName(self.dlg, "Select difference output file ","", '*.shp')
        name = str(filename[0])
        self.dlg.lineEdit_difference.setText(name)

    def select_output_file_merge(self):
        filename = QFileDialog.getSaveFileName(self.dlg, "Select merge output file ","", '*.shp')
        name = str(filename[0])
        self.dlg.lineEdit_merge.setText(name)

    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = DigCrossSectionDialog()

        lyr = [layer for layer in QgsProject.instance().mapLayers().values()]
        self.comboBox = self.dlg.findChild(QComboBox , "Shp_File")
        self.comboBox.clear()
        for layer in lyr:
            if layer.type() == QgsMapLayer.VectorLayer:
                self.comboBox.addItems([layer.name()])

        self.comboBox3 = self.dlg.findChild(QComboBox , "Shp_File_Area")
        self.comboBox3.clear()
        for layer in lyr:
            if layer.type() == QgsMapLayer.VectorLayer:
                self.comboBox3.addItems([layer.name()])

        self.comboBox2 = self.dlg.findChild(QComboBox , "DEM_File")
        self.comboBox2.clear()
        for layer in lyr:
            if layer.type() == QgsMapLayer.RasterLayer:
                self.comboBox2.addItems([layer.name()])

        # Clear save file path
        self.dlg.lineEdit_difference.clear()
        self.dlg.lineEdit_merge.clear()

        # show the dialog
        self.dlg.show()

        # Run the dialog event loop
        result = self.dlg.exec_()

        # Select DEM
        self.DEM_layer = QgsProject.instance().mapLayersByName(self.comboBox2.currentText())[0]
        self.DEM_path = self.DEM_layer.source()

        # Select layer
        self.shp_layer = QgsProject.instance().mapLayersByName(self.comboBox.currentText())[0]

        self.Area_layer = QgsProject.instance().mapLayersByName(self.comboBox3.currentText())[0]

        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            strtime = time.time()
            # Get parameters

            save1 = self.dlg.lineEdit_difference.text()
            save2 = self.dlg.lineEdit_merge.text()
            threshold = int(self.dlg.threshold.text())
            slope = float(self.dlg.max_slope_length.text())
            dig_value = float(self.dlg.Dig_value.text())

            print("shapfile procress")
            from .CalculateProcress.Vector import VectorProcress
            VecterLayer = VectorProcress(self.shp_layer,self.Area_layer)

            if VecterLayer.Check_Select_Area(): VecterLayer.Generate_Select_Area()

            VecterLayer.Channel_Buffer()
            VecterLayer.Merge_features()
            VecterLayer.Generate_New_Extent_Layer()

            print("DEM procress")
            from .CalculateProcress.Raster import RasterProcress
            RasterLayer = RasterProcress(self.DEM_path,VecterLayer.Get_Buffer_Area_Path(),VecterLayer.Get_Channel_Path(),dig_value)
            RasterLayer.Select_Extent_And_Dig_Channel()

            print("grass procress")
            from .CalculateProcress.GrassCalculate import grassCal
            grassfile = grassCal(RasterLayer.Get_Calculate_DEM(),threshold,slope)
            grassresult = grassfile.run_watershed()

            basinresult = grassfile.Output_Vector(grassresult['basin'],2)

            streamresult = grassfile.Output_Vector(grassresult['stream'],0)

            print("start to merge calculated layer to origin")

            self.Area_layer = VecterLayer.Fix_Error(self.Area_layer.source())
            Splitresult = grassfile.Split_Select_Basin_from_Buffer(basinresult["output"],VecterLayer.Get_Area_Path(),0,0)
            Difreault = VecterLayer.Difference(self.Area_layer.source(),save1)
            Mergeresult = VecterLayer.Merge_Layer(save1,Splitresult["output"],save2)
            #print(Mergeresult["OUTPUT"])
            endtime = time.time()
            print("cost time:",(endtime - strtime))
            #self.iface.addVectorLayer(save2, "Stream")


class Solution:
    # @return a string
    def __init__(self) :
        self.N_0_9 = ['','I','II','III','IV','V','VI','VII','VIII','IX']
        self.N_10_90 = ['', 'X','XX','XXX','XL','L','LX','LXX','LXXX','XC']
        self.N_100_900 = ['', 'C','CC','CCC','CD','D','DC','DCC','DCCC','CM']
        self.N_1000_3000=['', 'M', 'MM', 'MMM']

    def findV(self, roman, array, n) :
        lenA = len(array)
        for i in range(len(array)) :
            if roman.startswith(array[lenA-1-i]) :
                return n * (lenA-1-i), len(array[lenA-1-i])
    def romanToInt(self, s):
        sum = 0
        cur, used = self.findV(s, self.N_1000_3000, 1000)
        sum, s = sum + cur, s[used:]
        cur, used = self.findV(s, self.N_100_900, 100)
        sum, s = sum + cur, s[used:]
        cur, used = self.findV(s, self.N_10_90, 10)
        sum, s = sum + cur, s[used:]
        cur, used = self.findV(s, self.N_0_9, 1)
        sum = sum + cur
        return sum

    def intToRoman(self, num):
        return SELF.N_1000_3000[num / 1000] +  SELF.N_100_900[num % 1000 / 100]+\
            SELF.N_10_90[num % 100 / 10] + SELF.N_0_9[num % 10]


import csv
import glob
import json
import logging
import os
from typing import List

import tqdm

from transformers import PreTrainedTokenizer

logger = logging.getLogger(__name__)

class InputExample(object):
    """A single training/test example for multiple choice"""

    def __init__(self, example_id, question, contexts, endings, label=None):
        """Constructs a InputExample.
        Args:
            example_id: Unique id for the example.
            contexts: list of str. The untokenized text of the first sequence (context of corresponding question).
            question: string. The untokenized text of the second sequence (question).
            endings: list of str. multiple choice's options. Its length must be equal to contexts' length.
            label: (Optional) string. The label of the example. This should be
            specified for train and dev examples, but not for test examples.
        """
        self.example_id = example_id
        self.question = question
        self.contexts = contexts
        self.endings = endings
        self.label = label

class InputFeatures(object):
    def __init__(self, example_id, choices_features, label):
        self.example_id = example_id
        self.choices_features = [
            {"input_ids": input_ids, "input_mask": input_mask, "segment_ids": segment_ids}
            for input_ids, input_mask, segment_ids in choices_features
        ]
        self.label = label

class DataProcessor(object):
    """Base class for data converters for multiple choice data sets."""

    def get_train_examples(self, data_dir):
        """Gets a collection of `InputExample`s for the train set."""
        raise NotImplementedError()

    def get_dev_examples(self, data_dir):
        """Gets a collection of `InputExample`s for the dev set."""
        raise NotImplementedError()

    def get_test_examples(self, data_dir):
        """Gets a collection of `InputExample`s for the test set."""
        raise NotImplementedError()

    def get_labels(self):
        """Gets the list of labels for this data set."""
        raise NotImplementedError()

class SwagProcessor(DataProcessor):
    """Processor for the SWAG data set."""

    def get_train_examples(self, data_dir):
        """See base class."""
        logger.info("LOOKING AT {} train".format(data_dir))
        return self._create_examples(self._read_csv(os.path.join(data_dir, "train.csv")), "train")

    def get_dev_examples(self, data_dir):
        """See base class."""
        logger.info("LOOKING AT {} dev".format(data_dir))
        return self._create_examples(self._read_csv(os.path.join(data_dir, "val.csv")), "val")

    def get_test_examples(self, data_dir):
        """See base class."""
        logger.info("LOOKING AT {} dev".format(data_dir))
        #raise ValueError(
         #   "For swag testing, the input file does not contain a label column. It can not be tested in current code"
          #  "setting!"
        #)
        return self._create_examples(self._read_csv(os.path.join(data_dir, "test.csv")), "test")

    def get_labels(self):
        """See base class."""
        return ["0", "1"] #these are the labels of the endings

    def _read_csv(self, input_file):
        with open(input_file, "r", encoding="utf-8") as f:
            return list(csv.reader(f))

    def _create_examples(self, lines: List[List[str]], type: str):
        """Creates examples for the training and dev sets."""
        if type == "train" and lines[0][-1] != "label":
            raise ValueError("For training, the input file must contain a label column.")
        print(len(lines))
        print(len(lines[0]))
        examples = [
            InputExample(
                example_id=line[0], #this is the way the data is organized
                question=line[1],  #the startphrase or question
                contexts=[line[1], line[1]],
                endings=[line[2], line[3]], #possible endings/ sentence choices for ComVe
                label=str(line[4]), #label 0 or 1
            )
            for line in lines[1:]  # we skip the line with the column names
        ]
        return examples

def convert_examples_to_features(
    examples: List[InputExample],
    label_list: List[str],
    max_length: int,
    tokenizer: PreTrainedTokenizer,
    pad_token_segment_id=0,
    pad_on_left=False,
    pad_token=0,
    mask_padding_with_zero=True,
) -> List[InputFeatures]:
    """
    Loads a data file into a list of `InputFeatures`
    """

    label_map = {label: i for i, label in enumerate(label_list)}
    print("LABEL MAP", label_map)
    features = []
    for (ex_index, example) in tqdm.tqdm(enumerate(examples), desc="convert examples to features"):
        if ex_index % 10000 == 0:
            logger.info("Writing example %d of %d" % (ex_index, len(examples)))
        choices_features = []
        for ending_idx, (context, ending) in enumerate(zip(example.contexts, example.endings)):
            text_a = context
            if example.question.find("_") != -1:
                # this is for cloze question
                text_b = example.question.replace("_", ending)
            else:
                text_b = example.question + " " + ending

            inputs = tokenizer.encode_plus(text_a, text_b, add_special_tokens=True, max_length=max_length,)
            if "num_truncated_tokens" in inputs and inputs["num_truncated_tokens"] > 0:
                logger.info(
                    "Attention! you are cropping tokens (swag task is ok). "
                    "If you are training ARC and RACE and you are poping question + options,"
                    "you need to try to use a bigger max seq length!"
                )

            input_ids, token_type_ids = inputs["input_ids"], inputs["token_type_ids"]

            # The mask has 1 for real tokens and 0 for padding tokens. Only real
            # tokens are attended to.
            attention_mask = [1 if mask_padding_with_zero else 0] * len(input_ids)

            # Zero-pad up to the sequence length.
            padding_length = max_length - len(input_ids)
            if pad_on_left:
                input_ids = ([pad_token] * padding_length) + input_ids
                attention_mask = ([0 if mask_padding_with_zero else 1] * padding_length) + attention_mask
                token_type_ids = ([pad_token_segment_id] * padding_length) + token_type_ids
            else:
                input_ids = input_ids + ([pad_token] * padding_length)
                attention_mask = attention_mask + ([0 if mask_padding_with_zero else 1] * padding_length)
                token_type_ids = token_type_ids + ([pad_token_segment_id] * padding_length)

            assert len(input_ids) == max_length
            assert len(attention_mask) == max_length
            assert len(token_type_ids) == max_length
            choices_features.append((input_ids, attention_mask, token_type_ids))

        label = label_map[example.label]

        if ex_index < 2:
            logger.info("*** Example ***")
            logger.info("race_id: {}".format(example.example_id))
            for choice_idx, (input_ids, attention_mask, token_type_ids) in enumerate(choices_features):
                logger.info("choice: {}".format(choice_idx))
                logger.info("input_ids: {}".format(" ".join(map(str, input_ids))))
                logger.info("attention_mask: {}".format(" ".join(map(str, attention_mask))))
                logger.info("token_type_ids: {}".format(" ".join(map(str, token_type_ids))))
                logger.info("label: {}".format(label))

        features.append(InputFeatures(example_id=example.example_id, choices_features=choices_features,label=label))

    return features

processors = {"swag": SwagProcessor}

MULTIPLE_CHOICE_TASKS_NUM_LABELS = {"swag", 2}


import abc
import os
import re

import pandas as pd
from werkzeug.utils import secure_filename

from app_folder import db
from app_folder.models import LinkedInRecord, Contact, EtherealAddress, EtherealContact
from site_config import FConfig
from cytoolz import groupby

ALLOWED_EXTENSIONS = ['.csv', '.xls', '.xlsx']
TRY_ENCODINGS = ['default', 'unicode' 'latin1', 'cp1252', 'iso-8859-1', 'ascii']
UPLOAD_FOLDER = FConfig.UPLOAD_FOLDER

def inject_allowed_ext():
    return dict(allowed_ext=ALLOWED_EXTENSIONS)

class UploadSpreadsheet(object):
    """
    class object to handle heavy lifting of receiving files via upload

    :param request_file: flask request object
    """

    # TODO Subclass, mixins for email providers
    allowed_extensions = ALLOWED_EXTENSIONS
    try_encodings = TRY_ENCODINGS

    def __init__(self, request_file):
        self.request_file = request_file
        self.uploaded_file_path = None
        self.uploaded_file = None
        self.status = None

        self.open_file_()

    def find_file_ext_(self):
        filename = self.request_file.filename
        if not filename:
            return None
        _, file_ext = os.path.splitext(filename)
        return file_ext

    def allowed_file_(self):
        ext = self.find_file_ext_()
        if ext in self.allowed_extensions:
            return True
        else:
            self.status = "Extension {} not permitted".format(ext)
            return False

    def save_upload_(self):

        file = self.request_file
        if not file:
            self.status = "No file received"
            return None
        if file.filename == '':
            self.status = "Your file name is blank"
            return None

        filename = secure_filename(file.filename)

        if self.allowed_file_() is False:
            return None

        # Save file to open later for analysis
        file.save(os.path.join(UPLOAD_FOLDER, filename))

        # Save location
        file_path = os.path.join(UPLOAD_FOLDER, filename)

        return file_path

    def open_file_(self):

        """
        Function that handles opening the spreadsheet with pandas
        Gets file extension and uses appropriate open method with pandas
        Tries several encodings until opening is successful or ends with fail

        :return: pd.DataFrame() or False if fail to open
        """

        self.uploaded_file_path = self.save_upload_()
        if not self.uploaded_file_path:
            print(self.status)
            return None
        file_ext = self.find_file_ext_()
        if not file_ext:
            return None

        if file_ext == '.csv':
            open_method = pd.read_csv
        elif file_ext == '.xls' or file_ext == '.xlsx':
            open_method = pd.read_excel
        else:
            # No file extension found
            self.status = 'No file extension was found'
            return None

        for encoding in self.try_encodings:
            try:
                if encoding == 'default':
                    df = open_method(self.uploaded_file_path)

                else:
                    df = open_method(self.uploaded_file_path, encoding=encoding)
                self.uploaded_file = df
                break
            except Exception as e:
                print(e)
                if encoding == self.try_encodings[-1]:
                    # Tried all encodings, all failed
                    self.status = "Unable to determine file encoding"
                    return None
                else:
                    continue

class OptoutSpreadsheet(UploadSpreadsheet):

    EMAIL_SEARCH = re.compile(r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
    TARGET_HEADER = 'All emails'

    def __init__(self, request_file):
        self.new_nodes = []
        self.appended_nodes = []
        super().__init__(request_file)
        self.find_new_emails()

    def find_new_emails(self):

        """

        Parses spreadsheet rows to find emails. Each row may contain 0 or more emails

        For each row, if all email addresses are 'new' they are created along with a new EtherealContact

        Else, the 'new' address is created and appended to an existing EtherealContact

        :return:
        """

        new_nodes = []
        appended_nodes = []

        addresses = self.uploaded_file[self.TARGET_HEADER].apply(lambda x: self.EMAIL_SEARCH.findall(x))
        existing_ethereal = EtherealAddress.query.join(EtherealAddress.parent_contact)\
            .filter(EtherealContact._kind == EtherealContact.OPTOUT)
        existing_addresses = set([x.address for x in existing_ethereal])

        def attach_node(duplicated_address_group, xst=existing_addresses):

            # Find the matched EtherealAddress and Attach to .parent
            segmented_data = groupby(lambda x: x in xst, duplicated_address_group)
            is_duplicated, not_duplicated = segmented_data.get(True, []), segmented_data.get(False, [])
            if not is_duplicated:
                return None
            if not not_duplicated:
                return None

            # Query for parent

            parent = EtherealContact.query.filter(EtherealContact.children.any(
                EtherealAddress.address.in_(is_duplicated))).from_self().filter(
                EtherealContact._kind == EtherealContact.OPTOUT).first()

            if not parent:
                return None

            for new_address in not_duplicated:
                new_ethereal = EtherealAddress(is_email=True, is_personal=True, is_phone=False, is_website=False,
                                               address=new_address)
                db.session.add(new_ethereal)
                parent.children.append(new_ethereal)

            return parent

        def create_node(new_address_group):

            new_parent = EtherealContact(_kind=EtherealContact.OPTOUT)
            db.session.add(new_parent)

            for address in new_address_group:
                new_ethereal = EtherealAddress(is_email=True, is_personal=True, is_phone=False, is_website=False,
                                               address=address)
                db.session.add(new_ethereal)
                new_parent.children.append(new_ethereal)

            return new_parent

        for address_group in addresses:
            if not address_group:
                continue
            if any([x in existing_addresses for x in address_group]):
                if not all([x in existing_addresses for x in address_group]):
                    attached_node = attach_node(address_group)
                    if attached_node:
                        appended_nodes.append(attached_node)

            else:
                new_node = create_node(address_group)
                if new_node:
                    new_nodes.append(new_node)

        self.new_nodes = new_nodes
        self.appended_nodes = appended_nodes

        db.session.commit()

class ContactSpreadsheet(abc.ABC, UploadSpreadsheet):

    EMAIL_PERSONAL = 'email_personal'
    EMAIL_NOT_PERSONAL = 'email_work'
    PHONE_PERSONAL = 'phone_personal'
    WEBSITE_PERSONAL = 'website_personal'
    WEBSITE_LINKEDIN = 'website_linkedin'
    MEMBER_ID = 'member_id'

    @property
    @abc.abstractmethod
    def HEADER_SEARCH(self):
        return None

    @property
    @abc.abstractmethod
    def KEEP_PATTERNS(self):
        return []

    @abc.abstractmethod
    def scan_headers_(self):
        relevant_headers = {k: [] for k in self.HEADER_SEARCH.keys()}

        cols = self.uploaded_file.columns.tolist()
        for data_type, pattern in self.HEADER_SEARCH.items():
            relevant_headers[data_type] = [match.group() for match in [pattern.search(c) for c in cols] if match]

        return relevant_headers

    @abc.abstractmethod
    def scan_data_(self):

        relevant_headers = self.scan_headers_()
        file_data = self.uploaded_file.fillna('').to_dict('records')

        data_records = []

        for row_data in file_data:
            td = {}
            for data_type, header_names in relevant_headers.items():
                td[data_type] = [sv for sv in [v for k, v in row_data.items() if k in header_names] if self.filter_data_(sv, data_type)]
            data_records.append(td)
        return data_records

    @abc.abstractmethod
    def filter_data_(self, sv, data_type):
        if sv == '':
            return None
        if not self.KEEP_PATTERNS:
            return True
        for kept in self.KEEP_PATTERNS:
            for kept_type in kept['in']:
                if kept_type not in data_type:
                    continue
                if kept['pattern'] is False:
                    return True
                if kept['pattern'].search(sv) is not None:
                    return True
        return False

class JobJetSpreadsheet(ContactSpreadsheet):

    @property
    def HEADER_SEARCH(self):
        return {self.EMAIL_PERSONAL: re.compile(r"(Personal email \(\d\))", flags=re.IGNORECASE),
                self.EMAIL_NOT_PERSONAL: re.compile(r"(Work email \(\d\))", flags=re.IGNORECASE),
                self.PHONE_PERSONAL: re.compile(r"(Personal phone \(\d\))", flags=re.IGNORECASE),
                self.WEBSITE_PERSONAL: re.compile("(Website url \(\d\))", flags=re.IGNORECASE),
                self.WEBSITE_LINKEDIN: re.compile("(LinkedIn url \(\d\))", flags=re.IGNORECASE),
                self.MEMBER_ID: re.compile(r"(Tag1)", flags=re.IGNORECASE)}

    @property
    def KEEP_PATTERNS(self):

        """
        Fine grained control over filtering incoming data

        Where 'in' refers to the column data type and pattern refers to a regex object
        Specify False to allow all values
        """

        return [{'pattern': False, 'in': ['member_id']},
                {'pattern': False, 'in': ['email']},
                {'pattern': False, 'in': ['phone']},
                {'pattern': re.compile(r"(linkedin)|(github)|(twitter)|(google)|(facebook)", flags=re.IGNORECASE),
                 'in': ['website']}]

    def __init__(self, request):
        super().__init__(request)
        self.data_ = []
        if self.uploaded_file is not None:
            self.scan_data_()

    @property
    def records(self):
        return self.data_

    @records.getter
    def records(self):
        return self.data_

    def scan_data_(self):
        data_records = super().scan_data_()
        self.data_ = data_records

    def scan_headers_(self):
        relevant_headers = super().scan_headers_()
        return relevant_headers

    def filter_data_(self, sv, data_type):
        return super().filter_data_(sv, data_type)

class VsourceSpreadsheet(ContactSpreadsheet):

    @property
    def HEADER_SEARCH(self):
        return {'email_personal': re.compile(r"(home email_\d)", flags=re.IGNORECASE),
                'email_work': re.compile(r"(work email_\d)", flags=re.IGNORECASE),
                'website_personal': re.compile("(website_\d)", flags=re.IGNORECASE),
                'phone_personal': re.compile(r"(home phone_\d)", flags=re.IGNORECASE),
                'member_id': re.compile(r"(Tag1)", flags=re.IGNORECASE)}

    @property
    def KEEP_PATTERNS(self):
        return [{'pattern': False, 'in': ['member_id']},
                {'pattern': False, 'in': ['email']},
                {'pattern': False, 'in': ['phone']},
                {'pattern': re.compile(r"(github)|(twitter)|(google)|(facebook)", flags=re.IGNORECASE),
                 'in': ['website']}]

    def __init__(self, request):
        super().__init__(request)
        self.data_ = []
        if self.uploaded_file is not None:
            self.scan_data_()

    @property
    def records(self):
        return self.data_

    @records.getter
    def records(self):
        return self.data_

    def scan_data_(self):
        data_records = super().scan_data_()
        self.data_ = data_records

    def scan_headers_(self):
        relevant_headers = super().scan_headers_()
        return relevant_headers

    def filter_data_(self, sv, data_type):
        return super().filter_data_(sv, data_type)

class DataMapper(object):

    def __init__(self, mapped_object):
        self.mapped_object = mapped_object
        self.key_values = ['linkedin', 'member_id']

    def fetch_record_(self, row_data):
        member_id = row_data.get('member_id', None)
        linkedin_url = row_data.get('website_linkedin', None)
        if not member_id and not linkedin_url:
            return None
        if member_id:
            record = LinkedInRecord.query.get(member_id)
        else:
            record = None
        if not record and linkedin_url:
            record = LinkedInRecord.query.filter(LinkedInRecord.public_url.in_(linkedin_url)).all()
            if len(record) > 1:  # Avoid duplicating
                return None
            elif len(record) == 1:
                return record[0]
            else:
                return None
        return record

    def contact_factory(self, data_type):

        # Is it email, website or phone?
        if 'email' in data_type:
            is_email, is_website, is_phone = True, False, False
        elif 'website' in data_type:
            is_email, is_website, is_phone = False, True, False
        else:
            is_email, is_website, is_phone = False, False, True

        if 'person' in data_type:
            is_personal = True
        else:
            is_personal = False

        # Make new contact
        crecord = Contact(is_email=is_email, is_personal=is_personal, is_website=is_website, is_phone=is_phone)
        return crecord

    def ethereal_factory(self, data_type):

        # Is it email, website or phone?
        if 'email' in data_type:
            is_email, is_website, is_phone = True, False, False
        elif 'website' in data_type:
            is_email, is_website, is_phone = False, True, False
        else:
            is_email, is_website, is_phone = False, False, True

        if 'person' in data_type:
            is_personal = True
        else:
            is_personal = False

        # Make new contact
        crecord = EtherealAddress(is_email=is_email, is_personal=is_personal, is_website=is_website, is_phone=is_phone)
        crecord._kind = crecord.UNLINKED
        return crecord

    def enrich_record_(self, row_data):

        record = self.fetch_record_(row_data)
        if not record:
            return None, -1  # -1 Indicates no record found
        contact_records = []

        for data_type, data_values in row_data.items():

            if not data_values:
                continue
            if any([data_type in kv for kv in self.key_values]):  # Linkedin, member_id
                continue

            # Check for duplicate values, prevent adding
            if record.contacts:
                current_contacts_addr = [cr.address for cr in record.contacts]
                data_values = list(filter(lambda x: x not in current_contacts_addr, data_values))

            if not data_values:
                continue

            for dv in data_values:
                crecord = self.contact_factory(data_type)
                crecord.address = dv
                db.session.add(crecord)
                contact_records.append(crecord)

        if contact_records:
            record.contacts.extend(contact_records)
            db.session.add(record)
            return record, 1  # 1 is successfully added contact information
        else:
            return None, 0  # 0 indicates found record, no new information

    def enrich(self):

        data_records = self.mapped_object.records
        row_count = len(data_records)
        enriched_records = []
        outcomes = []
        for d in data_records:
            enriched_record = self.enrich_record_(d)
            if enriched_record[0]:
                enriched_records.append(enriched_record[0])
                outcomes.append(enriched_record[1])
            else:
                outcomes.append(enriched_record[1])
        return enriched_records, row_count, outcomes


def distance(box_1, box_2):
        x1, y1, x2, y2 = box_1
        x3, y3, x4, y4 = box_2
        dis = abs(x3 - x1) + abs(y3 - y1) + abs(x4- x2) + abs(y4 - y2)
        dis_2 = abs(x3 - x1) + abs(y3 - y1)
        dis_3 = abs(x4- x2) + abs(y4 - y2)
        return dis + min(dis_2, dis_3)

def compute_iou(rec1, rec2):
    """
    computing IoU
    :param rec1: (y0, x0, y1, x1), which reflects
            (top, left, bottom, right)
    :param rec2: (y0, x0, y1, x1)
    :return: scala value of IoU
    """
    # computing area of each rectangles
    S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
    S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])

    # computing the sum_area
    sum_area = S_rec1 + S_rec2

    # find the each edge of intersect rectangle
    left_line = max(rec1[1], rec2[1])
    right_line = min(rec1[3], rec2[3])
    top_line = max(rec1[0], rec2[0])
    bottom_line = min(rec1[2], rec2[2])

    # judge if there is an intersect
    if left_line >= right_line or top_line >= bottom_line:
        return 0.0
    else:
        intersect = (right_line - left_line) * (bottom_line - top_line)
        return (intersect / (sum_area - intersect))*1.0


'''
Utilities for cross-modality hashing experiments, including data loading and
statistics
'''
import numpy as np
import theano
import scipy.spatial
import pickle
import lasagne
import collections

def standardize(X):
    ''' Return column vectors to standardize X, via (X - X_mean)/X_std

    :parameters:
        - X : np.ndarray, shape=(n_filters, n_examples, n_features)
            Data matrix

    :returns:
        - X_mean : np.ndarray, shape=(n_filters, 1, n_features)
            Mean column vector
        - X_std : np.ndarray, shape=(n_filters, 1, n_features)
            Standard deviation column vector
    '''
    std = np.std(X, axis=1)
    return (np.mean(X, axis=1).reshape(X.shape[0], 1, X.shape[2]),
            (std + (std == 0)).reshape(X.shape[0], 1, X.shape[2]))

def load_data(train_list, valid_list):
    '''
    Load in dataset given lists of files in each split.
    Also standardizes (using train mean/std) the data.
    Each file should be a .npz file with a key 'X' for data in the X modality
    and 'Y' for data in the Y modality.

    :parameters:
        - train_list : list of str
            List of paths to files in the training set.
        - valid_list : list of str
            List of paths to files in the validation set.

    :returns:
        - X_train : list
            List of np.ndarrays of X modality features in training set
        - Y_train : list
            List of np.ndarrays of Y modality features in training set
        - X_valid : list
            List of np.ndarrays of X modality features in validation set
        - Y_valid : list
            List of np.ndarrays of Y modality features in validation set
    '''
    # We'll use dicts where key is the data subset, so we can iterate
    X = collections.defaultdict(list)
    Y = collections.defaultdict(list)
    for file_list, key in zip([train_list, valid_list],
                              ['train', 'valid']):
        # Load in all files
        for filename in file_list:
            data = np.load(filename)
            # Shingle and convert to floatX with correct column order
            X[key].append(np.array(
                data['X'], dtype=theano.config.floatX, order='C'))
            Y[key].append(np.array(
                data['Y'], dtype=theano.config.floatX, order='C'))
        # Get mean/std for training set
        if key == 'train':
            X_mean, X_std = standardize(np.concatenate(X[key], axis=1))
            Y_mean, Y_std = standardize(np.concatenate(Y[key], axis=1))
        # Use training set mean/std to standardize
        X[key] = [(x - X_mean)/X_std for x in X[key]]
        Y[key] = [(y - Y_mean)/Y_std for y in Y[key]]

    return X['train'], Y['train'], X['valid'], Y['valid']

def sample_sequences(X, Y, sample_size):
    ''' Given lists of sequences, crop out sequences of length sample_size
    from each sequence with a random offset

    :parameters:
        - X, Y : list of np.ndarray
            List of X/Y sequence matrices, each with shape (n_channels,
            n_time_steps, n_features)
        - sample_size : int
            The size of the cropped samples from the sequences

    :returns:
        - X_sampled, Y_sampled : np.ndarray
            X/Y sampled sequences, shape (n_samples, n_channels, n_time_steps,
            n_features)
    '''
    X_sampled = []
    Y_sampled = []
    for sequence_X, sequence_Y in zip(X, Y):
        # Ignore sequences which are too short
        if sequence_X.shape[1] < sample_size:
            continue
        # Compute a random offset to start cropping from
        offset = np.random.randint(0, sequence_X.shape[1] % sample_size + 1)
        # Extract samples of this sequence at offset, offset + sample_size,
        # offset + 2*sample_size ... until the end of the sequence
        X_sampled += [sequence_X[:, o:o + sample_size] for o in
                      np.arange(offset, sequence_X.shape[1] - sample_size + 1,
                                sample_size)]
        Y_sampled += [sequence_Y[:, o:o + sample_size] for o in
                      np.arange(offset, sequence_Y.shape[1] - sample_size + 1,
                                sample_size)]
    # Combine into new output array
    return np.array(X_sampled), np.array(Y_sampled)

def random_derangement(n):
    '''
    Permute the numbers up to n such that no number remains in the same place

    :parameters:
        - n : int
            Upper bound of numbers to permute from

    :returns:
        - v : np.ndarray, dtype=int
            Derangement indices

    :note:
        From
        http://stackoverflow.com/questions/26554211/numpy-shuffle-with-constraint
    '''
    while True:
        v = np.arange(n)
        for j in np.arange(n - 1, -1, -1):
            p = np.random.randint(0, j+1)
            if v[p] == j:
                break
            else:
                v[j], v[p] = v[p], v[j]
        else:
            if v[0] != 0:
                return v

def get_next_batch(X, Y, batch_size, sample_size, n_iter):
    ''' Randomly generates positive and negative example minibatches

    :parameters:
        - X, Y : list of np.ndarray
            List of data matrices in each modality
        - batch_size : int
            Size of each minibatch to grab
        - sample_size : int
            Size of each sampled sequence
        - n_iter : int
            Total number of iterations to run

    :returns:
        - X_p : np.ndarray
            Positive example minibatch in X modality
        - Y_p : np.ndarray
            Positive example minibatch in Y modality
        - X_n : np.ndarray
            Negative example minibatch in X modality
        - Y_n : np.ndarray
            Negative example minibatch in Y modality
    '''
    # These are dummy values which will force the sequences to be sampled
    current_batch = 1
    # We'll only know the number of batches after we sample sequences
    n_batches = 0
    for n in xrange(n_iter):
        if current_batch >= n_batches:
            X_sampled, Y_sampled = sample_sequences(X, Y, sample_size)
            N = X_sampled.shape[0]
            n_batches = int(np.floor(N/float(batch_size)))
            # Shuffle X_p and Y_p the same
            positive_shuffle = np.random.permutation(N)
            X_p = np.array(X_sampled[positive_shuffle])
            Y_p = np.array(Y_sampled[positive_shuffle])
            # Shuffle X_n and Y_n differently (derangement ensures nothing
            # stays in the same place)
            negative_shuffle = np.random.permutation(N)
            X_n = np.array(X_sampled[negative_shuffle])
            Y_n = np.array(Y_sampled[negative_shuffle][random_derangement(N)])
            current_batch = 0
        batch = slice(current_batch*batch_size, (current_batch + 1)*batch_size)
        yield X_p[batch], Y_p[batch], X_n[batch], Y_n[batch]
        current_batch += 1

def hash_entropy(X):
    ''' Get the entropy of the histogram of hashes.
    We want this to be close to n_bits.

    :parameters:
        - X : np.ndarray, shape=(n_examples, n_bits)
            Boolean data matrix, each column is the hash of an example

    :returns:
        - hash_entropy : float
            Entropy of the hash distribution
    '''
    # Convert bit vectors to ints
    bit_values = np.sum(2**np.arange(X.shape[1])*X, axis=1)
    # Count the number of occurences of each int
    counts = np.bincount(bit_values)
    # Normalize to form a probability distribution
    counts = counts/float(counts.sum())
    # Compute entropy
    return -np.sum(counts*np.log2(counts + 1e-100))

def statistics(X, Y):
    ''' Computes the number of correctly encoded codeworks and the number of
    bit errors made.  Assumes that rows of X should be hashed the same as rows
    of Y

    :parameters:
        - X : np.ndarray, shape=(n_examples, n_features)
            Data matrix of X modality
        - Y : np.ndarray, shape=(n_examples, n_features)
            Codeword matrix of Y modality

    :returns:
        - distance_distribution : int
            Emprical distribution of the codeword distances
        - mean_distance : float
            Mean of distances between corresponding codewords
        - std_distance : float
            Std of distances between corresponding codewords
    '''
    points_equal = (X == Y)
    distances = np.logical_not(points_equal).sum(axis=1)
    counts = np.bincount(distances, minlength=X.shape[1] + 1)
    return counts/float(X.shape[0]), np.mean(distances), np.std(distances)

def mean_reciprocal_rank(X, Y, indices):
    ''' Computes the mean reciprocal rank of the correct match
    Assumes that X[n] should be closest to Y[n]
    Uses hamming distance

    :parameters:
        - X : np.ndarray, shape=(n_examples, n_features)
            Data matrix in X modality
        - Y : np.ndarray, shape=(n_examples, n_features)
            Data matrix in Y modality
        - indices : np.ndarray
            Denotes which rows to use in MRR calculation

    :returns:
        - mrr_pessimist : float
            Mean reciprocal rank, where ties are resolved pessimistically
            That is, rank = # of distances <= dist(X[:, n], Y[:, n])
        - mrr_optimist : float
            Mean reciprocal rank, where ties are resolved optimistically
            That is, rank = # of distances < dist(X[:, n], Y[:, n]) + 1
    '''
    # Compute distances between each codeword and each other codeword
    distance_matrix = scipy.spatial.distance.cdist(X, Y, metric='hamming')
    # Rank is the number of distances smaller than the correct distance, as
    # specified by the indices arg
    n_le = distance_matrix.T <= distance_matrix[np.arange(X.shape[0]), indices]
    n_lt = distance_matrix.T < distance_matrix[np.arange(X.shape[0]), indices]
    return (np.mean(1./n_le.sum(axis=0)),
            np.mean(1./(n_lt.sum(axis=0) + 1)))

def build_network(input_shape, num_filters, filter_size, ds,
                  hidden_layer_sizes, dropout, n_bits):
    '''
    Construct a list of layers of a network given the network's structure.

    :parameters:
        - input_shape : tuple
            In what shape will data be supplied to the network?
        - num_filters : list
            Number of features in each convolutional layer
        - filter_size : list
            Number of features in each convolutional layer
        - ds : dict of list
            Number of features in each convolutional layer
        - hidden_layer_sizes : list
            Size of each hidden layer
        - dropout : bool
            Should dropout be applied between fully-connected layers?
        - n_bits : int
            Output dimensionality

    :returns:
        - layers : list
            List of layer instances for this network.
    '''
    layers = [lasagne.layers.InputLayer(shape=input_shape)]
    # Add each convolutional and pooling layer recursively
    for n in xrange(len(num_filters)):
        # In order to get the same shape out from each convolutional layer, we
        # need to pad the input because Conv2DLayer uses 'valid' convolution by
        # default and we can't rely on Conv2DLayer's mode='same' because it
        # doesn't allow even filter sizes.
        layers.append(lasagne.layers.PadLayer(
            layers[-1], width=((int(np.ceil((filter_size[n][0] - 1) / 2.)),
                                int(np.floor((filter_size[n][0] - 1) / 2.))),
                               (int(np.ceil((filter_size[n][1] - 1) / 2.)),
                                int(np.floor((filter_size[n][1] - 1) / 2.))))))
        # We will initialize weights to \sqrt{2/n_l}
        n_l = num_filters[n]*np.prod(filter_size[n])
        layers.append(lasagne.layers.Conv2DLayer(
            layers[-1], stride=(1, 1), num_filters=num_filters[n],
            filter_size=filter_size[n],
            nonlinearity=lasagne.nonlinearities.rectify,
            W=lasagne.init.Normal(np.sqrt(2./n_l))))
        layers.append(lasagne.layers.MaxPool2DLayer(
            layers[-1], ds[n], ignore_border=False))
    # A dense layer will treat any dimensions after the first as feature
    # dimensions, but the third dimension is really a timestep dimension.
    # We can only squash adjacent dimensions with a ReshapeLayer, so we
    # need to place the time stpe dimension after the batch dimension
    layers.append(lasagne.layers.DimshuffleLayer(
        layers[-1], (0, 2, 1, 3)))
    conv_output_shape = layers[-1].output_shape
    # Reshape to (n_batch*n_time_steps, n_conv_output_features)
    layers.append(lasagne.layers.ReshapeLayer(
        layers[-1], (-1, conv_output_shape[2]*conv_output_shape[3])))
    # Add dense hidden layers and optionally dropout
    for hidden_layer_size in hidden_layer_sizes:
        layers.append(lasagne.layers.DenseLayer(
            layers[-1], num_units=hidden_layer_size,
            nonlinearity=lasagne.nonlinearities.rectify))
        if dropout:
            layers.append(lasagne.layers.DropoutLayer(layers[-1], .5))
    # Add output layer
    layers.append(lasagne.layers.DenseLayer(
        layers[-1], num_units=n_bits,
        nonlinearity=lasagne.nonlinearities.tanh))

    return layers

def save_model(param_list, output_file):
    '''
    Write out a pickle file of a hashing network

    :parameters:
        - param_list : list of np.ndarray
            A list of values, per layer, of the parameters of the network
        - output_file : str
            Path to write the file to
    '''
    with open(output_file, 'wb') as f:
        pickle.dump(param_list, f)

def load_model(layers, param_file):
    '''
    Load in the parameters from a pkl file into a model

    :parameters:
        - layers : list
            A list of layers which define the model
        - param_file : str
            Pickle file of model parameters to load
    '''
    with open(param_file) as f:
        params = pickle.load(f)
    lasagne.layers.set_all_param_values(layers[-1], params)


"""Test Home Assistant json utility functions."""
from json import JSONEncoder
import os
import unittest
from unittest.mock import Mock
import sys
from tempfile import mkdtemp

import pytest

from homeassistant.util.json import (
    SerializationError, load_json, save_json)
from homeassistant.exceptions import HomeAssistantError

# Test data that can be saved as JSON
TEST_JSON_A = {"a": 1, "B": "two"}
TEST_JSON_B = {"a": "one", "B": 2}
# Test data that can not be saved as JSON (keys must be strings)
TEST_BAD_OBJECT = {("A",): 1}
# Test data that can not be loaded as JSON
TEST_BAD_SERIALIED = "THIS IS NOT JSON\n"
TMP_DIR = None

def setup():
    """Set up for tests."""
    global TMP_DIR
    TMP_DIR = mkdtemp()

def teardown():
    """Clean up after tests."""
    for fname in os.listdir(TMP_DIR):
        os.remove(os.path.join(TMP_DIR, fname))
    os.rmdir(TMP_DIR)

def _path_for(leaf_name):
    return os.path.join(TMP_DIR, leaf_name+".json")

def test_save_and_load():
    """Test saving and loading back."""
    fname = _path_for("test1")
    save_json(fname, TEST_JSON_A)
    data = load_json(fname)
    assert data == TEST_JSON_A

# Skipped on Windows
@unittest.skipIf(sys.platform.startswith('win'),
                 "private permissions not supported on Windows")
def test_save_and_load_private():
    """Test we can load private files and that they are protected."""
    fname = _path_for("test2")
    save_json(fname, TEST_JSON_A, private=True)
    data = load_json(fname)
    assert data == TEST_JSON_A
    stats = os.stat(fname)
    assert stats.st_mode & 0o77 == 0

def test_overwrite_and_reload():
    """Test that we can overwrite an existing file and read back."""
    fname = _path_for("test3")
    save_json(fname, TEST_JSON_A)
    save_json(fname, TEST_JSON_B)
    data = load_json(fname)
    assert data == TEST_JSON_B

def test_save_bad_data():
    """Test error from trying to save unserialisable data."""
    fname = _path_for("test4")
    with pytest.raises(SerializationError):
        save_json(fname, TEST_BAD_OBJECT)

def test_load_bad_data():
    """Test error from trying to load unserialisable data."""
    fname = _path_for("test5")
    with open(fname, "w") as fh:
        fh.write(TEST_BAD_SERIALIED)
    with pytest.raises(HomeAssistantError):
        load_json(fname)

def test_custom_encoder():
    """Test serializing with a custom encoder."""
    class MockJSONEncoder(JSONEncoder):
        """Mock JSON encoder."""

        def default(self, o):
            """Mock JSON encode method."""
            return "9"

    fname = _path_for("test6")
    save_json(fname, Mock(), encoder=MockJSONEncoder)
    data = load_json(fname)
    assert data == "9"


#!/usr/bin/python2.7
# coding=utf-8
"""
Created on 2015-4-28

@author: Jay
"""

"""
SYSTEM ERROR CODE
"""

ERROR_SUCCESS = 0                           # 操作成功
ERROR_UNKNOWN_ERROR = 1                     # 未知错误
ERROR_PARAMS_ERROR = 2                      # 参数格式错误
ERROR_DB_ERROR = 3                          # 数据库操作错误
ERROR_ACCESS_TOKEN_ERROR = 4                # AccessToken错误
ERROR_VERIFY_CODE_ERROR = 5                 # 验证码错误
ERROR_SIGN_ERROR = 6                        # 参数签名出错

ERROR_SERVICE_START_ERROR = 7               # 服务器启动错误
ERROR_SERVICE_STOP_ERROR = 8                # 服务器关闭错误

"""
LOGIC ERROR CODE
"""

ERROR_LOGIC = 440                           # 逻辑概要错误
ERROR_UID_NOT_EXIST = 441                   # uid不存在
EEROR_ACCEPT_BALANCE = 442					# 接受帮助资金平衡，请改天再来申请
EEROR_MATCH_COIN_LACK = 443                 # 排单币不足
ERROR_MAX_APPLY_HELP_LESS = 444             # 每次投资额不得低于上次投资额
ERROR_PHONE_EXISTED = 445                   # 手机号码已经存在
ERROR_PHONE_INVALID = 446                   # 手机号码无效
ERROR_ACCOUNT_SEALED = 447                  # 账号已经被封号，请联系管理员
ERROR_ACCOUNT_UNACTIVED = 448               # 账号未激活，请联系管理员


class Node(object):
    def __init__(self,data):
        self.data=data
        self.next=None

def create_single_link(node_number):
    '''
    创建单向链表
    :param node_number:节点数
    :return: head 第一个节点
    '''
    print('创建链表,节点个数{node_number}'.format(node_number=node_number))
    head=Node(1)
    cur=head
    for i in range(2,node_number+1):
        tmp=Node(i)
        cur.next=tmp
        cur=cur.next
    return head

def print_single_link(head):
    '''
    打印链表
    :param head:
    :return:
    '''
    data_list=[]
    cur=head
    while(cur is not None):
        data_list.append(cur.data)
        cur = cur.next
    data_list=[str(i) for i in data_list]
    print('-->'.join(data_list))
    return None

def reverse_link(head):
    '''
    反转链表
    :param head:
    :return:
    '''
    pre=None
    cur=head
    while(cur is not None):
        next_node=cur.next
        cur.next=pre

        pre=cur
        cur=next_node

    return pre

if __name__ == '__main__':
    node_number=10
    head=create_single_link(node_number)
    print_single_link(head)

    print('反转链表')
    head=reverse_link(head)
    print_single_link(head)


def print_report(filename):
    """
    print the characters report of the file.
    filename (str) - the name of the file
    """

    # read the file
    f = open(filename, "r")
    content = f.read()
    f.close()

    # statistics the characters
    vowels = 0
    consonants = 0
    whitespace = 0
    punctuation = 0
    for c in content:
        if c.isalpha():
            if c.lower() in ["a", "e", "i", "o", "u"]:
                vowels += 1
            else:
                consonants += 1
        elif c.isspace():
            whitespace += 1
        elif not c.isdigit():
            punctuation += 1
    characters = len(content)
    per_vowels = round(vowels*100.0/characters, 1)
    per_consonants = round(consonants*100.0/characters, 1)
    per_whitespace = round(whitespace*100.0/characters, 1)
    per_punctuation = round(punctuation*100.0/characters, 1)

    # output the result
    print("---------", filename, "--------")
    print("Vowels:\t\t\t", vowels)
    print("Consonants:\t\t", consonants)
    print("Whitespace:\t\t", whitespace)
    print("Punctuation:\t\t", punctuation)
    print("-------------------------------")
    print("Total:\t\t\t", characters)
    print()
    print("Percent vowels:\t\t", per_vowels)
    print("Percent consonants:\t", per_consonants)
    print("Percent whitespace:\t", per_whitespace)
    print("Percent punctuation:\t", per_punctuation)
    print("===============================")

def replace_parts_of_speech(content, label):
    """
    Ask user for some words and repalce by label of content.
    content (str) - containing part of speech labels
    label (str) - part of speech label to replace
    """

    sentences = content.split(label)
    output = ""
    for i in range(len(sentences)):
        # if not last sentence then add word
        if i < len(sentences) - 1:
            word = input("Enter " + label.lower() + ":")
        else:
            word = ""
        output += sentences[i] + word
    return output

def complete_mad_lib(filename):
    """
    Output a completed story.
    filename (str) - name of a Mad Lib template file to read
    """

    # open the file
    f = open(filename, "r")
    lines = f.readlines()
    f.close()

    # replace words line by line
    story = ""
    for line in lines:
        line = replace_parts_of_speech(line, "PLURAL NOUN")
        line = replace_parts_of_speech(line, "VERB PAST")
        line = replace_parts_of_speech(line, "NOUN")
        line = replace_parts_of_speech(line, "VERB")
        line = replace_parts_of_speech(line, "ADJECTIVE")
        story += line

    # output the story
    f = open("MAD_" + filename, "w")
    f.write(story)
    f.close()

def main():
    """
    Open a file and print the report of it, then complete the story.
    """

    filename = input("Enter the name of a Mad-Lib template file:")
    print_report(filename)
    complete_mad_lib(filename)
    print("Finish!")

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-

from __future__ import print_function

import logging

from pybel.constants import *
from pybel.manager.citation_utils import get_citations_by_pmids
from pybel.parser.parse_control import set_citation_stub, set_tag

__all__ = (
    'PubMedAnnotator',
    'rewrite_path_with_citations',
)

log = logging.getLogger(__name__)

class PubMedAnnotator:
    """Wraps functionality for rewriting BEL scripts"""

    def __init__(self, manager=None, group_size=200):
        self.cache = {}
        self.parser = set_tag + set_citation_stub
        self.group_size = group_size
        self.manager = manager

    def get_citations(self, pubmed_identifiers):
        """

        :param iter[str] pubmed_identifiers:
        """

        result = {}

        to_query = []

        for pmid in pubmed_identifiers:
            if pmid in self.cache:
                result[pmid] = self.cache[pmid]
            else:
                to_query.append(pmid)

        tr, _ = get_citations_by_pmids(pmids=to_query, manager=self.manager, group_size=self.group_size)

        logging.warning('len tr: %s', len(tr))

        self.cache.update(**tr)

        result.update(**tr)

        return result

    def rewrite(self, lines):
        """Rewrites a BEL document

        Uses a clever stack so only the last 200 PubMed identifiers are ever in the memory and all the lines in between

        :param iter[str] lines: An iterable over the lines of a BEL file
        :return: An iterable of the new lines of a BEL file
        :rtype: iter[str]
        """
        pmids = set()
        stack = []

        for line in lines:
            try:
                r = self.parser.parseString(line)

                if r[0] != CITATION_TYPE_PUBMED:
                    stack.append(line)

                else:
                    pmid = int(r[1 if len(r) == 2 else 2])
                    log.warning('pmid: %s', pmid)
                    pmids.add(pmid)
                    stack.append(pmid)

                    if len(pmids) == self.group_size:
                        for item in self.help_iterate(stack, pmids):
                            yield item
            except:
                stack.append(line)

        for item in self.help_iterate(stack, pmids):
            yield item

    def help_iterate(self, stack, pmids):
        results = self.get_citations(pmids)

        for line in stack:
            if isinstance(line, int):
                pmid = str(line)

                result = results[pmid]

                yield 'SET Citation = {{"{}", "{}", "{}", "{}", "{}"}}'.format(
                    CITATION_TYPE_PUBMED,
                    result['title'],
                    pmid,
                    result[CITATION_DATE],
                    '|'.join(result[CITATION_AUTHORS]),
                )
            else:
                yield line

        pmids.clear()
        stack.clear()

def rewrite_path_with_citations(path, annotator=None, file=None):
    """Rewrites the BEL file at the given path with better citations

    :param str path:
    :param PubMedAnnotator annotator:
    :param file file:
    :return:
    """
    annotator = PubMedAnnotator() if annotator is None else annotator

    with open(path) as f:
        for line in annotator.rewrite(f):
            print(line.strip(), file=file)


import math
import sys

def euclidean_distance(list1, list2):
    '''(list of numbers, list of numbers) -> number

    Return the distance between two points in space

    Precondition: list1 and list2 length are equal

    >> give example

    '''
    sum = 0
    for index in range(len(list1)):
        sum = sum + math.pow((list1[index] - list2[index]), 2)

    return math.sqrt(sum)

def min_distance_between_center(centers, s_attr):
    '''(dictionary of centers, list of numbers) -> number

    Return the minimum distance between centers and object

    Precondition: list1 and list2 length are equal

    >> give example

    '''
    min = sys.maxsize

    for key in centers:
        tmp = euclidean_distance(centers[key], s_attr)
        if min > tmp:
            min = tmp

    return min

def max_distance(centers):
    '''(dictionary of centers) -> number

    Return the maximum distance between centers

    >> give example

    '''
    max = 0

    for key1 in centers:
        for key2 in centers:
            tmp = euclidean_distance(centers[key1], centers[key2])
            if max < tmp:
                max = tmp

    return max

def is_center_exists(centers, objects, p):
    '''(dictionary of centers, dictionary of objects, number in range [1/2, 1] ) -> bool

    Return true if new center found

    >> give example

    '''
    max = 0
    nextCenterKey = ''
    for key in objects:
        tmp = min_distance_between_center(centers, objects[key])
        print(key + ":" + str(tmp))
        if max < tmp:
            max = tmp
            nextCenterKey = key

    if nextCenterKey != '' and max >= p*max_distance(centers):
        centers[nextCenterKey] = objects[nextCenterKey]
        return True

    return False

def read_from_file(path):
    '''(str path of file) -> dictionary of objects

    >> give example

    '''
    objects = {}
    f = open(path, 'r')
    for line in f:
        objects = eval(line)
    return objects


# -*- coding: utf-8 -*-
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import annotations

from typing import MutableMapping, MutableSequence

import proto  # type: ignore

from google.cloud.discoveryengine_v1beta.types import user_event as gcd_user_event

__protobuf__ = proto.module(
    package="google.cloud.discoveryengine.v1beta",
    manifest={
        "WriteUserEventRequest",
        "CollectUserEventRequest",
    },
)

class WriteUserEventRequest(proto.Message):
    r"""Request message for WriteUserEvent method.

    .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields

    Attributes:
        parent (str):
            Required. The parent DataStore resource name, such as
            ``projects/{project}/locations/{location}/collections/{collection}/dataStores/{data_store}``.
        user_event (google.cloud.discoveryengine_v1beta.types.UserEvent):
            Required. User event to write.

            This field is a member of `oneof`_ ``_user_event``.
    """

    parent: str = proto.Field(
        proto.STRING,
        number=1,
    )
    user_event: gcd_user_event.UserEvent = proto.Field(
        proto.MESSAGE,
        number=2,
        optional=True,
        message=gcd_user_event.UserEvent,
    )

class CollectUserEventRequest(proto.Message):
    r"""Request message for CollectUserEvent method.

    .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields

    Attributes:
        parent (str):
            Required. The parent DataStore resource name, such as
            ``projects/{project}/locations/{location}/collections/{collection}/dataStores/{data_store}``.
        user_event (str):
            Required. URL encoded UserEvent proto with a
            length limit of 2,000,000 characters.
        uri (str):
            The URL including cgi-parameters but
            excluding the hash fragment with a length limit
            of 5,000 characters. This is often more useful
            than the referer URL, because many browsers only
            send the domain for third-party requests.

            This field is a member of `oneof`_ ``_uri``.
        ets (int):
            The event timestamp in milliseconds. This
            prevents browser caching of otherwise identical
            get requests. The name is abbreviated to reduce
            the payload bytes.

            This field is a member of `oneof`_ ``_ets``.
    """

    parent: str = proto.Field(
        proto.STRING,
        number=1,
    )
    user_event: str = proto.Field(
        proto.STRING,
        number=2,
    )
    uri: str = proto.Field(
        proto.STRING,
        number=3,
        optional=True,
    )
    ets: int = proto.Field(
        proto.INT64,
        number=4,
        optional=True,
    )

__all__ = tuple(sorted(__protobuf__.manifest))


from time import sleep
from random import randint
z,result=1,0
while z<300:
    n=6
    t=0
    L0,L1,L2,L3=[],n*[0],n*[0],n*[0]
    while L1.count(0)>0:
        t+=1
        r=randint(0,n-1)
        L0.append(r)
        if L1[r]==0: L1[r]=t
        L2[r]=t
        L3[r]+=1
    y="{} objets obtenus en {} tirages\n|objets|premier|dernier|nombre|".format(n,t)
    print(y)
    # result+=int(n)
    # result+=" objets obtenus en "
    # result+=int(t)
    # result+=" tirages\n|objets|premier|dernier|nombre|"
    for i in range(n):
        print("|{:6}|{:7}|{:7}|{:6}|".format(i+1,L1[i],L2[i],L3[i]))
        # result+="|{:6}|{:7}|{:7}|{:6}|".format(i+1,L1[i],L2[i],L3[i])
    print("Liste des tirages:",[i+1 for i in L0])
    # result+="Liste des tirages:",[i+1 for i in L0]
    sleep(0.05)
    z+=1
    print("nombre de tours {}".format(z))
    # result+="nombre de tours {}".format(z)
# f=open("cache_de_exemple_10_objets_en_tirage.py.txt", "a")
# s=f.write(result)
# f.close()