<commit_before>import sys
sys.path.append("./spikerlib.egg")
from spikerlib.metrics import kreuz as kr
import numpy as np
import multiprocessing as mp

def call_interval_kr(record):
    id = record["id"]
    inspikes = record["inspikes"]
    outspikes = record["outspikes"]
    dist_kr = np.mean(kr.interval(inspikes, outspikes, mp=False))
    return {"id": id, "kr": dist_kr}

spikes = np.load("2014-01-31_spikes.npz")["data"]
_num_items = len(spikes)
pool = mp.Pool()
dist_kr = pool.imap(call_interval_kr, spikes)
print("Starting calculation of kreuz ...")
dist_kr = []
for idx, kr_item in enumerate(kreuz_iter, 1):
    dist_kr.append(kr_item)
    print("%i/%i complete ..." % (idx, _num_items))
print("Calculation complete. Saving to kreuz.npz")
np.savez("kreuz.npz", data=dist_kr)
print("DONE!")

<commit_msg>Stupid variable name bug<commit_after>import sys
sys.path.append("./spikerlib.egg")
from spikerlib.metrics import kreuz as kr
import numpy as np
import multiprocessing as mp

def call_interval_kr(record):
    id = record["id"]
    inspikes = record["inspikes"]
    outspikes = record["outspikes"]
    dist_kr = np.mean(kr.interval(inspikes, outspikes, mp=False))
    return {"id": id, "kr": dist_kr}

spikes = np.load("2014-01-31_spikes.npz")["data"]
_num_items = len(spikes)
pool = mp.Pool()
kreuz_iter = pool.imap(call_interval_kr, spikes)
print("Starting calculation of kreuz ...")
dist_kr = []
for idx, kr_item in enumerate(kreuz_iter, 1):
    dist_kr.append(kr_item)
    print("%i/%i complete ..." % (idx, _num_items))
print("Calculation complete. Saving to kreuz.npz")
np.savez("kreuz.npz", data=dist_kr)
print("DONE!")

<|endoftext|>


<commit_before># coding=utf-8
"""
Application entry for PicDB.
"""
# Copyright (c) 2016 Stefan Braun
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and
# associated documentation files (the "Software"), to deal in the Software
# without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit persons to
# whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
#  all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#  IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE
# AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
#  LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import argparse
import logging
import tkinter as tk
from tkinter import ttk

from .log import initialize_logger
from .uistatus import StatusPanel
from .uipictures import PictureManagement
from .uigroups import GroupManagement
from .uitags import TagManagement
from .persistence import create_db, DBParameters
from .config import get_configuration

version = '1.0.2.1'

class Application(ttk.Frame):
    """PicDB Frontend"""

    def __init__(self, master):
        super().__init__(master, padding="3 5 3 5", width=400, height=300)
        self.logger = logging.getLogger('picdb.ui')
        self.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
        self.create_widgets()

    def create_widgets(self):
        """Build UI."""
        notebook = ttk.Notebook(self)
        notebook.grid(row=0, column=0, sticky=(tk.N, tk.W, tk.E, tk.S))
        import_frame = PictureManagement(notebook)
        series_frame = GroupManagement(notebook)
        tags_frame = TagManagement(notebook)
        notebook.add(import_frame, text='manage pictures')
        notebook.add(series_frame, text='manage series')
        notebook.add(tags_frame, text='manage tags')

        status_panel = StatusPanel(self, version=version)
        status_panel.grid(row=1, column=0, sticky=(tk.N, tk.W, tk.E, tk.S))

        ttk.Button(self, text='Quit',
                   command=self.quit).grid(row=2, column=0,
                                           sticky=(tk.N, tk.S))
        self.rowconfigure(0, weight=1, minsize=400)
        self.rowconfigure(1, weight=0)
        self.rowconfigure(2, weight=0)
        self.columnconfigure(0, weight=1, minsize=600)

def _parse_arguments(args):
    """Parse command line arguments.

    :param args: given arguments, e.g. sys.argc[1:]
    :type args: [str]
    :return: configuration namespace
    :rtype: {<key>:<value>}
    """
    parser = argparse.ArgumentParser(
        description='Assign tags to pictures and pictures to groups.')
    parser.add_argument('--db', action='store', dest='db',
                        default=get_configuration('db_name'),
                        help='Name to database to use. Overrides '
                             'configuration file.')
    parser.add_argument('--user', action='store', dest='user',
                        default=get_configuration('db_user'),
                        help='Database user. Overrides '
                             'configuration file.')
    parser.add_argument('--passwd', action='store', dest='passwd',
                        default=get_configuration('db_passwd'),
                        help='Password of database user. Overrides '
                             'configuration file.')
    parser.add_argument('--port', action='store', dest='port',
                        default=get_configuration('db_port'),
                        help='Port of database to use. Overrides '
                             'configuration file.')
    parser.add_argument('--title', action='store', dest='title',
                        default='PicDB',
                        help='Window title.')
    parser.add_argument('--geometry', action='store', dest='geometry',
                        default=get_configuration('geometry'),
                        help='Window geometry, e.g. "2200x1000+100+100".')
    arguments = parser.parse_args(args)
    return arguments

def create_db_by_arguments(args):
    create_db(DBParameters(args.db, args.user, args.passwd, args.port))

def start_application(argv):
    initialize_logger()
    root = tk.Tk()
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)
    # no tear-off menus
    root.option_add('*tearoff', False)
    args = _parse_arguments(argv)
    create_db_by_arguments(args)
    root.geometry(args.geometry)
    app = Application(root)
    app.master.title(args.title)
    app.mainloop()
<commit_msg>reset version to 1.0.1.1<commit_after># coding=utf-8
"""
Application entry for PicDB.
"""
# Copyright (c) 2016 Stefan Braun
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and
# associated documentation files (the "Software"), to deal in the Software
# without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit persons to
# whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
#  all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#  IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE
# AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
#  LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import argparse
import logging
import tkinter as tk
from tkinter import ttk

from .log import initialize_logger
from .uistatus import StatusPanel
from .uipictures import PictureManagement
from .uigroups import GroupManagement
from .uitags import TagManagement
from .persistence import create_db, DBParameters
from .config import get_configuration

version = '1.0.1.1'

class Application(ttk.Frame):
    """PicDB Frontend"""

    def __init__(self, master):
        super().__init__(master, padding="3 5 3 5", width=400, height=300)
        self.logger = logging.getLogger('picdb.ui')
        self.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
        self.create_widgets()

    def create_widgets(self):
        """Build UI."""
        notebook = ttk.Notebook(self)
        notebook.grid(row=0, column=0, sticky=(tk.N, tk.W, tk.E, tk.S))
        import_frame = PictureManagement(notebook)
        series_frame = GroupManagement(notebook)
        tags_frame = TagManagement(notebook)
        notebook.add(import_frame, text='manage pictures')
        notebook.add(series_frame, text='manage series')
        notebook.add(tags_frame, text='manage tags')

        status_panel = StatusPanel(self, version=version)
        status_panel.grid(row=1, column=0, sticky=(tk.N, tk.W, tk.E, tk.S))

        ttk.Button(self, text='Quit',
                   command=self.quit).grid(row=2, column=0,
                                           sticky=(tk.N, tk.S))
        self.rowconfigure(0, weight=1, minsize=400)
        self.rowconfigure(1, weight=0)
        self.rowconfigure(2, weight=0)
        self.columnconfigure(0, weight=1, minsize=600)

def _parse_arguments(args):
    """Parse command line arguments.

    :param args: given arguments, e.g. sys.argc[1:]
    :type args: [str]
    :return: configuration namespace
    :rtype: {<key>:<value>}
    """
    parser = argparse.ArgumentParser(
        description='Assign tags to pictures and pictures to groups.')
    parser.add_argument('--db', action='store', dest='db',
                        default=get_configuration('db_name'),
                        help='Name to database to use. Overrides '
                             'configuration file.')
    parser.add_argument('--user', action='store', dest='user',
                        default=get_configuration('db_user'),
                        help='Database user. Overrides '
                             'configuration file.')
    parser.add_argument('--passwd', action='store', dest='passwd',
                        default=get_configuration('db_passwd'),
                        help='Password of database user. Overrides '
                             'configuration file.')
    parser.add_argument('--port', action='store', dest='port',
                        default=get_configuration('db_port'),
                        help='Port of database to use. Overrides '
                             'configuration file.')
    parser.add_argument('--title', action='store', dest='title',
                        default='PicDB',
                        help='Window title.')
    parser.add_argument('--geometry', action='store', dest='geometry',
                        default=get_configuration('geometry'),
                        help='Window geometry, e.g. "2200x1000+100+100".')
    arguments = parser.parse_args(args)
    return arguments

def create_db_by_arguments(args):
    create_db(DBParameters(args.db, args.user, args.passwd, args.port))

def start_application(argv):
    initialize_logger()
    root = tk.Tk()
    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)
    # no tear-off menus
    root.option_add('*tearoff', False)
    args = _parse_arguments(argv)
    create_db_by_arguments(args)
    root.geometry(args.geometry)
    app = Application(root)
    app.master.title(args.title)
    app.mainloop()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Test the ability to configure the $PCHCOM construction variable.
"""

import TestSCons
import sys

if sys.platform != 'win32':
    msg = "Skipping Visual C/C++ test on non-Windows platform '%s'\n" % sys.platform
    test.skip_test(msg)

_python_ = TestSCons._python_

test = TestSCons.TestSCons()

test.write('SConstruct', """
env_64 = Environment(tools=['default', 'msvc'],
                  TARGET_ARCH = 'amd64')
env_32 = Environment(tools=['default', 'msvc'],
                  TARGET_ARCH = 'x86')
""" % locals())

test.run(arguments = ".")

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
<commit_msg>Fix test for non-win32 platforms<commit_after>#!/usr/bin/env python
#
# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Test the ability to configure the $PCHCOM construction variable.
"""

import TestSCons
import sys

_python_ = TestSCons._python_

test = TestSCons.TestSCons()

if sys.platform != 'win32':
    msg = "Skipping Visual C/C++ test on non-Windows platform '%s'\n" % sys.platform
    test.skip_test(msg)

test.write('SConstruct', """
env_64 = Environment(tools=['default', 'msvc'],
                  TARGET_ARCH = 'amd64')
env_32 = Environment(tools=['default', 'msvc'],
                  TARGET_ARCH = 'x86')
""" % locals())

test.run(arguments = ".")

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
<|endoftext|>


<commit_before># coding: utf-8

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import sys

# project
from streammorphology import ExperimentRunner
from streammorphology.freqvar import FreqVariance

runner = ExperimentRunner(ExperimentClass=FreqVariance)
runner.run(config_filename='FreqVariance-regular.cfg')

runner = ExperimentRunner(ExperimentClass=FreqVariance)
runner.run(config_filename='FreqVariance-mildly_chaotic.cfg')

runner = ExperimentRunner(ExperimentClass=FreqVariance)
runner.run(config_filename='FreqVariance-chaotic.cfg')

sys.exit(0)
<commit_msg>only call one config<commit_after># coding: utf-8

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import sys

# project
from streammorphology import ExperimentRunner
from streammorphology.freqvar import FreqVariance

runner = ExperimentRunner(ExperimentClass=FreqVariance)
runner.run()

sys.exit(0)
<|endoftext|>


<commit_before>#! /usr/bin/env python
"""Main script for automating computations using aospy."""
import itertools

import aospy
import aospy_user

def main(proj=None, model=None, run=None, ens_mem=None, var=None,
         yr_range=None, region=None, intvl_in=None, intvl_out=None,
         dtype_in_time=None, dtype_in_vert=None, dtype_out_time=None,
         dtype_out_vert=None, level=None, yr_chunk_len=False, verbose=True,
         compute=True, print_table=False):
    """Main script for interfacing with aospy."""

    # Instantiate objects and load default/all models, runs, and regions.
    proj = aospy_user.to_proj(proj)
    model = aospy_user.to_model(model, proj)
    var = aospy_user.to_var(var)
    region = aospy_user.to_region(region, proj=proj)
    proj, model, var, region = [aospy_user.to_iterable(obj)
                                for obj in (proj, model, var, region)]

    print '\nProject:', proj
    print 'Models:', model
    print 'Runs:', run
    print 'Ensemble members:', ens_mem
    print 'Variables:', var
    print 'Year ranges:', yr_range
    print 'Geographical regions:', region
    print 'Time interval of input data:', intvl_in
    print 'Time intervals for averaging:', intvl_out
    print 'Input data time type:', dtype_in_time
    print 'Input data vertical type:', dtype_in_vert
    print 'Output data time types:', dtype_out_time
    print 'Output data vert types:', dtype_out_vert
    print 'Vertical levels:', level
    print 'Year chunks:', yr_chunk_len
    print 'Compute this data:', compute
    print 'Print this data:', print_table

    if not raw_input("\nProceed using these parameters? ").lower() == 'y':
        raise IOError('\nExecution cancelled by user.')

    # Iterate through given parameter combos, saving resulting calculations.
    print '\n\tVariable time averages and statistics:'
    calcs = []
    data = []
    for mod in model:
        runs = aospy_user.to_run(run, mod, proj)
        mod = aospy_user.to_iterable(mod)

        for params in itertools.product(
                proj, mod, runs, ens_mem, var, yr_range, region,
                intvl_in, intvl_out, dtype_in_time, dtype_in_vert,
                [dtype_out_time], dtype_out_vert, level
        ):
            calc = aospy.Calc(*params, verbose=verbose,
                              yr_chunk_len=yr_chunk_len)
            if compute:
                try:
                    calc.compute()
                except:
                    raise
                calcs.append(calc)
            if print_table:
                try:
                    dat = calc.load(
                        dtype_out_time[0], dtype_out_vert=params[-2],
                        region=params[6][0], plot_units=True
                    )
                    print dat
                except:
                    raise
                data.append(dat)
    print "Calculations finished."
    return calcs

if __name__ == '__main__':
    proj = 'aero_3agcm'
    model = 'hiram_mz'
    run = 'default'
    ens_mem = [None]
    var = ['precip']
    yr_range = ['default']
    region = ['all']
    intvl_in = ['monthly']
    intvl_out = ['jas']
    dtype_in_time = ['ts']
    dtype_in_vert = [False]
    dtype_out_time = ('av', 'std', 'reg.av', 'reg.ts', 'reg.std')
    # dtype_out_time = ('',)
    dtype_out_vert = [False]
    level = [None]
    yr_chunk_len = False
    compute = True
    verbose = True
    print_table = False

    try:
        if compute:
            calc = main(
                proj=proj, model=model, run=run, ens_mem=ens_mem, var=var,
                yr_range=yr_range, region=region, intvl_in=intvl_in,
                intvl_out=intvl_out, dtype_in_time=dtype_in_time,
                dtype_in_vert=dtype_in_vert, dtype_out_time=dtype_out_time,
                dtype_out_vert=dtype_out_vert, level=level,
                yr_chunk_len=yr_chunk_len, verbose=verbose, compute=compute,
                print_table=print_table
            )
        if print_table:
            calc = main(
                proj=proj, model=model, run=run, ens_mem=ens_mem, var=var,
                yr_range=yr_range, region=print_table, intvl_in=intvl_in,
                intvl_out=intvl_out, dtype_in_time=dtype_in_time,
                dtype_in_vert=dtype_in_vert, dtype_out_time=('reg.ts',),
                dtype_out_vert=dtype_out_vert, level=level,
                yr_chunk_len=yr_chunk_len, verbose=verbose, compute=compute,
                print_table=True
            )
    except:
        raise
<commit_msg>Create MainParams and CalcParams interfaces for main.py<commit_after>#! /usr/bin/env python
"""Main script for automating computations using aospy."""
import itertools

import aospy
import aospy_user

class CalcParams(object):
    """Interface to Calc class."""
    pass

def main(main_params):
    """Main script for interfacing with aospy."""
    # Instantiate objects and load default/all models, runs, and regions.
    proj = aospy_user.to_proj(main_params.proj)
    model = aospy_user.to_model(main_params.model, proj)
    var = aospy_user.to_var(main_params.var)
    region = aospy_user.to_region(main_params.region, proj=proj)

    cp = CalcParams()
    cp.proj, cp.model, cp.var, cp.region = [
        aospy_user.to_iterable(obj) for obj in (proj, model, var, region)
    ]
    cp.run = main_params.run
    cp.ens_mem = main_params.ens_mem
    cp.yr_range = main_params.yr_range
    cp.intvl_in = main_params.intvl_in
    cp.intvl_out = main_params.intvl_out
    cp.dtype_in_time = main_params.dtype_in_time
    cp.dtype_in_vert = main_params.dtype_in_vert
    cp.dtype_out_time = main_params.dtype_out_time
    cp.dtype_out_vert = main_params.dtype_out_vert
    cp.level = main_params.level
    cp.yr_chunk_len = main_params.yr_chunk_len
    cp.compute = main_params.compute
    cp.verbose = main_params.verbose
    cp.print_table = main_params.print_table

    print '\nProject:', cp.proj
    print 'Models:', cp.model
    print 'Runs:', cp.run
    print 'Ensemble members:', cp.ens_mem
    print 'Variables:', cp.var
    print 'Year ranges:', cp.yr_range
    print 'Geographical regions:', region
    print 'Time interval of input data:', cp.intvl_in
    print 'Time intervals for averaging:', cp.intvl_out
    print 'Input data time type:', cp.dtype_in_time
    print 'Input data vertical type:', cp.dtype_in_vert
    print 'Output data time types:', cp.dtype_out_time
    print 'Output data vert types:', cp.dtype_out_vert
    print 'Vertical levels:', cp.level
    print 'Year chunks:', cp.yr_chunk_len
    print 'Compute this data:', cp.compute
    print 'Print this data:', cp.print_table

    if not raw_input("\nProceed using these parameters? ").lower() == 'y':
        raise IOError('\nExecution cancelled by user.')

    # Iterate through given parameter combos, saving resulting calculations.
    print '\n\tVariable time averages and statistics:'
    calcs = []
    data = []
    for mod in cp.model:
        runs = aospy_user.to_run(main_params.run, mod, cp.proj)
        mod = aospy_user.to_iterable(mod)

        for params in itertools.product(
                cp.proj, mod, runs, cp.ens_mem, cp.var, cp.yr_range, cp.region,
                cp.intvl_in, cp.intvl_out,  cp.dtype_in_time, cp.dtype_in_vert,
                [cp.dtype_out_time], cp.dtype_out_vert, cp.level
        ):
            calc = aospy.Calc(*params, verbose=cp.verbose,
                              yr_chunk_len=cp.yr_chunk_len)
            if cp.compute:
                calc.compute()
                calcs.append(calc)

            if cp.print_table:
                dat = calc.load(
                    cp.dtype_out_time[0], dtype_out_vert=params[-2],
                    region=params[6][0], plot_units=True
                )
                print dat
                data.append(dat)
    print "Calculations finished."
    return calcs, data

class MainParams(object):
    """Interface to main routine."""
    pass

if __name__ == '__main__':
    mp = MainParams()
    mp.proj = 'aero_3agcm'
    mp.model = 'default'
    mp.run = 'default'
    mp.ens_mem = [None]
    mp.var = ['precip']
    mp.yr_range = ['default']
    mp.region = ['all']
    mp.intvl_in = ['monthly']
    mp.intvl_out = ['jas']
    mp.dtype_in_time = ['ts']
    mp.dtype_in_vert = [False]
    mp.dtype_out_time = ('av', 'std', 'reg.av', 'reg.ts', 'reg.std')
    mp.dtype_out_vert = [False]
    mp.level = [None]
    mp.yr_chunk_len = False
    mp.compute = True
    mp.verbose = True
    mp.print_table = False

    calc, data = main(mp)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
#  Copyright 2019 The FATE Authors. All Rights Reserved.
#
#  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.
#

import math
import numpy as np

from federatedml.util import consts, LOGGER

"""
Structure of compressed object, for memory saving we use tuple (value, g, delta) in fate>=v1.8
"""

"""
class Stats(object):
    def __init__(self, value, g: int, delta: int):
        self.value = value
        self.g = g
        self.delta = delta
"""

class QuantileSummaries(object):
    def __init__(self, compress_thres=consts.DEFAULT_COMPRESS_THRESHOLD,
                 head_size=consts.DEFAULT_HEAD_SIZE,
                 error=consts.DEFAULT_RELATIVE_ERROR,
                 abnormal_list=None):
        self.compress_thres = compress_thres
        self.head_size = head_size
        self.error = error
        self.head_sampled = []
        self.sampled = []  # list of Stats
        self.count = 0  # Total observations appeared
        self.missing_count = 0
        if abnormal_list is None:
            self.abnormal_list = []
        else:
            self.abnormal_list = abnormal_list

    # insert a number
    def insert(self, x):
        """
        Insert an observation of data. First store in a array buffer. If the buffer is full,
        do a batch insert. If the size of sampled list reach compress_thres, compress this list.
        Parameters
        ----------
        x : float
            The observation that prepare to insert

        """
        if x in self.abnormal_list or (isinstance(x, float) and np.isnan(x)):
            self.missing_count += 1
            return

        x = float(x)

        self.head_sampled.append(x)
        if len(self.head_sampled) >= self.head_size:
            self._insert_head_buffer()
            if len(self.sampled) >= self.compress_thres:
                self.compress()

    def _insert_head_buffer(self):
        if not len(self.head_sampled):  # If empty
            return
        current_count = self.count
        sorted_head = sorted(self.head_sampled)
        head_len = len(sorted_head)
        sample_len = len(self.sampled)
        new_sampled = []
        sample_idx = 0
        ops_idx = 0
        while ops_idx < head_len:
            current_sample = sorted_head[ops_idx]
            while sample_idx < sample_len and self.sampled[sample_idx][0] <= current_sample:
                new_sampled.append(self.sampled[sample_idx])
                sample_idx += 1

            current_count += 1

            # If it is the first one to insert or if it is the last one
            if not new_sampled or (sample_idx == sample_len and
                                   ops_idx == head_len - 1):
                delta = 0
            else:
                # delta = math.floor(2 * self.error * current_count) - 1
                delta = math.floor(2 * self.error * current_count)

            new_sampled.append((current_sample, 1, delta))
            ops_idx += 1

        new_sampled += self.sampled[sample_idx:]
        self.sampled = new_sampled
        self.head_sampled = []
        self.count = current_count

    def compress(self):
        self._insert_head_buffer()
        # merge_threshold = math.floor(2 * self.error * self.count) - 1
        merge_threshold = 2 * self.error * self.count
        compressed = self._compress_immut(merge_threshold)
        self.sampled = compressed

    def merge(self, other):
        """
        merge current summeries with the other one.
        Parameters
        ----------
        other : QuantileSummaries
            The summaries to be merged
        """
        if other.head_sampled:
            # other._insert_head_buffer()
            other.compress()

        if self.head_sampled:
            # self._insert_head_buffer()
            self.compress()

        if other.count == 0:
            return self

        if self.count == 0:
            return other

        # merge two sorted array
        new_sample = []
        i, j = 0, 0
        self_sample_len = len(self.sampled)
        other_sample_len = len(other.sampled)
        while i < self_sample_len and j < other_sample_len:
            if self.sampled[i][0] < other.sampled[j][0]:
                new_sample.append(self.sampled[i])
                i += 1
            else:
                new_sample.append(other.sampled[j])
                j += 1
        new_sample += self.sampled[i:]
        new_sample += other.sampled[j:]

        res_summary = self.__class__(compress_thres=self.compress_thres,
                                     head_size=self.head_size,
                                     error=self.error,
                                     abnormal_list=self.abnormal_list)
        res_summary.count = self.count + other.count
        res_summary.missing_count = self.missing_count + other.missing_count
        res_summary.sampled = new_sample
        # self.sampled = new_sample
        # self.count += other.count
        # merge_threshold = math.floor(2 * self.error * self.count) - 1
        merge_threshold = 2 * self.error * res_summary.count

        res_summary.sampled = res_summary._compress_immut(merge_threshold)
        return res_summary

    def query(self, quantile):
        """
        Given the queried quantile, return the approximation guaranteed result
        Parameters
        ----------
        quantile : float [0.0, 1.0]
            The target quantile

        Returns
        -------
        float, the corresponding value result.
        """
        if self.head_sampled:
            # self._insert_head_buffer()
            self.compress()

        if quantile < 0 or quantile > 1:
            raise ValueError("Quantile should be in range [0.0, 1.0]")

        if self.count == 0:
            return 0

        if quantile <= self.error:
            return self.sampled[0][0]

        if quantile >= 1 - self.error:
            return self.sampled[-1][0]

        rank = math.ceil(quantile * self.count)
        target_error = math.ceil(self.error * self.count)
        min_rank = 0
        i = 1
        while i < len(self.sampled) - 1:
            cur_sample = self.sampled[i]
            min_rank += cur_sample[1]
            max_rank = min_rank + cur_sample[2]
            if max_rank - target_error <= rank <= min_rank + target_error:
                return cur_sample[0]
            i += 1
        return self.sampled[-1][0]

    def query_percentile_rate_list(self, percentile_rate_list):
        if self.head_sampled:
            self.compress()

        if np.min(percentile_rate_list) < 0 or np.max(percentile_rate_list) > 1:
            raise ValueError("Quantile should be in range [0.0, 1.0]")

        if self.count == 0:
            return [0] * len(percentile_rate_list)

        split_points = []
        i, j = 0, len(percentile_rate_list) - 1
        while i < len(percentile_rate_list) and percentile_rate_list[i] <= self.error:
            split_points.append(self.sampled[0][0])
            # split_points.append(self.sampled[0].value)
            i += 1

        while j >= 0 and percentile_rate_list[i] >= 1 - self.error:
            j -= 1

        k = 1
        min_rank = 0
        while i <= j:
            quantile = percentile_rate_list[i]
            rank = math.ceil(quantile * self.count)
            target_error = math.ceil(self.error * self.count)
            while k < len(self.sampled) - 1:
                # cur_sample = self.sampled[k]
                # min_rank += cur_sample.g
                # max_rank = min_rank + cur_sample.delta
                cur_sample_value = self.sampled[k][0]
                min_rank += self.sampled[k][1]
                max_rank = min_rank + self.sampled[k][2]
                if max_rank - target_error <= rank <= min_rank + target_error:
                    split_points.append(cur_sample_value)
                    min_rank -= self.sampled[k][1]
                    break
                k += 1

            if k == len(self.sampled) - 1:
                # split_points.append(self.sampled[-1].value)
                split_points.append(self.sampled[-1][0])

            i += 1

        while j + 1 < len(percentile_rate_list):
            j += 1
            split_points.append(self.sampled[-1][0])

        assert len(percentile_rate_list) == len(split_points)
        return split_points

    def value_to_rank(self, value):
        min_rank, max_rank = 0, 0
        for sample in self.sampled:
            if sample[0] < value:
                min_rank += sample[1]
                max_rank = min_rank + sample[2]
            else:
                return (min_rank + max_rank) // 2
        return (min_rank + max_rank) // 2

    def query_value_list(self, values):
        """
        Given a sorted value list, return the rank of each element in this list
        """
        self.compress()
        res = []
        min_rank, max_rank = 0, 0
        idx = 0
        sample_idx = 0

        while sample_idx < len(self.sampled):
            v = values[idx]
            sample = self.sampled[sample_idx]
            if sample[0] < v:
                min_rank += sample[1]
                max_rank = min_rank + sample[2]
                sample_idx += 1
            else:
                res.append((min_rank + max_rank) // 2)
                idx += 1
                if idx >= len(values):
                    break

        while idx < len(values):
            res.append((min_rank + max_rank) // 2)
            idx += 1
        return res

    def _compress_immut(self, merge_threshold):
        if not self.sampled:
            return self.sampled

        res = []

        # Start from the last element
        head = self.sampled[-1]
        sum_g_delta = head[1] + head[2]
        i = len(self.sampled) - 2  # Do not merge the last element

        while i >= 1:
            this_sample = self.sampled[i]
            if this_sample[1] + sum_g_delta < merge_threshold:
                head = (head[0], head[1] + this_sample[1], head[2])
                sum_g_delta += this_sample[1]
            else:
                res.append(head)
                head = this_sample
                sum_g_delta = head[1] + head[2]
            i -= 1
        res.append(head)

        # If head of current sample is smaller than this new res's head
        # Add current head into res
        current_head = self.sampled[0]
        if current_head[0] <= head[0] and len(self.sampled) > 1:
            res.append(current_head)

        # Python do not support prepend, thus, use reverse instead
        res.reverse()
        return res

class SparseQuantileSummaries(QuantileSummaries):
    def __init__(self, compress_thres=consts.DEFAULT_COMPRESS_THRESHOLD,
                 head_size=consts.DEFAULT_HEAD_SIZE,
                 error=consts.DEFAULT_RELATIVE_ERROR,
                 abnormal_list=None):
        super(SparseQuantileSummaries, self).__init__(compress_thres, head_size, error, abnormal_list)

        # Compare with the sparse point, static the number of each part.
        self.smaller_num = 0
        self.bigger_num = 0
        self._total_count = 0

    def set_total_count(self, total_count):
        self._total_count = total_count
        return self

    @property
    def summary_count(self):
        return self._total_count - self.missing_count

    def insert(self, x):
        if x in self.abnormal_list or np.isnan(x):
            self.missing_count += 1
            return
        if x < consts.FLOAT_ZERO:
            self.smaller_num += 1
        elif x >= consts.FLOAT_ZERO:
            self.bigger_num += 1
        super(SparseQuantileSummaries, self).insert(x)

    def query(self, quantile):
        if self.zero_lower_bound < quantile < self.zero_upper_bound:
            return 0.0

        non_zero_quantile = self._convert_query_percentile(quantile)
        result = super(SparseQuantileSummaries, self).query(non_zero_quantile)
        return result

    def value_to_rank(self, value):
        quantile_rank = super().value_to_rank(value)
        zeros_count = self.zero_counts

        if value > 0:
            return quantile_rank + zeros_count
        elif value < 0:
            return quantile_rank
        else:
            return quantile_rank + zeros_count // 2

    def merge(self, other):
        assert isinstance(other, SparseQuantileSummaries)
        res_summary = super(SparseQuantileSummaries, self).merge(other)
        res_summary.smaller_num = self.smaller_num + other.smaller_num
        res_summary.bigger_num = self.bigger_num + other.bigger_num
        return res_summary

    def _convert_query_percentile(self, quantile):
        zeros_count = self.zero_counts
        if zeros_count == 0:
            return quantile

        if quantile <= self.zero_lower_bound:
            return ((self._total_count - self.missing_count) / self.count) * quantile

        return (quantile - self.zero_upper_bound + self.zero_lower_bound) / (
            1 - self.zero_upper_bound + self.zero_lower_bound)

    @property
    def zero_lower_bound(self):
        if self.smaller_num == 0:
            return 0.0
        return self.smaller_num / (self._total_count - self.missing_count)

    @property
    def zero_upper_bound(self):
        if self.bigger_num == 0:
            return self._total_count - self.missing_count
        return (self.smaller_num + self.zero_counts) / (self._total_count - self.missing_count)

    @property
    def zero_counts(self):
        return self._total_count - self.smaller_num - self.bigger_num - self.missing_count

    def query_value_list(self, values):
        summary_ranks = super().query_value_list(values)
        res = []
        for v, r in zip(values, summary_ranks):
            if v == 0:
                res.append(self.smaller_num)
            elif v < 0:
                res.append(r)
            else:
                res.append(r + self.zero_counts)
        return res

def quantile_summary_factory(is_sparse, param_dict):
    if is_sparse:
        return SparseQuantileSummaries(**param_dict)
    else:
        return QuantileSummaries(**param_dict)
<commit_msg>fix sparse quantile summary's query interface<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
#  Copyright 2019 The FATE Authors. All Rights Reserved.
#
#  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.
#

import math
import numpy as np

from federatedml.util import consts, LOGGER

"""
Structure of compressed object, for memory saving we use tuple (value, g, delta) in fate>=v1.8
"""

"""
class Stats(object):
    def __init__(self, value, g: int, delta: int):
        self.value = value
        self.g = g
        self.delta = delta
"""

class QuantileSummaries(object):
    def __init__(self, compress_thres=consts.DEFAULT_COMPRESS_THRESHOLD,
                 head_size=consts.DEFAULT_HEAD_SIZE,
                 error=consts.DEFAULT_RELATIVE_ERROR,
                 abnormal_list=None):
        self.compress_thres = compress_thres
        self.head_size = head_size
        self.error = error
        self.head_sampled = []
        self.sampled = []  # list of Stats
        self.count = 0  # Total observations appeared
        self.missing_count = 0
        if abnormal_list is None:
            self.abnormal_list = []
        else:
            self.abnormal_list = abnormal_list

    # insert a number
    def insert(self, x):
        """
        Insert an observation of data. First store in a array buffer. If the buffer is full,
        do a batch insert. If the size of sampled list reach compress_thres, compress this list.
        Parameters
        ----------
        x : float
            The observation that prepare to insert

        """
        if x in self.abnormal_list or (isinstance(x, float) and np.isnan(x)):
            self.missing_count += 1
            return

        x = float(x)

        self.head_sampled.append(x)
        if len(self.head_sampled) >= self.head_size:
            self._insert_head_buffer()
            if len(self.sampled) >= self.compress_thres:
                self.compress()

    def _insert_head_buffer(self):
        if not len(self.head_sampled):  # If empty
            return
        current_count = self.count
        sorted_head = sorted(self.head_sampled)
        head_len = len(sorted_head)
        sample_len = len(self.sampled)
        new_sampled = []
        sample_idx = 0
        ops_idx = 0
        while ops_idx < head_len:
            current_sample = sorted_head[ops_idx]
            while sample_idx < sample_len and self.sampled[sample_idx][0] <= current_sample:
                new_sampled.append(self.sampled[sample_idx])
                sample_idx += 1

            current_count += 1

            # If it is the first one to insert or if it is the last one
            if not new_sampled or (sample_idx == sample_len and
                                   ops_idx == head_len - 1):
                delta = 0
            else:
                # delta = math.floor(2 * self.error * current_count) - 1
                delta = math.floor(2 * self.error * current_count)

            new_sampled.append((current_sample, 1, delta))
            ops_idx += 1

        new_sampled += self.sampled[sample_idx:]
        self.sampled = new_sampled
        self.head_sampled = []
        self.count = current_count

    def compress(self):
        self._insert_head_buffer()
        # merge_threshold = math.floor(2 * self.error * self.count) - 1
        merge_threshold = 2 * self.error * self.count
        compressed = self._compress_immut(merge_threshold)
        self.sampled = compressed

    def merge(self, other):
        """
        merge current summeries with the other one.
        Parameters
        ----------
        other : QuantileSummaries
            The summaries to be merged
        """
        if other.head_sampled:
            # other._insert_head_buffer()
            other.compress()

        if self.head_sampled:
            # self._insert_head_buffer()
            self.compress()

        if other.count == 0:
            return self

        if self.count == 0:
            return other

        # merge two sorted array
        new_sample = []
        i, j = 0, 0
        self_sample_len = len(self.sampled)
        other_sample_len = len(other.sampled)
        while i < self_sample_len and j < other_sample_len:
            if self.sampled[i][0] < other.sampled[j][0]:
                new_sample.append(self.sampled[i])
                i += 1
            else:
                new_sample.append(other.sampled[j])
                j += 1
        new_sample += self.sampled[i:]
        new_sample += other.sampled[j:]

        res_summary = self.__class__(compress_thres=self.compress_thres,
                                     head_size=self.head_size,
                                     error=self.error,
                                     abnormal_list=self.abnormal_list)
        res_summary.count = self.count + other.count
        res_summary.missing_count = self.missing_count + other.missing_count
        res_summary.sampled = new_sample
        # self.sampled = new_sample
        # self.count += other.count
        # merge_threshold = math.floor(2 * self.error * self.count) - 1
        merge_threshold = 2 * self.error * res_summary.count

        res_summary.sampled = res_summary._compress_immut(merge_threshold)
        return res_summary

    def query(self, quantile):
        """
        Given the queried quantile, return the approximation guaranteed result
        Parameters
        ----------
        quantile : float [0.0, 1.0]
            The target quantile

        Returns
        -------
        float, the corresponding value result.
        """
        if self.head_sampled:
            # self._insert_head_buffer()
            self.compress()

        if quantile < 0 or quantile > 1:
            raise ValueError("Quantile should be in range [0.0, 1.0]")

        if self.count == 0:
            return 0

        if quantile <= self.error:
            return self.sampled[0][0]

        if quantile >= 1 - self.error:
            return self.sampled[-1][0]

        rank = math.ceil(quantile * self.count)
        target_error = math.ceil(self.error * self.count)
        min_rank = 0
        i = 1
        while i < len(self.sampled) - 1:
            cur_sample = self.sampled[i]
            min_rank += cur_sample[1]
            max_rank = min_rank + cur_sample[2]
            if max_rank - target_error <= rank <= min_rank + target_error:
                return cur_sample[0]
            i += 1
        return self.sampled[-1][0]

    def query_percentile_rate_list(self, percentile_rate_list):
        if self.head_sampled:
            self.compress()

        if np.min(percentile_rate_list) < 0 or np.max(percentile_rate_list) > 1:
            raise ValueError("Quantile should be in range [0.0, 1.0]")

        if self.count == 0:
            return [0] * len(percentile_rate_list)

        split_points = []
        i, j = 0, len(percentile_rate_list) - 1
        while i < len(percentile_rate_list) and percentile_rate_list[i] <= self.error:
            split_points.append(self.sampled[0][0])
            # split_points.append(self.sampled[0].value)
            i += 1

        while j >= 0 and percentile_rate_list[i] >= 1 - self.error:
            j -= 1

        k = 1
        min_rank = 0
        while i <= j:
            quantile = percentile_rate_list[i]
            rank = math.ceil(quantile * self.count)
            target_error = math.ceil(self.error * self.count)
            while k < len(self.sampled) - 1:
                # cur_sample = self.sampled[k]
                # min_rank += cur_sample.g
                # max_rank = min_rank + cur_sample.delta
                cur_sample_value = self.sampled[k][0]
                min_rank += self.sampled[k][1]
                max_rank = min_rank + self.sampled[k][2]
                if max_rank - target_error <= rank <= min_rank + target_error:
                    split_points.append(cur_sample_value)
                    min_rank -= self.sampled[k][1]
                    break
                k += 1

            if k == len(self.sampled) - 1:
                # split_points.append(self.sampled[-1].value)
                split_points.append(self.sampled[-1][0])

            i += 1

        while j + 1 < len(percentile_rate_list):
            j += 1
            split_points.append(self.sampled[-1][0])

        assert len(percentile_rate_list) == len(split_points)
        return split_points

    def value_to_rank(self, value):
        min_rank, max_rank = 0, 0
        for sample in self.sampled:
            if sample[0] < value:
                min_rank += sample[1]
                max_rank = min_rank + sample[2]
            else:
                return (min_rank + max_rank) // 2
        return (min_rank + max_rank) // 2

    def query_value_list(self, values):
        """
        Given a sorted value list, return the rank of each element in this list
        """
        self.compress()
        res = []
        min_rank, max_rank = 0, 0
        idx = 0
        sample_idx = 0

        while sample_idx < len(self.sampled):
            v = values[idx]
            sample = self.sampled[sample_idx]
            if sample[0] < v:
                min_rank += sample[1]
                max_rank = min_rank + sample[2]
                sample_idx += 1
            else:
                res.append((min_rank + max_rank) // 2)
                idx += 1
                if idx >= len(values):
                    break

        while idx < len(values):
            res.append((min_rank + max_rank) // 2)
            idx += 1
        return res

    def _compress_immut(self, merge_threshold):
        if not self.sampled:
            return self.sampled

        res = []

        # Start from the last element
        head = self.sampled[-1]
        sum_g_delta = head[1] + head[2]
        i = len(self.sampled) - 2  # Do not merge the last element

        while i >= 1:
            this_sample = self.sampled[i]
            if this_sample[1] + sum_g_delta < merge_threshold:
                head = (head[0], head[1] + this_sample[1], head[2])
                sum_g_delta += this_sample[1]
            else:
                res.append(head)
                head = this_sample
                sum_g_delta = head[1] + head[2]
            i -= 1
        res.append(head)

        # If head of current sample is smaller than this new res's head
        # Add current head into res
        current_head = self.sampled[0]
        if current_head[0] <= head[0] and len(self.sampled) > 1:
            res.append(current_head)

        # Python do not support prepend, thus, use reverse instead
        res.reverse()
        return res

class SparseQuantileSummaries(QuantileSummaries):
    def __init__(self, compress_thres=consts.DEFAULT_COMPRESS_THRESHOLD,
                 head_size=consts.DEFAULT_HEAD_SIZE,
                 error=consts.DEFAULT_RELATIVE_ERROR,
                 abnormal_list=None):
        super(SparseQuantileSummaries, self).__init__(compress_thres, head_size, error, abnormal_list)

        # Compare with the sparse point, static the number of each part.
        self.smaller_num = 0
        self.bigger_num = 0
        self._total_count = 0

    def set_total_count(self, total_count):
        self._total_count = total_count
        return self

    @property
    def summary_count(self):
        return self._total_count - self.missing_count

    def insert(self, x):
        if x in self.abnormal_list or np.isnan(x):
            self.missing_count += 1
            return
        if x < consts.FLOAT_ZERO:
            self.smaller_num += 1
        elif x >= consts.FLOAT_ZERO:
            self.bigger_num += 1
        super(SparseQuantileSummaries, self).insert(x)

    def query(self, quantile):
        if self.zero_lower_bound < quantile < self.zero_upper_bound:
            return 0.0

        non_zero_quantile = self._convert_query_percentile(quantile)
        result = super(SparseQuantileSummaries, self).query(non_zero_quantile)
        return result

    def query_percentile_rate_list(self, percentile_rate_list):
        result = []
        non_zero_quantile_list = list()
        for quantile in percentile_rate_list:
            if self.zero_lower_bound < quantile < self.zero_upper_bound:
                result.append(0.0)
            else:
                non_zero_quantile_list.append(self._convert_query_percentile(quantile))

        if non_zero_quantile_list:
            result += super(SparseQuantileSummaries, self).query_percentile_rate_list(non_zero_quantile_list)

        return result

    def value_to_rank(self, value):
        quantile_rank = super().value_to_rank(value)
        zeros_count = self.zero_counts

        if value > 0:
            return quantile_rank + zeros_count
        elif value < 0:
            return quantile_rank
        else:
            return quantile_rank + zeros_count // 2

    def merge(self, other):
        assert isinstance(other, SparseQuantileSummaries)
        res_summary = super(SparseQuantileSummaries, self).merge(other)
        res_summary.smaller_num = self.smaller_num + other.smaller_num
        res_summary.bigger_num = self.bigger_num + other.bigger_num
        return res_summary

    def _convert_query_percentile(self, quantile):
        zeros_count = self.zero_counts
        if zeros_count == 0:
            return quantile

        if quantile <= self.zero_lower_bound:
            return ((self._total_count - self.missing_count) / self.count) * quantile

        return (quantile - self.zero_upper_bound + self.zero_lower_bound) / (
            1 - self.zero_upper_bound + self.zero_lower_bound)

    @property
    def zero_lower_bound(self):
        if self.smaller_num == 0:
            return 0.0
        return self.smaller_num / (self._total_count - self.missing_count)

    @property
    def zero_upper_bound(self):
        if self.bigger_num == 0:
            return self._total_count - self.missing_count
        return (self.smaller_num + self.zero_counts) / (self._total_count - self.missing_count)

    @property
    def zero_counts(self):
        return self._total_count - self.smaller_num - self.bigger_num - self.missing_count

    def query_value_list(self, values):
        summary_ranks = super().query_value_list(values)
        res = []
        for v, r in zip(values, summary_ranks):
            if v == 0:
                res.append(self.smaller_num)
            elif v < 0:
                res.append(r)
            else:
                res.append(r + self.zero_counts)
        return res

def quantile_summary_factory(is_sparse, param_dict):
    if is_sparse:
        return SparseQuantileSummaries(**param_dict)
    else:
        return QuantileSummaries(**param_dict)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Dave Lasley
#    Copyright: 2015 LasLabs
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

#from openerp import models, fields, api
import logging
from openerp.osv import fields, osv
from openerp.addons.base_geoengine import geo_model, fields

_logger = logging.getLogger(__name__)

class StockProductionLot(geo_model.GeoModel):
    """Add geo_point to stock.production.lot """
    _inherit = "stock.production.lot"

    geo_point = geo_fields.GeoPoint(readonly=True, store=True)

class StockMove(osv.osv):
    _inherit = 'stock.move'

    def write(self, cr, uid, ids, vals, context=None):

        super(StockMove, self).write(cr, uid, ids, vals, context)

        for move in self.browse(cr, uid, ids, context=context):
            if move.state == 'done':

                if move.location_dest_id.usage == 'customer':
                    for lot in move.lot_ids:

                        try:
                            lot.geo_point = move.partner_id.geo_point
                        except Exception as e:
                            _logger.error(
                                'Unable to apply geo for customer %s\n%s\n',
                                move.partner_id.id, e
                            )

                elif move.location_dest_id.usage == 'internal':
                    for lot in move.lot_ids:

                        try:
                            lot.geo_point = move.location_dest_id.partner_id.geo_point
                        except Exception as e:
                            _logger.error(
                                'Unable to apply geo for location %s\n%s\n',
                                move.location_dest_id.id, e
                            )

                else:
                    _logger.error(
                        'Location type %s not implemented for geo tracking',
                    )
                    <commit_msg>* fixed import<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Author: Dave Lasley
#    Copyright: 2015 LasLabs
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

#from openerp import models, fields, api
import logging
from openerp.osv import fields, osv
from openerp.addons.base_geoengine import geo_model
from openerp.addons.base_geoengine import fields as geo_fields

_logger = logging.getLogger(__name__)

class StockProductionLot(geo_model.GeoModel):
    """Add geo_point to stock.production.lot """
    _inherit = "stock.production.lot"

    geo_point = geo_fields.GeoPoint(readonly=True, store=True)

class StockMove(osv.osv):
    _inherit = 'stock.move'

    def write(self, cr, uid, ids, vals, context=None):

        super(StockMove, self).write(cr, uid, ids, vals, context)

        for move in self.browse(cr, uid, ids, context=context):
            if move.state == 'done':

                if move.location_dest_id.usage == 'customer':
                    for lot in move.lot_ids:

                        try:
                            lot.geo_point = move.partner_id.geo_point
                        except Exception as e:
                            _logger.error(
                                'Unable to apply geo for customer %s\n%s\n',
                                move.partner_id.id, e
                            )

                elif move.location_dest_id.usage == 'internal':
                    for lot in move.lot_ids:

                        try:
                            lot.geo_point = move.location_dest_id.partner_id.geo_point
                        except Exception as e:
                            _logger.error(
                                'Unable to apply geo for location %s\n%s\n',
                                move.location_dest_id.id, e
                            )

                else:
                    _logger.error(
                        'Location type %s not implemented for geo tracking',
                    )
                    <|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

# Hive Netius System
# Copyright (C) 2008-2014 Hive Solutions Lda.
#
# This file is part of Hive Netius System.
#
# Hive Netius System 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 3 of the License, or
# (at your option) any later version.
#
# Hive Netius System is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hive Netius System. If not, see <http://www.gnu.org/licenses/>.

__author__ = "João Magalhães <joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2014 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "GNU General Public License (GPL), Version 3"
""" The license for the module """

import re
import time

import netius.common
import netius.servers

class ReverseProxyServer(netius.servers.ProxyServer):

    def __init__(
        self,
        config = "proxy.json",
        regex = {},
        hosts = {},
        strategy = "smart",
        *args,
        **kwargs
    ):
        netius.servers.ProxyServer.__init__(self, *args, **kwargs)
        if type(regex) == dict: regex = regex.items()
        if not type(hosts) == dict: hosts = dict(hosts)
        self.load_config(
            path = config,
            regex = regex,
            hosts = hosts,
            strategy = strategy,
            robin = dict(),
            smart = netius.common.PriorityDict()
        )
        self.balancer_m = getattr(self, "balancer_" + self.strategy)
        self.releaser_m = getattr(self, "releaser_" + self.strategy)

    def on_data_http(self, connection, parser):
        netius.servers.ProxyServer.on_data_http(self, connection, parser)

        # retrieves the various parts/configuration values of the parser, that
        # are going to be used in the processing/routing of the proxy request,
        # note that some of these values need to be transformed to be used
        method = parser.method.upper()
        path = parser.path_s
        headers = parser.headers
        version_s = parser.version_s
        is_secure = connection.ssl
        host = headers.get("host", None)
        protocol = "https" if is_secure else "http"

        # constructs the url that is going to be used by the rule engine and
        # then "forwards" both the url and the parser object to the rule engine
        # in order to obtain the possible prefix value for url reconstruction,
        # a state value is also retrieved, this value will be used latter for
        # the releasing part of the balancing strategy operation
        url = "%s://%s%s" % (protocol, host, path)
        prefix, state = self.rules(url, parser)

        # in case no prefix is defined at this stage there's no matching
        # against the currently defined rules and so an error must be raised
        # and propagated to the client connection (end user notification)
        if not prefix:
            self.debug("No valid proxy endpoint found")
            connection.send_response(
                data = "No valid proxy endpoint found",
                headers = dict(
                    connection = "close"
                ),
                version = version_s,
                code = 404,
                code_s = "Not Found",
                apply = True,
                callback = self._prx_close
            )
            return

        # re-calculates the url for the reverse connection based on the
        # prefix value that has just been "resolved" using the rule engine
        # this value should be constructed based on the original path
        url = prefix + path

        # updates the various headers that are relates with the reverse
        # proxy operation this is required so that the request gets
        # properly handled by the reverse server, otherwise some problems
        # would occur in the operation of handling the request
        headers["x-forwarded-proto"] = protocol

        # verifies if the current connection contains already contains
        # a proxy connection if that's the case that must be unset from the
        # connection and from the connection map internal structures at
        # least until the http client returns from the method call
        proxy_c = hasattr(connection, "proxy_c") and connection.proxy_c
        proxy_c = proxy_c or None
        connection.proxy_c = None
        if proxy_c in self.conn_map: del self.conn_map[proxy_c]

        # calls the proper (http) method in the client this should acquire
        # a new connection and starts the process of sending the request
        # to the associated http server (request handling)
        _connection = self.http_client.method(
            method,
            url,
            headers = headers,
            data = parser.get_message(),
            version = version_s,
            connection = proxy_c
        )

        # sets the state attribute in the connection so that it's possible
        # to retrieve it latter for tagging evaluation, this is required for
        # advanced load balancing techniques to be performed
        _connection.state = state

        # prints a debug message about the connection becoming a waiting
        # connection meaning that the connection with the client host has
        # not been yet established (no data has been  received)
        self.debug("Setting connection as waiting, proxy connection loading ...")

        # sets the current http back-end client connection as waiting and then
        # maps it as the proxy connection in the connection and also creates
        # the reverse mapping using the connection map of the current server
        _connection.waiting = True
        connection.proxy_c = _connection
        self.conn_map[_connection] = connection

    def rules(self, url, parser):
        resolved = self.rules_regex(url, parser)
        if resolved[0]: return resolved
        resolved = self.rules_host(url, parser)
        if resolved[0]: return resolved
        return None, None

    def rules_regex(self, url, parser):
        # sets the prefix and state values initially for the invalid/unset value,
        # these values are going to be populated once a valid match is found
        prefix = None
        state = None

        # iterates over the complete set of defined regex values to try
        # to find a valid match and apply the groups value for format
        # if the complete chain of regex is processed but there's no
        # valid match the prefix value is considered to be unset
        for regex, _prefix in self.regex:
            match = regex.match(url)
            if not match: continue
            _prefix, _state = self.balancer(_prefix)
            groups = match.groups()
            if groups: _prefix = _prefix.format(*groups)
            prefix = _prefix
            state = _state
            break

        # returns the prefix and state values that have just been resolved
        # through regex based validation, this value may be unset for a mismatch
        return prefix, state

    def rules_host(self, url, parser):
        # retrieves the reference to the headers map from the parser so
        # that it may be used to retrieve the current host value and try
        # to match it against any of the currently defined rules
        headers = parser.headers

        # retrieves the host header from the received set of headers,
        # removing the port definition part of the host and then verifies
        # the complete set of defined hosts in order to check for the
        # presence of such rule, in case there's a match the defined
        # url prefix is going to be used instead, the balancer operation
        # is then used to "resolve" the final prefix value from sequence
        host = headers.get("host", None)
        if host: host = host.split(":", 1)[0]
        prefix = self.hosts.get(host, None)
        resolved = self.balancer(prefix)

        # returns the final "resolved" prefix value (in case there's any)
        # to the caller method, this should be used for url reconstruction
        # note that the state value is also returned and should be store in
        # the current handling connection so that it may latter be used
        return resolved

    def balancer(self, values):
        is_sequence = type(values) in (list, tuple)
        if not is_sequence: return values, None
        return self.balancer_m(values)

    def balancer_robin(self, values):
        index = self.robin.get(values, 0)
        prefix = values[index]
        next = 0 if index + 1 == len(values) else index + 1
        self.robin[values] = next
        return prefix, None

    def balancer_smart(self, values):
        queue = self.smart.get(values, None)
        if not queue:
            queue = netius.common.PriorityDict()
            for value in values: queue[value] = [0, 0]
            self.smart[values] = queue

        prefix = queue.smallest()

        sorter = queue[prefix]
        if sorter[0] == 0: sorter[1] = time.time() * -1
        sorter[0] += 1
        queue[prefix] = sorter

        return prefix, (prefix, queue)

    def releaser(self, state):
        self.releaser_m(state)

    def releaser_robin(self, state):
        pass

    def releaser_smart(self, state):
        prefix, queue = state
        sorter = queue[prefix]
        sorter[0] -= 1
        queue[prefix] = sorter

    def _on_prx_message(self, client, parser, message):
        _connection = parser.owner
        state = _connection.state if hasattr(_connection, "state") else None
        if state: self.releaser(state); _connection.state = None
        netius.servers.ProxyServer._on_prx_message(self, client, parser, message)

    def _on_prx_close(self, client, _connection):
        state = _connection.state if hasattr(_connection, "state") else None
        if state: self.releaser(state); _connection.state = None
        netius.servers.ProxyServer._on_prx_close(self, client, _connection)

if __name__ == "__main__":
    import logging
    regex = (
        (re.compile(r"https://host\.com"), "http://localhost"),
        (re.compile(r"https://([a-zA-Z]*)\.host\.com"), "http://localhost/{0}")
    )
    hosts = {
        "host.com" : "http://localhost"
    }
    server = ReverseProxyServer(
        regex = regex,
        hosts = hosts,
        level = logging.INFO
    )
    server.serve(env = True)
<commit_msg>saves last time reached zero<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

# Hive Netius System
# Copyright (C) 2008-2014 Hive Solutions Lda.
#
# This file is part of Hive Netius System.
#
# Hive Netius System 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 3 of the License, or
# (at your option) any later version.
#
# Hive Netius System is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Hive Netius System. If not, see <http://www.gnu.org/licenses/>.

__author__ = "João Magalhães <joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2014 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "GNU General Public License (GPL), Version 3"
""" The license for the module """

import re
import time

import netius.common
import netius.servers

class ReverseProxyServer(netius.servers.ProxyServer):

    def __init__(
        self,
        config = "proxy.json",
        regex = {},
        hosts = {},
        strategy = "smart",
        *args,
        **kwargs
    ):
        netius.servers.ProxyServer.__init__(self, *args, **kwargs)
        if type(regex) == dict: regex = regex.items()
        if not type(hosts) == dict: hosts = dict(hosts)
        self.load_config(
            path = config,
            regex = regex,
            hosts = hosts,
            strategy = strategy,
            robin = dict(),
            smart = netius.common.PriorityDict()
        )
        self.balancer_m = getattr(self, "balancer_" + self.strategy)
        self.releaser_m = getattr(self, "releaser_" + self.strategy)

    def on_data_http(self, connection, parser):
        netius.servers.ProxyServer.on_data_http(self, connection, parser)

        # retrieves the various parts/configuration values of the parser, that
        # are going to be used in the processing/routing of the proxy request,
        # note that some of these values need to be transformed to be used
        method = parser.method.upper()
        path = parser.path_s
        headers = parser.headers
        version_s = parser.version_s
        is_secure = connection.ssl
        host = headers.get("host", None)
        protocol = "https" if is_secure else "http"

        # constructs the url that is going to be used by the rule engine and
        # then "forwards" both the url and the parser object to the rule engine
        # in order to obtain the possible prefix value for url reconstruction,
        # a state value is also retrieved, this value will be used latter for
        # the releasing part of the balancing strategy operation
        url = "%s://%s%s" % (protocol, host, path)
        prefix, state = self.rules(url, parser)

        # in case no prefix is defined at this stage there's no matching
        # against the currently defined rules and so an error must be raised
        # and propagated to the client connection (end user notification)
        if not prefix:
            self.debug("No valid proxy endpoint found")
            connection.send_response(
                data = "No valid proxy endpoint found",
                headers = dict(
                    connection = "close"
                ),
                version = version_s,
                code = 404,
                code_s = "Not Found",
                apply = True,
                callback = self._prx_close
            )
            return

        # re-calculates the url for the reverse connection based on the
        # prefix value that has just been "resolved" using the rule engine
        # this value should be constructed based on the original path
        url = prefix + path

        # updates the various headers that are relates with the reverse
        # proxy operation this is required so that the request gets
        # properly handled by the reverse server, otherwise some problems
        # would occur in the operation of handling the request
        headers["x-forwarded-proto"] = protocol

        # verifies if the current connection contains already contains
        # a proxy connection if that's the case that must be unset from the
        # connection and from the connection map internal structures at
        # least until the http client returns from the method call
        proxy_c = hasattr(connection, "proxy_c") and connection.proxy_c
        proxy_c = proxy_c or None
        connection.proxy_c = None
        if proxy_c in self.conn_map: del self.conn_map[proxy_c]

        # calls the proper (http) method in the client this should acquire
        # a new connection and starts the process of sending the request
        # to the associated http server (request handling)
        _connection = self.http_client.method(
            method,
            url,
            headers = headers,
            data = parser.get_message(),
            version = version_s,
            connection = proxy_c
        )

        # sets the state attribute in the connection so that it's possible
        # to retrieve it latter for tagging evaluation, this is required for
        # advanced load balancing techniques to be performed
        _connection.state = state

        # prints a debug message about the connection becoming a waiting
        # connection meaning that the connection with the client host has
        # not been yet established (no data has been  received)
        self.debug("Setting connection as waiting, proxy connection loading ...")

        # sets the current http back-end client connection as waiting and then
        # maps it as the proxy connection in the connection and also creates
        # the reverse mapping using the connection map of the current server
        _connection.waiting = True
        connection.proxy_c = _connection
        self.conn_map[_connection] = connection

    def rules(self, url, parser):
        resolved = self.rules_regex(url, parser)
        if resolved[0]: return resolved
        resolved = self.rules_host(url, parser)
        if resolved[0]: return resolved
        return None, None

    def rules_regex(self, url, parser):
        # sets the prefix and state values initially for the invalid/unset value,
        # these values are going to be populated once a valid match is found
        prefix = None
        state = None

        # iterates over the complete set of defined regex values to try
        # to find a valid match and apply the groups value for format
        # if the complete chain of regex is processed but there's no
        # valid match the prefix value is considered to be unset
        for regex, _prefix in self.regex:
            match = regex.match(url)
            if not match: continue
            _prefix, _state = self.balancer(_prefix)
            groups = match.groups()
            if groups: _prefix = _prefix.format(*groups)
            prefix = _prefix
            state = _state
            break

        # returns the prefix and state values that have just been resolved
        # through regex based validation, this value may be unset for a mismatch
        return prefix, state

    def rules_host(self, url, parser):
        # retrieves the reference to the headers map from the parser so
        # that it may be used to retrieve the current host value and try
        # to match it against any of the currently defined rules
        headers = parser.headers

        # retrieves the host header from the received set of headers,
        # removing the port definition part of the host and then verifies
        # the complete set of defined hosts in order to check for the
        # presence of such rule, in case there's a match the defined
        # url prefix is going to be used instead, the balancer operation
        # is then used to "resolve" the final prefix value from sequence
        host = headers.get("host", None)
        if host: host = host.split(":", 1)[0]
        prefix = self.hosts.get(host, None)
        resolved = self.balancer(prefix)

        # returns the final "resolved" prefix value (in case there's any)
        # to the caller method, this should be used for url reconstruction
        # note that the state value is also returned and should be store in
        # the current handling connection so that it may latter be used
        return resolved

    def balancer(self, values):
        is_sequence = type(values) in (list, tuple)
        if not is_sequence: return values, None
        return self.balancer_m(values)

    def balancer_robin(self, values):
        index = self.robin.get(values, 0)
        prefix = values[index]
        next = 0 if index + 1 == len(values) else index + 1
        self.robin[values] = next
        return prefix, None

    def balancer_smart(self, values):
        queue = self.smart.get(values, None)
        if not queue:
            queue = netius.common.PriorityDict()
            for value in values: queue[value] = [0, 0]
            self.smart[values] = queue

        prefix = queue.smallest()

        sorter = queue[prefix]
        sorter[0] += 1
        queue[prefix] = sorter

        return prefix, (prefix, queue)

    def releaser(self, state):
        self.releaser_m(state)

    def releaser_robin(self, state):
        pass

    def releaser_smart(self, state):
        prefix, queue = state
        sorter = queue[prefix]
        sorter[0] -= 1
        if sorter[0] == 0: sorter[1] = time.time() * -1
        queue[prefix] = sorter

    def _on_prx_message(self, client, parser, message):
        _connection = parser.owner
        state = _connection.state if hasattr(_connection, "state") else None
        if state: self.releaser(state); _connection.state = None
        netius.servers.ProxyServer._on_prx_message(self, client, parser, message)

    def _on_prx_close(self, client, _connection):
        state = _connection.state if hasattr(_connection, "state") else None
        if state: self.releaser(state); _connection.state = None
        netius.servers.ProxyServer._on_prx_close(self, client, _connection)

if __name__ == "__main__":
    import logging
    regex = (
        (re.compile(r"https://host\.com"), "http://localhost"),
        (re.compile(r"https://([a-zA-Z]*)\.host\.com"), "http://localhost/{0}")
    )
    hosts = {
        "host.com" : "http://localhost"
    }
    server = ReverseProxyServer(
        regex = regex,
        hosts = hosts,
        level = logging.INFO
    )
    server.serve(env = True)
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
# import asyncio
import json
# import io
# import random
# import time
# import random
import aiohttp

class Watashi(commands.Bot):
    def __init__(self, config_path: str, *args, **kwargs):
        self.config_path = config_path
        with open(self.config_path) as f:
            self.configs = json.load(f)

        self.default_cogs = ('cogs.base', 'cogs.coding', 'cogs.emoji', 'cogs.wiki', 'cogs.grief', 'cogs.aesthetic')

        self.embed_colour = int(self.configs['embed_colour'], 16)

        super().__init__(command_prefix=self.configs['prefix'], self_bot=True)

        #Colours
        self.gold = 16766720
        self.red = 16711680
        self.orange = 16753920
        self.yellow = 16776960
        self.darkgreen = 25600
        self.lightgreen = 589568
        self.lightblue = 58879
        self.darkblue = 255
        self.blurple = 7506394
        self.purple = 8388736
        self.grey = 8421504

        self.aiohttp_session = aiohttp.ClientSession(loop=self.loop)

    def run(self):
        super().run(self.configs['token'], bot=False)

    async def on_ready(self):
            print('\n'*100)
            print("<----------------->\nWatashi SelfBot\n<----------------->\nCoded by:\nPrestige#9162\nDemo#9465\nnaught0#4417\n<----------------->\nWarning:\nUnder the MIT\nlicense we are\nnot liable for any\ndamage caused/\naction taken\nagainst you for\nusing a selfbot\nwhich is in violation\nof Discord's TOS")
            for cog in self.default_cogs:
                self.load_extension(cog)<commit_msg>Added the cog to watashi<commit_after>import discord
from discord.ext import commands
# import asyncio
import json
# import io
# import random
# import time
# import random
import aiohttp

class Watashi(commands.Bot):
    def __init__(self, config_path: str, *args, **kwargs):
        self.config_path = config_path
        with open(self.config_path) as f:
            self.configs = json.load(f)

        self.default_cogs = ('cogs.base', 'cogs.coding', 'cogs.emoji', 'cogs.wiki', 'cogs.grief', 'cogs.aesthetic','cogs.urband')

        self.embed_colour = int(self.configs['embed_colour'], 16)

        super().__init__(command_prefix=self.configs['prefix'], self_bot=True)

        #Colours
        self.gold = 16766720
        self.red = 16711680
        self.orange = 16753920
        self.yellow = 16776960
        self.darkgreen = 25600
        self.lightgreen = 589568
        self.lightblue = 58879
        self.darkblue = 255
        self.blurple = 7506394
        self.purple = 8388736
        self.grey = 8421504

        self.aiohttp_session = aiohttp.ClientSession(loop=self.loop)

    def run(self):
        super().run(self.configs['token'], bot=False)

    async def on_ready(self):
            print('\n'*100)
            print("<----------------->\nWatashi SelfBot\n<----------------->\nCoded by:\nPrestige#9162\nDemo#9465\nnaught0#4417\n<----------------->\nWarning:\nUnder the MIT\nlicense we are\nnot liable for any\ndamage caused/\naction taken\nagainst you for\nusing a selfbot\nwhich is in violation\nof Discord's TOS")
            for cog in self.default_cogs:
                self.load_extension(cog)<|endoftext|>