# pylint: disable=g-bad-file-header
# Copyright 2017 The Bazel 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 os
import stat
import unittest
from src.test.py.bazel import test_base

class LauncherTest(test_base.TestBase):

  def testJavaBinaryLauncher(self):
    self.ScratchFile('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'java_binary(',
        '  name = "foo",',
        '  srcs = ["Main.java"],',
        '  main_class = "Main",',
        '  data = ["//bar:bar.txt"],',
        ')',
    ])
    self.ScratchFile('foo/Main.java', [
        'public class Main {',
        '  public static void main(String[] args) {'
        '    System.out.println("hello java");',
        '    System.out.println("java_runfiles=" + ',
        '        System.getenv("JAVA_RUNFILES"));',
        '    System.out.println("runfiles_manifest_only=" + ',
        '        System.getenv("RUNFILES_MANIFEST_ONLY"));',
        '    System.out.println("runfiles_manifest_file=" + ',
        '        System.getenv("RUNFILES_MANIFEST_FILE"));',
        '  }',
        '}',
    ])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]

    exit_code, _, stderr = self.RunBazel(['build', '//foo'])
    self.AssertExitCode(exit_code, 0, stderr)
    main_binary = os.path.join(bazel_bin,
                               'foo/foo%s' % ('.cmd'
                                              if self.IsWindows() else ''))
    self.assertTrue(os.path.isfile(main_binary))
    self.assertTrue(os.path.isdir(os.path.join(bazel_bin, 'foo/foo.runfiles')))

    if self.IsWindows():
      self.assertTrue(os.path.isfile(main_binary))
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin, 'foo/foo.runfiles/MANIFEST'),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin, 'foo/foo.runfiles/__main__/bar/bar.txt')))

    exit_code, stdout, stderr = self.RunProgram([main_binary])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(len(stdout), 4)
    self.assertEqual(stdout[0], 'hello java')
    if self.IsWindows():
      self.assertRegexpMatches(stdout[1], r'java_runfiles=.*foo\\foo.runfiles')
      self.assertEqual(stdout[2], 'runfiles_manifest_only=1')
      self.assertRegexpMatches(
          stdout[3], r'^runfiles_manifest_file=[a-zA-Z]:[/\\].*MANIFEST$')
    else:
      self.assertRegexpMatches(stdout[1], r'java_runfiles=.*/foo/foo.runfiles')
      self.assertEqual(stdout[2], 'runfiles_manifest_only=')
      self.assertRegexpMatches(stdout[3], r'^runfiles_manifest_file.*MANIFEST$')

  def _buildShBinaryTargets(self, bazel_bin, launcher_flag, bin1_suffix):
    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin1.sh'] +
                                         launcher_flag)
    self.AssertExitCode(exit_code, 0, stderr)

    bin1 = os.path.join(bazel_bin, 'foo', 'bin1.sh%s' % bin1_suffix)

    self.assertTrue(os.path.exists(bin1))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/bin1.sh%s.runfiles' % bin1_suffix)))

    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin2.cmd'] +
                                         launcher_flag)
    self.AssertExitCode(exit_code, 0, stderr)

    bin2 = os.path.join(bazel_bin, 'foo/bin2.cmd')
    self.assertTrue(os.path.exists(bin2))
    self.assertTrue(
        os.path.isdir(os.path.join(bazel_bin, 'foo/bin2.cmd.runfiles')))

    exit_code, _, stderr = self.RunBazel(['build', '//foo:bin3.bat'] +
                                         launcher_flag)
    if self.IsWindows():
      self.AssertExitCode(exit_code, 1, stderr)
      self.assertIn('target name extension should match source file extension.',
                    os.linesep.join(stderr))
    else:
      bin3 = os.path.join(bazel_bin, 'foo', 'bin3.bat')
      self.assertTrue(os.path.exists(bin3))
      self.assertTrue(
          os.path.isdir(os.path.join(bazel_bin, 'foo/bin3.bat.runfiles')))

    if self.IsWindows():
      self.assertTrue(os.path.isfile(bin1))
      self.assertTrue(os.path.isfile(bin2))
    else:
      self.assertTrue(os.path.islink(bin1))
      self.assertTrue(os.path.islink(bin2))
      self.assertTrue(os.path.islink(bin3))

    if self.IsWindows():
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin,
                       'foo/bin1.sh%s.runfiles/MANIFEST' % bin1_suffix),
          '__main__/bar/bar.txt')
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin, 'foo/bin2.cmd.runfiles/MANIFEST'),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin1.sh.runfiles/__main__/bar/bar.txt')))
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin2.cmd.runfiles/__main__/bar/bar.txt')))
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin,
                           'foo/bin3.bat.runfiles/__main__/bar/bar.txt')))

    exit_code, stdout, stderr = self.RunProgram([bin1])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(len(stdout), 3)
    self.assertEqual(stdout[0], 'hello shell')
    if self.IsWindows():
      self.assertEqual(stdout[1], 'runfiles_manifest_only=1')
      self.assertRegexpMatches(
          stdout[2],
          (r'^runfiles_manifest_file='
           r'[a-zA-Z]:/.*/foo/bin1.sh%s.runfiles/MANIFEST$' % bin1_suffix))
    else:
      # TODO(laszlocsomor): Find out whether the runfiles-related envvars should
      # be set on Linux (e.g. $RUNFILES, $RUNFILES_MANIFEST_FILE). Currently
      # they aren't, and that may be a bug. If it's indeed a bug, fix that bug
      # and update this test.
      self.assertEqual(stdout[1], 'runfiles_manifest_only=')
      self.assertEqual(stdout[2], 'runfiles_manifest_file=')

    if self.IsWindows():
      exit_code, stdout, stderr = self.RunProgram([bin2])
      self.AssertExitCode(exit_code, 0, stderr)
      self.assertEqual(stdout[0], 'hello batch')

  def _buildPyTargets(self, bazel_bin, launcher_flag, binary_suffix):
    # Verify that the build of our py_binary succeeds.
    exit_code, _, stderr = self.RunBazel(['build', '//foo:foo'] + launcher_flag)
    self.AssertExitCode(exit_code, 0, stderr)

    # Verify that generated files exist.
    foo_bin = os.path.join(bazel_bin, 'foo', 'foo%s' % binary_suffix)
    self.assertTrue(os.path.isfile(foo_bin))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/foo%s.runfiles' % binary_suffix)))

    # Verify contents of runfiles (manifest).
    if self.IsWindows():
      self.AssertRunfilesManifestContains(
          os.path.join(bazel_bin,
                       'foo/foo%s.runfiles/MANIFEST' % binary_suffix),
          '__main__/bar/bar.txt')
    else:
      self.assertTrue(
          os.path.islink(
              os.path.join(bazel_bin, 'foo/foo.runfiles/__main__/bar/bar.txt')))

    # Try to run the built py_binary.
    exit_code, stdout, stderr = self.RunProgram([foo_bin])
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(stdout[0], 'Hello World!')

    # Try to use the py_binary as an executable in a Skylark rule.
    exit_code, stdout, stderr = self.RunBazel(['build', '//foo:hello'] +
                                              launcher_flag)
    self.AssertExitCode(exit_code, 0, stderr)

    # Verify that the Skylark action generated the right output.
    hello_path = os.path.join(bazel_bin, 'foo', 'hello.txt')
    self.assertTrue(os.path.isfile(hello_path))
    with open(hello_path, 'r') as f:
      self.assertEqual(f.read(), 'Hello World!')

    # Verify that running py_test succeeds.
    exit_code, _, stderr = self.RunBazel(['test', '//foo:test'] + launcher_flag)
    self.AssertExitCode(exit_code, 0, stderr)

  def testShBinaryLauncher(self):
    self.ScratchFile('WORKSPACE')
    self.ScratchFile(
        'foo/BUILD',
        [
            # On Linux/MacOS, all sh_binary rules generate an output file with
            # the same name as the rule, and this is a symlink to the file in
            # `srcs`. (Bazel allows only one file in `sh_binary.srcs`.)
            # On Windows, if the srcs's extension is one of ".exe", ".cmd", or
            # ".bat", then Bazel requires the rule's name has the same
            # extension, and the output file will be a copy of the source file.
            'sh_binary(',
            '  name = "bin1.sh",',
            '  srcs = ["foo.sh"],',
            '  data = ["//bar:bar.txt"],',
            ')',
            'sh_binary(',
            '  name = "bin2.cmd",',  # name's extension matches that of srcs[0]
            '  srcs = ["foo.cmd"],',
            '  data = ["//bar:bar.txt"],',
            ')',
            'sh_binary(',
            '  name = "bin3.bat",',  # name's extension doesn't match srcs[0]'s
            '  srcs = ["foo.cmd"],',
            '  data = ["//bar:bar.txt"],',
            ')',
        ])
    foo_sh = self.ScratchFile('foo/foo.sh', [
        '#!/bin/bash',
        'echo hello shell',
        'echo runfiles_manifest_only=${RUNFILES_MANIFEST_ONLY:-}',
        'echo runfiles_manifest_file=${RUNFILES_MANIFEST_FILE:-}',
    ])
    foo_cmd = self.ScratchFile('foo/foo.cmd', ['@echo hello batch'])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])
    os.chmod(foo_sh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
    os.chmod(foo_cmd, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]

    self._buildShBinaryTargets(bazel_bin, ['--windows_exe_launcher=0'], '.cmd'
                               if self.IsWindows() else '')
    self._buildShBinaryTargets(bazel_bin, [], '.exe'
                               if self.IsWindows() else '')

  def testShBinaryArgumentPassing(self):
    self.ScratchFile('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'sh_binary(',
        '  name = "bin",',
        '  srcs = ["bin.sh"],',
        ')',
    ])
    foo_sh = self.ScratchFile('foo/bin.sh', [
        '#!/bin/bash',
        '# Store arguments in a array',
        'args=("$@")',
        '# Get the number of arguments',
        'N=${#args[@]}',
        '# Echo each argument',
        'for (( i=0;i<$N;i++)); do',
        ' echo ${args[${i}]}',
        'done',
    ])
    os.chmod(foo_sh, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]

    exit_code, _, stderr = self.RunBazel(
        ['build', '--windows_exe_launcher', '//foo:bin'])
    self.AssertExitCode(exit_code, 0, stderr)

    bin_suffix = '.exe' if self.IsWindows() else ''

    bin1 = os.path.join(bazel_bin, 'foo', 'bin%s' % bin_suffix)
    self.assertTrue(os.path.exists(bin1))
    self.assertTrue(
        os.path.isdir(
            os.path.join(bazel_bin, 'foo/bin%s.runfiles' % bin_suffix)))

    arguments = ['a', 'a b', '"b"', 'C:\\a\\b\\', '"C:\\a b\\c\\"']
    exit_code, stdout, stderr = self.RunProgram([bin1] + arguments)
    self.AssertExitCode(exit_code, 0, stderr)
    self.assertEqual(stdout, arguments)

  def testPyBinaryLauncher(self):
    self.ScratchFile('WORKSPACE')
    self.ScratchFile('foo/foo.bzl', [
        'def _impl(ctx):',
        '  ctx.actions.run(',
        '      arguments=[ctx.outputs.out.path],',
        '      outputs=[ctx.outputs.out],',
        '      executable=ctx.executable._hello_world,',
        '      use_default_shell_env=True)',
        '',
        'helloworld = rule(',
        '  implementation=_impl,',
        '  attrs={',
        '      "srcs": attr.label_list(allow_files=True),',
        '      "out": attr.output(mandatory=True),',
        '      "_hello_world": attr.label(executable=True, cfg="host",',
        '                                 allow_files=True,',
        '                                 default=Label("//foo:foo"))',
        '  }',
        ')',
    ])
    self.ScratchFile('foo/BUILD', [
        'load(":foo.bzl", "helloworld")', '', 'py_binary(', '  name = "foo",',
        '  srcs = ["foo.py"],', '  data = ["//bar:bar.txt"],', ')', '',
        'py_test(', '  name = "test",', '  srcs = ["test.py"],', ')', '',
        'helloworld(', '  name = "hello",', '  out = "hello.txt",', ')'
    ])
    foo_py = self.ScratchFile('foo/foo.py', [
        '#!/usr/bin/env python',
        'import sys',
        'if len(sys.argv) == 2:',
        '  with open(sys.argv[1], "w") as f:',
        '    f.write("Hello World!")',
        'else:',
        '  print("Hello World!")',
    ])
    test_py = self.ScratchFile('foo/test.py', [
        '#!/usr/bin/env python',
        'import unittest',
        'class MyTest(unittest.TestCase):',
        '  def test_dummy(self):',
        '      pass',
        'if __name__ == \'__main__\':',
        '  unittest.main()',
    ])
    self.ScratchFile('bar/BUILD', ['exports_files(["bar.txt"])'])
    self.ScratchFile('bar/bar.txt', ['hello'])
    os.chmod(foo_py, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
    os.chmod(test_py, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

    exit_code, stdout, stderr = self.RunBazel(['info', 'bazel-bin'])
    self.AssertExitCode(exit_code, 0, stderr)
    bazel_bin = stdout[0]

    self._buildPyTargets(bazel_bin, ['--windows_exe_launcher=0'], '.cmd'
                         if self.IsWindows() else '')
    self._buildPyTargets(bazel_bin, [], '.exe' if self.IsWindows() else '')

  def AssertRunfilesManifestContains(self, manifest, entry):
    with open(manifest, 'r') as f:
      for l in f:
        tokens = l.strip().split(' ', 1)
        if len(tokens) == 2 and tokens[0] == entry:
          return
    self.fail('Runfiles manifest "%s" did not contain "%s"' % (manifest, entry))

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


import ROOT
import os

folder1   = "input_jets01"
folder2   = "input_jets02"
folder3   = "input_jets12"
folderOut = "input_jetsij"

#folder1   = "input_jets01"
#folder2   = "input_jets01"
#folder3   = "input_jets01"
#folderOut = "input_jetsij_test3"

fileList = [
    "ResonanceShapes_qq_13TeV_CaloScouting_2016.root",
    "ResonanceShapes_qq_13TeV_CaloScouting_2016_JERDOWN.root",
    "ResonanceShapes_qq_13TeV_CaloScouting_2016_JERUP.root",
    "ResonanceShapes_qq_13TeV_CaloScouting_2016_JESDOWN.root",
    "ResonanceShapes_qq_13TeV_CaloScouting_2016_JESUP.root",
    "full.root"
]

def merge(fileName1,fileName2,fileName3,fileNameOut):
    print("#CALLING merge(%s,%s,%s,%s)"%(fileName1,fileName2,fileName3,fileNameOut))
    f1 = ROOT.TFile.Open(fileName1)
    f2 = ROOT.TFile.Open(fileName2)
    f3 = ROOT.TFile.Open(fileName3)
    fo = ROOT.TFile.Open(fileNameOut,"RECREATE")

    if "ResonanceShapes" in fileName1:
        data = False
    else:
        data = True
    dataFolder = "DijetFilter/dijetMassHisto"
    if data:
        fo.mkdir(dataFolder)
        for a in f1.Get(dataFolder).GetListOfKeys():
            obj1 = f1.Get(dataFolder).Get(a.GetName())
            obj2 = f2.Get(dataFolder).Get(a.GetName())
            obj3 = f3.Get(dataFolder).Get(a.GetName())
#            for obj in [obj1,obj2,obj3]:
#                obj.Sumw2()
#                obj.Scale(1./3)
            fo.cd(dataFolder)
            out = obj1.Clone(obj1.GetName())
            out.Add(obj2)
            out.Add(obj3)
            out.Write()
    else:
        for a in f1.GetListOfKeys():
            obj1 = f1.Get(a.GetName())
            obj2 = f2.Get(a.GetName())
            obj3 = f3.Get(a.GetName())
            for obj in [obj1,obj2,obj3]:
                obj.Sumw2()
                obj.Scale(1./3)
            fo.cd()
            out = obj1.Clone(obj1.GetName())
            out.Add(obj2)
            out.Add(obj3)
            out.Write()
    fo.Close()

for fil in fileList:
    fileName1   = folder1 + "/" + fil
    fileName2   = folder2 + "/" + fil
    fileName3   = folder3 + "/" + fil
    fileNameOut = folderOut + "/" + fil
    merge(fileName1,fileName2,fileName3,fileNameOut)


from path import path
import tempfile
import unittest
import yaml

class TestSiteConfig(unittest.TestCase):
    """
    """
    def setUp(self):
        self.tmpdir = path(tempfile.mkdtemp())

    def makeone(self, name):
        from marina.site import SiteConfig
        return SiteConfig(self.tmpdir / name)

    def test_siteconfig_gen(self):
        name = 'test1'
        sc = self.makeone(name)
        sc.generate()

        site = sc.path
        assert 'site.yml' in set(x.name for x  in site.files())
        assert 'nginx' in set(x.name for x  in site.dirs())
        siteyml = site / 'site.yml'
        assert siteyml.parent.exists()
        assert siteyml.text(), siteyml.text()
        with open(siteyml) as stream:
            data = yaml.load(stream)

        keys = set(('registry', 'dockers', 'services', 'name'))
        assert set(data.keys()) == keys, keys.difference(set(data.keys()))

    def tearDown(self):
        self.tmpdir.rmtree_p()


#######################################################################
#  File:      rbfopt.py
#  Author(s): Giacomo Nannicini
#             Singapore University of Technology and Design
#             nannicini@sutd.edu.sg
#  Date:      02/02/14
#
#  (C) Copyright Singapore University of Technology and Design 2014.
#  You should have received a copy of the license with this code.
#  Research supported by the SUTD-MIT International Design Center.
#######################################################################

from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import sys
import math
import random
import time
import copy
import itertools as it
import numpy as np
import rbfopt_utils as ru
import rbfopt_aux_problems as aux
import rbfopt_config as config

class RbfSettings:
    """
    Class containing algorithmic settings for the enhanced RBF method,
    as well as global settings such as tolerances, limits and so on.

    Parameters:
    ---

    rbf: radial basis function used by the method. Choice of 'cubic',
         'thin_plate_spline', 'linear', 'multiquadric',
         'auto'. Default 'cubic'.

    max_iterations: maximum number of iterations. Default 150.

    max_evaluations: maximum number of function evaluations in
                     accurate mode. This includes the evaluations to
                     initialize the algorithm. Default 250.

    max_fast_evaluations: maximum number of function evaluations in
                          fast mode. Default 150.

    max_clock_time: maximum wall clock time in seconds. Default 1.0e30.

    target_objval: the objective function value we want to reach,
                   i.e. the value of the unknown optimum. Useful for
                   testing purposes. Default -1.0e10.

    eps_opt: optimality threshold. Any solution within this relative
             distance from the target_objval is considered optimal.
             Default 1.0e-2.

    eps_zero: tolerance for zeroing out small coefficients in the
              calculations. Any value smaller than this will be
              considered zero. Default 1.0e-15.

    eps_impr: tolerance for improvement of the objective function. Any
              improvement in the objective function by less than this
              amount in absolute and relative terms, will be ignored.
              Default 1.0e-3.

    min_dist: minimum Euclidean distance between nodes. A new point
              will be discarded if it is closer than this value from
              existing nodes. This prevents the RBF pairwise distance
              matrix from becoming singular. Default 1.0e-5.

    do_infstep: Should we perform the InfStep? Default False.

    skip_targetval_clipping: Should we skip the method to clip target
                             value selection based on periodically
                             eliminating some of the largest function
                             values, as proposed by Gutmann (2001) and
                             later Regis and Shoemaker (2007)? Default
                             False.

    num_global_searches: number of steps in the global search phase.
                         Default 5.

    max_consecutive_local_searches: maximum number of consecutive
                                    local searches during the
                                    optimization phase. Default 2.

    init_strategy: strategy to select initial points. Choice of
                   'all_corners', 'lower_corners', 'rand_corners',
                   'lhd_maximin', 'lhd_corr'. Default 'lhd_maximin'

    function_scaling: rescaling method for the function values. Choice
                      of 'off', 'affine', 'log', 'auto'. Default 'auto'.

    domain_scaling: rescaling method for the domain. Choice of 'off',
                    'affine', 'auto'. Default 'auto'.

    dynamism_clipping: dynamism clipping strategy. Choice of 'off',
                       'median', 'clip_at_dyn', 'auto'. Default
                       'auto'.

    dynamism_threshold: minimum value of the ratio between the largest
                        and the smallest absolute function values
                        before the dynamism clipping strategy is
                        applied. Default 1.0e3.

    local_search_box_scaling: rescaling factor for the hyperbox used
                              for local search. See parameter nu of
                              Regis and Shoemaker (2007). Default 0.5.

    max_stalled_cycles: maximum number of consecutive optimization
                        cycles without improvement before we perform a
                        full restart. Default 6.

    max_stalled_objfun_impr: maximum relative objective function
                             improvement between consecutive
                             optimization cycles to be considered
                             "stalling". Default 0.05.

    fast_objfun_rel_error: an estimate of the relative error by which
                           the fast version of the objective function
                           is affected. Default 0.1.

    fast_objfun_abs_error: an estimate of the absolute error by which
                           the fast version of the objective function
                           is affected. Default 0.0.

    max_fast_restarts: maximum number of restarts in fast mode before
                       we switch to accurate mode. Default 2.

    max_fast_iterations: maximum number of iterations in fast mode
                         before switching to accurate mode. Default
                         100.

    print_solver_output: print the output of the solvers to
                         screen. Note that this cannot be redirected
                         to file so it will go to stdout. Default False.

    rand_seed: seed for the random number generator.
               Default 937627691.
    """

    # Allowed values for multiple choice options
    allowed_rbf = {'auto', 'cubic', 'thin_plate_spline', 'linear',
                   'multiquadric'}
    allowed_init_strategy = {'all_corners', 'lower_corners', 'rand_corners',
                             'lhd_maximin', 'lhd_corr'}
    allowed_function_scaling = {'off', 'affine', 'log', 'auto'}
    allowed_domain_scaling = {'off', 'affine', 'auto'}
    allowed_dynamism_clipping = {'off', 'median', 'clip_at_dyn', 'auto'}

    def __init__(self,
                 rbf = 'cubic',
                 max_iterations = 150,
                 max_evaluations = 250,
                 max_fast_evaluations = 150,
                 max_clock_time = 1.0e30,
                 target_objval = -1.0e10,
                 eps_opt = 1.0e-2,
                 eps_zero = 1.0e-15,
                 eps_impr = 1.0e-3,
                 min_dist = 1.0e-5,
                 do_infstep = False,
                 skip_targetval_clipping = False,
                 num_global_searches = 5,
                 max_consecutive_local_searches = 2,
                 init_strategy = 'lhd_maximin',
                 function_scaling = 'auto',
                 domain_scaling = 'off',
                 dynamism_clipping = 'auto',
                 dynamism_threshold = 1.0e3,
                 local_search_box_scaling = 0.5,
                 max_stalled_cycles = 6,
                 max_stalled_objfun_impr = 0.05,
                 fast_objfun_rel_error = 0.1,
                 fast_objfun_abs_error = 0.0,
                 max_fast_restarts = 2,
                 max_fast_iterations = 100,
                 print_solver_output = False,
                 rand_seed = 937627691):
        """
        Class constructor with default values. See list of parameters
        in the class description.
        """
        self.rbf = rbf
        self.max_iterations = max_iterations
        self.max_evaluations = max_evaluations
        self.max_fast_evaluations = max_fast_evaluations
        self.max_clock_time = max_clock_time
        self.target_objval = target_objval
        self.eps_opt = eps_opt
        self.eps_zero = eps_zero
        self.eps_impr = eps_impr
        self.min_dist = min_dist
        self.do_infstep = do_infstep
        self.skip_targetval_clipping = skip_targetval_clipping
        self.num_global_searches = num_global_searches
        self.max_consecutive_local_searches = max_consecutive_local_searches
        self.init_strategy = init_strategy
        self.function_scaling = function_scaling
        self.domain_scaling = domain_scaling
        self.dynamism_clipping = dynamism_clipping
        self.dynamism_threshold = dynamism_threshold
        self.local_search_box_scaling = local_search_box_scaling
        self.max_stalled_cycles = max_stalled_cycles
        self.max_stalled_objfun_impr = max_stalled_objfun_impr
        self.fast_objfun_rel_error = fast_objfun_rel_error
        self.fast_objfun_abs_error = fast_objfun_abs_error
        self.max_fast_restarts = max_fast_restarts
        self.max_fast_iterations = max_fast_iterations
        self.print_solver_output = print_solver_output
        self.rand_seed = rand_seed

        if (self.rbf not in RbfSettings.allowed_rbf):
            raise ValueError('settings.rbf = ' +
                             str(self.rbf) + ' not supported')
        if (self.init_strategy not in RbfSettings.allowed_init_strategy):
            raise ValueError('settings.init_strategy = ' +
                             str(self.init_strategy) + ' not supported')
        if (self.function_scaling not in RbfSettings.allowed_function_scaling):
            raise ValueError('settings.function_scaling = ' +
                             str(self.function_scaling) + ' not supported')
        if (self.domain_scaling not in RbfSettings.allowed_domain_scaling):
            raise ValueError('settings.domain_scaling = ' +
                             str(self.domain_scaling) + ' not supported')
        if (self.dynamism_clipping not in
            RbfSettings.allowed_dynamism_clipping):
            raise ValueError('settings.dynamism_clipping = ' +
                             str(self.dynamism_clipping) + ' not supported')

    def set_auto_parameters(self, dimension, var_lower, var_upper,
                            integer_vars):
        """
        Create a copy of the settings and assign 'auto' parameters. The
        original settings are untouched.

        Parameters
        ---

        dimension: the dimension of the problem, i.e. size of the space.
        var_lower: vector of variable lower bounds.
        var_upper: vector of variable upper bounds.
        integer_vars: a list containing the indices of the integrality
                      constrained variables. If None or empty list, all
                      variables are assumed to be continuous.

        Returns
        ---

        A copy of the settings, without any 'auto' parameter values.
        """
        assert(dimension==len(var_lower))
        assert(dimension==len(var_upper))
        assert((integer_vars is None) or (len(integer_vars) == 0) or
               (max(integer_vars) < dimension))

        l_settings = copy.deepcopy(self)

        if (l_settings.rbf == 'auto'):
            l_settings.rbf = 'cubic'

        if (l_settings.function_scaling == 'auto'):
            if (l_settings.rbf == 'linear'):
                l_settings.function_scaling = 'affine'
            else:
                l_settings.function_scaling = 'off'

        if (l_settings.dynamism_clipping == 'auto'):
            l_settings.dynamism_clipping = 'median'

        if (l_settings.domain_scaling == 'auto'):
            if (integer_vars is not None):
                l_settings.domain_scaling = 'off'
            else:
                # Compute the length of the domain of each variable
                size = [var_upper[i]-var_lower[i] for i in range(dimension)]
                size.sort()
                # If the problem is badly scaled, i.e. a variable has
                # a domain 5 times as large as anoether, rescale.
                if (size[-1] >= 5*size[0]):
                    l_settings.domain_scaling = 'affine'
                else:
                    l_settings.domain_scaling = 'off'

        return l_settings

    def print(self, output_stream):
        """
        Print the value of all settings.
        """
        print('RbfSettings:', file = output_stream)
        attrs = vars(self)
        print(', '.join('{:s}: {:s}'.format(str(item[0]), str(item[1]))
                        for item in sorted(attrs.items())),
              file = output_stream)
        print(file = output_stream)
        output_stream.flush()

# -- end of class RbfSettings

def rbf_optimize(settings, dimension, var_lower, var_upper, objfun,
                 objfun_fast = None, integer_vars = None,
                 init_node_pos = None, init_node_val = None,
                 output_stream = sys.stdout):
    """
    Optimize an unknown function over a box using the enhanced RBF
    method.

    Parameters
    ---

    settings: global and algorithmic settings (see class RbfSettings).

    dimension: the dimension of the problem, i.e. size of the space.

    var_lower: vector of variable lower bounds.

    var_upper: vector of variable upper bounds.

    objfun: the unknown function we want to optimize.

    objfun_fast: a faster, lower quality version of the unknown
                 function we want to optimize. If None, it is assumed
                 that such a version of the function is not available.

    integer_vars: a list containing the indices of the integrality
                  constrained variables. If None or empty list, all
                  variables are assumed to be continuous.

    init_node_pos: coordinates of points at which the function value
                   is known. If None, the initial points will be
                   generated by the algorithm. This must be of length
                   at least dimension + 1, if provided.

    init_node_val: function values corresponding to the points given
                   in init_node_pos. Should be None if the previous
                   argument is None.

    output_stream: a stream object that will be used to print
                   output. By default, this will be the standard
                   output stream.

    Returns
    ---

    A quintuple (value, point, itercount, evalcount, fast_evalcount)
    containing the objective function value of the best solution
    found, the corresponding value of the decision variables, the
    number of iterations of the algorithm, the total number of
    function evaluations, and the number of these evaluations that
    were performed in 'fast' mode.
    """

    assert(len(var_lower) == dimension)
    assert(len(var_upper) == dimension)
    assert((integer_vars is None) or (len(integer_vars) == 0) or
           (max(integer_vars) < dimension))
    assert(init_node_pos is None or
           (len(init_node_pos) == len(init_node_val) and
            len(init_node_pos) >= dimension + 1))
    assert(isinstance(settings, RbfSettings))

    # Start timing
    start_time = time.time()

    # Set the value of 'auto' parameters if necessary
    l_settings = settings.set_auto_parameters(dimension, var_lower,
                                              var_upper, integer_vars)

    # Local and global RBF models are usually the same
    best_local_rbf, best_global_rbf = l_settings.rbf, l_settings.rbf

    # We use n to denote the dimension of the problem, same notation
    # of the paper. This is redundant but it simplifies our life.
    n = dimension

    # Set random seed. Some of the (external) libraries use numpy's
    # random generator, we use python's internal generator, so we have
    # to seed both for consistency.
    random.seed(l_settings.rand_seed)
    np.random.seed(l_settings.rand_seed)

    # Iteration number
    itercount = 0

    # Total number of function evaluations in accurate mode
    evalcount = 0
    # Total number of fast function evaluation
    fast_evalcount = 0

    # Identifier of the current step within the cyclic optimization
    # strategy counter. This typically increases at every iteration,
    # but sometimes we may decide to repeat a step.
    current_step = 0

    # Current number of consecutive local searches
    num_cons_ls = 0

    # Number of consecutive cycles without improvement
    num_stalled_cycles = 0

    # Number of restarts in fast mode
    num_fast_restarts = 0

    # Initialize identifiers of the search steps
    inf_step = 0
    local_search_step = (l_settings.num_global_searches + 1)
    cycle_length = (l_settings.num_global_searches + 2)

    # Initialize settings for two-phase optimization.
    # two_phase_optimization indicates if the fast buy noisy objective
    # function is available.
    # is_best_fast indicates if the best known objective function
    # value was evaluated in fast mode or in accurate mode.
    # current_mode indicates the evaluation mode for the objective
    # function at a given stage.
    if (objfun_fast is not None):
        two_phase_optimization = True
        is_best_fast = True
        current_mode = 'fast'
    else:
        two_phase_optimization = False
        is_best_fast = False
        current_mode = 'accurate'

    # Round variable bounds to integer if necessary
    ru.round_integer_bounds(var_lower, var_upper, integer_vars)

    # List of node coordinates is node_pos, list of node values is in
    # node_val. We keep a current list and a global list; they can be
    # different in case of restarts.

    # We must choose the initial interpolation points. If they are not
    # given, generate them using the chosen strategy.
    if (init_node_pos is None):
        node_pos = ru.initialize_nodes(l_settings, var_lower, var_upper,
                                       integer_vars)
        if (current_mode == 'accurate'):
            node_val = [objfun(point) for point in node_pos]
            evalcount += len(node_val)
        else:
            node_val = [objfun_fast(point) for point in node_pos]
            fast_evalcount += len(node_val)
        node_is_fast = [current_mode == 'fast' for val in node_val]
    else:
        node_pos = init_node_pos
        node_val = init_node_val
        # We assume that initial points provided by the user are
        # 'accurate'.
        node_is_fast = [False for val in node_val]

    # Make a copy, in the original space
    all_node_pos = [point for point in node_pos]
    all_node_val = [val for val in node_val]
    # Store if each function evaluation is fast or accurate
    all_node_is_fast = [val for val in node_is_fast]
    # We need to remember the index of the first node in all_node_pos
    # after every restart
    all_node_pos_size_at_restart = 0

    # Rescale the domain of the function
    node_pos = [ru.transform_domain(l_settings, var_lower, var_upper, point)
                for point in node_pos]

    (l_lower,
     l_upper) = ru.transform_domain_bounds(l_settings, var_lower, var_upper)

    # Current minimum value among the nodes, and its index
    fmin_index = node_val.index(min(node_val))
    fmin = node_val[fmin_index]
    # Current maximum value among the nodes
    fmax = max(all_node_val)
    # Denominator of errormin
    gap_den = (abs(l_settings.target_objval)
               if (abs(l_settings.target_objval) >= l_settings.eps_zero)
               else 1.0)
    # Shift due to fast function evaluation
    gap_shift = (ru.get_fast_error_bounds(l_settings, fmin)[1]
                 if is_best_fast else 0.0)
    # Current minimum distance from the optimum
    gap = ((fmin + gap_shift - l_settings.target_objval)/gap_den)

    # Best value function at the beginning of an optimization cycle
    fmin_cycle_start = fmin

    # Print the initialization points
    for (i, val) in enumerate(node_val):
        min_dist = ru.get_min_distance(node_pos[i], node_pos[:i] +
                                       node_pos[(i+1):])
        print('Iteration {:3d}'.format(itercount) +
              ' {:16s}'.format('Initialization') +
              ': objval{:s}'.format('~' if node_is_fast[i] else ' ') +
              ' {:16.6f}'.format(val) +
              ' min_dist {:9.4f}'.format(min_dist) +
              ' gap {:8.2f}'.format(gap*100),
              file = output_stream)

    # Main loop
    while (itercount < l_settings.max_iterations and
           evalcount < l_settings.max_evaluations and
           time.time() - start_time < l_settings.max_clock_time and
           gap > l_settings.eps_opt):
        # Number of nodes at current iteration
        k = len(node_pos)

        # Compute indices of fast node evaluations (sparse format)
        fast_node_index = ([i for (i, val) in enumerate(node_is_fast) if val]
                           if two_phase_optimization else list())

        # Rescale nodes if necessary
        (scaled_node_val, scaled_fmin, scaled_fmax,
         node_err_bounds) = ru.transform_function_values(l_settings, node_val,
                                                         fmin, fmax,
                                                         fast_node_index)

        # If selection is automatic, at the beginning of each cycle
        # check if a different RBF yields a better model
        if (settings.rbf == 'auto' and k > n+1 and current_step == inf_step):
            best_local_rbf = ru.get_best_rbf_model(l_settings, n, k, node_pos,
                                                   scaled_node_val,
                                                   int(math.ceil(k*0.1)))
            best_global_rbf = ru.get_best_rbf_model(l_settings, n, k, node_pos,
                                                    scaled_node_val,
                                                    int(math.ceil(k*0.7)))
        # If we are in local search or just before local search, use a
        # local model.
        if (current_step >= (local_search_step - 1)):
            l_settings.rbf = best_local_rbf
        # Otherwise, global.
        else:
            l_settings.rbf = best_global_rbf

        # Compute the matrices necessary for the algorithm
        Amat = ru.get_rbf_matrix(l_settings, n, k, node_pos)
        Amatinv = ru.get_matrix_inverse(l_settings, Amat)
        # Compute RBF interpolant at current stage
        if (fast_node_index):
            # Get coefficients for the exact RBF
            (rbf_l, rbf_h) = ru.get_rbf_coefficients(l_settings, n, k,
                                                     Amat, scaled_node_val)
            # RBF with some fast function evaluations
            (rbf_l, rbf_h) = aux.get_noisy_rbf_coefficients(l_settings, n, k,
                                                            Amat[:k, :k],
                                                            Amat[:k, k:],
                                                            scaled_node_val,
                                                            fast_node_index,
                                                            node_err_bounds,
                                                            rbf_l, rbf_h)
        else:
            # Fully accurate RBF
            (rbf_l, rbf_h) = ru.get_rbf_coefficients(l_settings, n, k,
                                                     Amat, scaled_node_val)

        # For displaying purposes, record what type of iteration we
        # are performing
        iteration_id = ''

        # Initialize the new point to None
        next_p = None

        if (current_step == inf_step):
            # If the user wants to skip inf_step as in the original
            # paper of Gutmann (2001), we proceed to the next
            # iteration.
            if (not l_settings.do_infstep):
                current_step = (current_step+1) % cycle_length
                continue
            # Infstep: explore the parameter space
            next_p = aux.maximize_one_over_mu(l_settings, n, k, l_lower,
                                              l_upper, node_pos, Amatinv,
                                              integer_vars)
            iteration_id = 'InfStep'

        elif (current_step == local_search_step):
            # Local search: compute the minimum of the RBF.
            min_rbf = aux.minimize_rbf(l_settings, n, k, l_lower,
                                       l_upper, node_pos,
                                       rbf_l, rbf_h, integer_vars)
            if (min_rbf is not None):
                min_rbf_val = ru.evaluate_rbf(l_settings, min_rbf, n, k,
                                              node_pos, rbf_l, rbf_h)
            # If the RBF cannot me minimized, or if the minimum is
            # larger than the node with smallest value, just take the
            # node with the smallest value.
            if (min_rbf is None or
                (min_rbf_val >= scaled_fmin + l_settings.eps_zero)):
                min_rbf = node_pos[fmin_index]
                min_rbf_val = scaled_fmin
            # Check if point can be accepted: is there an improvement?
            if (min_rbf_val <= (scaled_fmin - l_settings.eps_impr *
                                max(1.0, abs(scaled_fmin)))):
                target_val = min_rbf_val
                next_p = min_rbf
                iteration_id = 'LocalStep'
            else:
                # If the point is not improving, we solve a global
                # search problem, rescaling the search box to enforce
                # some sort of local search
                target_val = scaled_fmin - 0.01*max(1.0, abs(scaled_fmin))
                local_varl = [max(l_lower[i], min_rbf[i] -
                                  l_settings.local_search_box_scaling *
                                  0.33 * (l_upper[i] - l_lower[i]))
                              for i in range(n)]
                local_varu = [min(l_upper[i], min_rbf[i] +
                                  l_settings.local_search_box_scaling *
                                  0.33 * (l_upper[i] - l_lower[i]))
                              for i in range(n)]
                ru.round_integer_bounds(local_varl, local_varu,
                                        integer_vars)
                next_p  = aux.maximize_h_k(l_settings, n, k, local_varl,
                                           local_varu, node_pos, rbf_l,
                                           rbf_h, Amatinv, target_val,
                                           integer_vars)
                iteration_id = 'AdjLocalStep'

        else:
            # Global search: compromise between finding a good value
            # of the objective function, and improving the model.
            # Choose target value for the objective function. To do
            # so, we need the minimum of the RBF interpolant.
            min_rbf = aux.minimize_rbf(l_settings, n, k, l_lower,
                                       l_upper, node_pos,
                                       rbf_l, rbf_h, integer_vars)
            if (min_rbf is not None):
                min_rbf_val = ru.evaluate_rbf(l_settings, min_rbf, n, k,
                                              node_pos, rbf_l, rbf_h)
            # If the RBF cannot me minimized, or if the minimum is
            # larger than the node with smallest value, just take the
            # node with the smallest value.
            if (min_rbf is None or
                min_rbf_val >= scaled_fmin + l_settings.eps_zero):
                min_rbf = node_pos[fmin_index]
                min_rbf_val = scaled_fmin
            # The scaling factor is 1 - h/kappa, where h goes from
            # 0 to kappa-1 over the course of one global search
            # cycle, and kappa is the number of global searches.
            scaling = (1 - ((current_step - 1) /
                            l_settings.num_global_searches))**2
            # Compute the function value used to determine the
            # target value. This is given by the sorted value in
            # position sigma_n, where sigma_n is a function
            # described in the paper by Gutmann (2001). Unless we
            # want to skip this approach.
            if (l_settings.skip_targetval_clipping):
                local_fmax = fmax
            else:
                local_fmax = ru.get_fmax_current_iter(l_settings, n, k,
                                                      current_step,
                                                      scaled_node_val)
            target_val = (min_rbf_val -
                          scaling * (local_fmax - min_rbf_val))

            # If the global search is almost a local search, we
            # restrict the search to a box following Regis and
            # Shoemaker (2007)
            if (scaling <= config.LOCAL_SEARCH_THRESHOLD):
                local_varl = [max(l_lower[i], min_rbf[i] -
                                  l_settings.local_search_box_scaling *
                                  math.sqrt(scaling) *
                                  (l_upper[i] - l_lower[i]))
                              for i in range(n)]
                local_varu = [min(l_upper[i], min_rbf[i] +
                                  l_settings.local_search_box_scaling *
                                  math.sqrt(scaling) *
                                  (l_upper[i] - l_lower[i]))
                              for i in range(n)]
                ru.round_integer_bounds(local_varl, local_varu,
                                        integer_vars)
            # Otherwise, use original bounds
            else:
                local_varl = l_lower
                local_varu = l_upper

            next_p  = aux.maximize_h_k(l_settings, n, k, local_varl,
                                       local_varu, node_pos, rbf_l,
                                       rbf_h, Amatinv, target_val,
                                       integer_vars)
            iteration_id = 'GlobalStep'

        # -- end if

        # If previous points were evaluated in low quality and we are
        # now in high-quality local search mode, then we should verify
        # if it is better to evaluate a brand new point or re-evaluate
        # a previously known point.
        if ((two_phase_optimization == True) and
            (current_step == local_search_step) and
            (current_mode == 'accurate')):
            (ind, bump) = ru.get_min_bump_node(l_settings, n, k, Amat,
                                               scaled_node_val,
                                               fast_node_index,
                                               node_err_bounds, target_val)

            if (ind is not None and next_p is not None):
                # Check if the newly proposed point is very close to
                # an existing one.
                if (ru.get_min_distance(next_p, node_pos) >
                    l_settings.min_dist):
                    # If not, compute bumpiness of the newly proposed point.
                    n_bump = ru.get_bump_new_node(l_settings, n, k, node_pos,
                                                  scaled_node_val, next_p,
                                                  fast_node_index,
                                                  node_err_bounds, target_val)
                else:
                    # If yes, we will simply reevaluate the existing
                    # point (if it can be reevaluated).
                    ind = ru.get_min_distance_index(next_p, node_pos)
                    n_bump = (float('inf') if node_is_fast[ind]
                              else float('-inf'))
                if (n_bump > bump):
                    # In this case we want to put the new point at the
                    # same location as one of the old points.  Remove
                    # the noisy function evaluation from the data
                    # structures, so that the point can be evaluated
                    # in accurate mode.
                    next_p = node_pos.pop(ind)
                    node_val.pop(ind)
                    node_is_fast.pop(ind)
                    all_node_pos.pop(all_node_pos_size_at_restart + ind)
                    all_node_val.pop(all_node_pos_size_at_restart + ind)
                    all_node_is_fast.pop(all_node_pos_size_at_restart + ind)
                    # We must update k here to make sure it is consistent
                    # until the start of the next iteration.
                    k = len(node_pos)

        # If the optimization failed or the point is too close to
        # current nodes, discard it. Otherwise, add it to the list.
        if ((next_p is None) or
            (ru.get_min_distance(next_p, node_pos) <= l_settings.min_dist)):
            current_step = (current_step+1) % cycle_length
            num_cons_ls = 0
            print('Iteration {:3d}'.format(itercount) + ' Discarded',
                  file = output_stream)
            output_stream.flush()
        else:
            min_dist = ru.get_min_distance(next_p, node_pos)
            # Transform back to original space if necessary
            next_p_orig = ru.transform_domain(l_settings, var_lower,
                                              var_upper, next_p, True)
            # Evaluate the new point, in accurate mode or fast mode
            if (current_mode == 'accurate'):
                next_val = objfun(next_p_orig)
                evalcount += 1
                node_is_fast.append(False)
            else:
                next_val = objfun_fast(next_p_orig)
                fast_evalcount += 1
                # Check if the point could be optimal in accurate
                # mode. In that case, perform an accurate evaluation
                # immediately. Otherwise, add to the list of fast
                # evaluations.
                if ((next_val +
                     ru.get_fast_error_bounds(l_settings, next_val)[0]) <=
                    (l_settings.target_objval +
                     l_settings.eps_opt*abs(l_settings.target_objval))):
                    next_val = objfun(next_p_orig)
                    evalcount += 1
                    node_is_fast.append(False)
                else:
                    node_is_fast.append(True)

            # Add to the lists
            node_pos.append(next_p)
            node_val.append(next_val)
            all_node_pos.append(next_p_orig)
            all_node_val.append(next_val)
            all_node_is_fast.append(node_is_fast[-1])

            if ((current_step == local_search_step) and
                (next_val <= fmin - l_settings.eps_impr*max(1.0,abs(fmin))) and
                (num_cons_ls < l_settings.max_consecutive_local_searches - 1)):
                # Keep doing local search
                num_cons_ls += 1
            else:
                current_step = (current_step+1) % cycle_length
                num_cons_ls = 0

            # Update fmin
            if (next_val < fmin):
                fmin_index = k
                fmin = next_val
                is_best_fast = node_is_fast[-1]
            fmax = max(fmax, next_val)
            # Shift due to fast function evaluation
            gap_shift = (ru.get_fast_error_bounds(l_settings, next_val)[1]
                         if is_best_fast else 0.0)
            gap = min(gap, (next_val + gap_shift - l_settings.target_objval) /
                      gap_den)

            print('Iteration {:3d}'.format(itercount) +
                  ' {:16s}'.format(iteration_id) +
                  ': objval{:s}'.format('~' if node_is_fast[-1] else ' ') +
                  ' {:16.6f}'.format(next_val) +
                  ' min_dist {:9.4f}'.format(min_dist) +
                  ' gap {:8.2f}'.format(gap*100),
                  file = output_stream)
            output_stream.flush()

        # Update iteration number
        itercount += 1

        # At the beginning of each loop of the cyclic optimization
        # strategy, check if the main loop is stalling
        if (current_step == inf_step or
            ((not l_settings.do_infstep) and current_step == inf_step + 1)):
            if (fmin <= (fmin_cycle_start- l_settings.max_stalled_objfun_impr *
                         max(1.0, abs(fmin_cycle_start)))):
                num_stalled_cycles = 0
                fmin_cycle_start = fmin
            else:
                num_stalled_cycles += 1

        # Check if we should restart. We only restart if the initial
        # sampling strategy is random, otherwise it makes little sense.
        if (num_stalled_cycles >= l_settings.max_stalled_cycles and
            evalcount + n + 1 < l_settings.max_evaluations and
            l_settings.init_strategy != 'all_corners' and
            l_settings.init_strategy != 'lower_corners'):
            print('Restart at iteration {:3d}'.format(itercount),
                  file = output_stream)
            output_stream.flush()
            # We update the number of fast restarts here, so that if
            # we hit the limit on fast restarts, we can evaluate
            # points in accurate mode after restarting (even if
            # current_mode is updated in a subsequent block of code)
            num_fast_restarts += (1 if current_mode == 'fast' else 0.0)
            # Store the current number of nodes
            all_node_pos_size_at_restart = len(all_node_pos)
            # Compute a new set of starting points
            node_pos = ru.initialize_nodes(l_settings, var_lower, var_upper,
                                           integer_vars)
            if (current_mode == 'accurate' or
                num_fast_restarts > l_settings.max_fast_restarts or
                fast_evalcount + n + 1 >= l_settings.max_fast_evaluations):
                node_val = [objfun(point) for point in node_pos]
                evalcount += len(node_val)
            else:
                node_val = [objfun_fast(point) for point in node_pos]
                fast_evalcount += len(node_val)
            node_is_fast = [current_mode == 'fast' for val in node_val]
            # Print the initialization points
            for (i, val) in enumerate(node_val):
                min_dist = ru.get_min_distance(node_pos[i], node_pos[:i] +
                                               node_pos[(i+1):])
                print('Iteration {:3d}'.format(itercount) +
                      ' {:16s}'.format('Initialization') +
                      ': objval{:s}'.format('~' if node_is_fast[i] else ' ') +
                      ' {:16.6f}'.format(val) +
                      ' min_dist {:9.4f}'.format(min_dist) +
                      ' gap {:8.2f}'.format(gap*100),
                      file = output_stream)
            all_node_pos.extend(node_pos)
            all_node_val.extend(node_val)
            all_node_is_fast.extend(node_is_fast)
            # Rescale the domain of the function
            node_pos = [ru.transform_domain(l_settings, var_lower,
                                            var_upper, point)
                        for point in node_pos]
            (l_lower, l_upper) = ru.transform_domain_bounds(l_settings,
                                                            var_lower,
                                                            var_upper)
            # Update all counters and values to restart properly
            fmin_index = node_val.index(min(node_val))
            fmin = node_val[fmin_index]
            fmax = max(node_val)
            fmin_cycle_start = fmin
            num_stalled_cycles = 0

        # Check if we should switch to the second phase of two-phase
        # optimization. The conditions for switching are:
        # 1) Optimization in fast mode restarted too many times.
        # 2) We reached the limit of fast mode iterations.
        if ((two_phase_optimization == True) and (current_mode == 'fast') and
            ((num_fast_restarts > l_settings.max_fast_restarts) or
             (itercount >= l_settings.max_fast_iterations) or
             (fast_evalcount >= l_settings.max_fast_evaluations))):
            print('Switching to accurate mode ' +
                  'at iteration {:3d}'.format(itercount),
                  file = output_stream)
            output_stream.flush()
            current_mode = 'accurate'

    # -- end while

    # Find best point and return it
    i = all_node_val.index(min(all_node_val))
    fmin = all_node_val[i]
    gap_shift = (ru.get_fast_error_bounds(l_settings, fmin)[1]
                   if all_node_is_fast[i] else 0.0)
    gap = ((fmin + gap_shift - l_settings.target_objval) / gap_den)

    print('Summary: iterations {:3d}'.format(itercount) +
          ' evaluations {:3d}'.format(evalcount) +
          ' fast_evals {:3d}'.format(fast_evalcount) +
          ' clock time {:7.2f}'.format(time.time() - start_time) +
          ' objval{:s}'.format('~' if (all_node_is_fast[i]) else ' ') +
          ' {:15.6f}'.format(fmin) +
          ' gap {:6.2f}'.format(100*gap),
          file = output_stream)
    output_stream.flush()

    return (all_node_val[i], all_node_pos[i],
            itercount, evalcount, fast_evalcount)


import scipy as sci
import pylab as plt
import scipy.linalg as linalg

N=200                    # number of particles
def Vp(r):              # 1st derivative
    vp=-1./r**2         # repulsive 1/r potential
    #vp=-0.5/r**2       # wrong repulsive 1/r potential: forgotten factor of 2 from pairwise sum
    return vp

def Vpp(r):             # 2nd derivative
    vp=2./r**3          # repulsive 1/r potential
    #vp=1/r**3          # wrong repulsive 1/r potential: forgotten factor of 2 from pairwise sum
    return vp

def dV(x, n):
    # grad(V) for particle n
    # harmonic external potential
    res = sci.copy(x[n])
    # pairwise interaction, derivative V'
    for i in range(x.shape[0]):
        if i != n:
            v = x[n] - x[i]
            d = abs(v)
            res +=Vp(d)*v/d
    return res

def grad(x):
    #grad(V) for all particles x: [[x1],[x2],..]
    res = sci.zeros(x.shape)
    for i in range(x.shape[0]):
        res[i] = dV(x, i)
    return res

def J(x):
    # Jacobian (N)x(N) (Hessian of the potential)
    # x1,x2,x3,x4,...
    jac = sci.eye(N)
    jac = -jac
    for i in range(N):
        for j in range(i):
            r = x[i]-x[j]
            d = abs(r)
            ww=Vp(d)/d
            wwp=Vpp(d)-ww
            jxx = -ww - wwp*r[0]**2/d**2
            jac[i,i]   += jxx		# df_xi/dxi
            jac[i,j]	 -= jxx		# df_xi/dxj
            jac[j,j]   += jxx		# df_xi/dxi
            jac[j,i]	 -= jxx		# df_xi/dxj
    return jac

def newton(x,delta = 1.,eps =  1e-6):
    # delta: maximal length of shift vector
    # eps: convergence criterion
    j = J(x)
    f = -grad(x)
    f = f.reshape(N)
    dx = sci.linalg.solve(j,f)
    shift=sci.sqrt(sci.dot(dx,dx))
    factor=delta/(delta+shift)
    dx = dx.reshape(N,1)
    x -= factor*dx
    if (shift>eps):
        return False
    return True

xpos=[]
if N==1:
    xpos[0]=0
elif N==2:
    x0=(1/4)**(1/3)  # analytically obtained equilibrium positions
    xpos.append(-x0)
    xpos.append(x0)
#    xpos[1]= x0
elif N==3:
    x0=(5/4)**(1/3) # analytically obtained equilibrium positions
    xpos.append(-x0)
    xpos.append(  0)
    xpos.append(x0)

# Set initial positions, uniformly distributed:
wid=sci.sqrt(N)                 # range for initial conditions
x=sci.linspace(-wid,wid,N)      # linear spacing as a single vector
x=wid*(2*sci.rand(N)-1)             # random initial conditions
x=x.reshape(N,1)                # ... reshaped as array of arrays

print(" Initial positions\n",x)      # print initial condtion

plt.figure()
basevect=sci.ones(N)                 # time = number of iterates
plt.plot(0*basevect,x,'x')
plt.xlabel('Number of iterates')
plt.ylabel('Position')

# First part: Approximate equilibrium with a gradient method
l = 0.05                    # stepsize for gradient method
#l = 0.5                    # stepsize for gradient method set too large for test purposes
nmax = 1000                     # maximum number of iterations
converged = False
i = 0
while i < nmax and converged == False:
#    print(i,sci.transpose(x))   # old position
    i += 1                      # update counter
    d = grad(x)                 # compute gradient
    dl=d.reshape(N)
    dlf=sci.sqrt(sci.dot(dl,dl)) # length of gradient
    fac=l/(l+dlf)               # limit gradient step in length < l
    x -= fac*d                  # update position

    converged = True            # check convergence
    if sci.any(abs(d) > 1e-1):
        converged = False

    tcurrent=i*basevect         # nr of iterates
    plt.plot(tcurrent,x, '.r')  # add current positions

print ("\n Number of gradient-iterations: {0}".format(i))
print ("\n Value of gradients \n",grad(x))
print ("\n Positions after gradient iteration: \n",x)
print()

tNewton=(i+1)*basevect          # result from Newton= i(gradient)+1 for later
plt.xlim(-0.5,i+1.5)            # set xrange for plot
plt.ylim(-1.5*wid,1.5*wid)      # set yrange for plot
plt.plot(tcurrent,x, 'v')       # change symbol of last position

# By applying a few Newton steps we improve positions
converged = False
i = 0
while (i < nmax and converged == False):
  i += 1
  converged = newton(x,delta=.1) # apply Newton steps up to nmax or convergence

print ("\n Number of Newton-iterations: {0}".format(i))
print("\n Positions after Newton iteration: \n",x)

# print analytical solution for N < 4:
if N<4:
    print("\n Exact positions:\n",xpos)

print("\nGradients after Newton iteration:")
plt.title('Gradient method + Newton method')
print (grad(x))

plt.plot(tNewton,x,'sg')   # show position after Newton

# determine stability of equilibria:

j = J(x)
ew,ev = sci.linalg.eigh(j)              # determine eigenvalues of Jacobian
                                        # linalg.eigh returns eigenvalues and eigenvectors of symmetric (applicable here) or Hermitian matrix

print ("\nEigenvalues:")                # print eigenvalues
print (ew)

plt.figure()    # new figure for eigenmodes

for l in range(x.shape[0]):
    print(l,ew[l], ev[:,l])             # print eigenvalue and eigenvector
#    ypos=(l+1)*basevect                     # y-position for
    ypos=-ew[l]*basevect                     # y-position for
    plt.plot(x,ypos,'ob')               # .. particle positions
    plt.quiver(x,ypos,ev[:,l].reshape(N),0*ypos,scale=8) # & eigenvectors

plt.xlim(-3, 3)
plt.ylim(ymin=0)
plt.xlabel('Position')
plt.ticklabel_format(style='plain')
plt.ylabel('$\omega^2$')
plt.title('Eigenmodes')
plt.show()


from dataAccess.baseDA import BaseDA
from dataAccess.connectionmanagment import ConnectionManagment
from entities.product import Product

class ProductDA(BaseDA):

    def findAll(self):

        conn = ConnectionManagment.getConnection()

        cursor = conn.cursor()
        sql = 'select * from product'
        cursor.execute(sql)
        data = cursor.fetchall()

        conn.commit()
        conn.close

        productList = []
        for item in data:
            product = Product(item[0], item[1], item[2], item[3])
            productList.append(product)

        return productList

    def findById(self, id):

        conn = ConnectionManagment.getConnection()

        cursor = conn.cursor()
        tupleId = (id,)
        sql = 'select * from product where product_id = %s'
        cursor.execute(sql, tupleId)

        item = cursor.fetchone()

        conn.commit()
        conn.close

        try:
            product = Product(item[0], item[1], item[2], item[3])
        except:
            product = Product(None, None, None, None)

        return product

    def delete(self, id):

        conn = ConnectionManagment.getConnection()

        cursor = conn.cursor()
        tupleId = (id,)
        sql = 'delete from product where product_id = %s'
        cursor.execute(sql, tupleId)

        conn.commit()
        conn.close

        if cursor.rowcount > 0:
            return True
        else:
            return False

    def save(self, product):

        conn = ConnectionManagment.getConnection()

        cursor = conn.cursor()
        tuple_product = (product.id, product.desc, product.product_class, product.price)
        sql = 'insert into product (product_id,product_desc,product_class,price) values(%s,%s,%s)'
        cursor.execute(sql, tuple_product)

        conn.commit()
        conn.close

        if cursor.rowcount > 0:
            return True
        else:
            return False

    # product price update
    def update(self, id, data):

        conn = ConnectionManagment.getConnection()

        cursor = conn.cursor()
        sql = 'UPDATE product SET price = %s where product_id = %s'
        tuple_update = (data, id)
        cursor.execute(sql, tuple_update)

        conn.commit()
        conn.close

        if cursor.rowcount > 0:
            return True
        else:
            return False


#!/usr/bin/env python

"""
Wed Oct 26 17:11:41 EEST 2016, Nikos Koukis
Compute the transformation of the roof cameras wrt the workspace origin.

"""

import re
import os

import rospy
import tf2_ros
from geometry_msgs.msg import TransformStamped

class MultiRobotBroadcaster:
    def __init__(self):
        self._broadcaster = tf2_ros.TransformBroadcaster()

        self.gt_ns = "ground_truth"
        self._get_ros_server_parameters()

        self.lcamera_frame_ID = "left_camera"
        self.rcamera_frame_ID = "right_camera"

        self.lcamera_ns = "/ar_multi_boards_top_left/"
        self.rcamera_ns = "/ar_multi_boards_top_right/"

        self._init_subscribers_publishers()

    def _init_subscribers_publishers(self):
        """Subscribe to the transforms as published by ArSys and push them to
        the /tf topic.

        """
        rospy.Subscriber(self.lcamera_ns + "transform",
                         TransformStamped, self._handle_incoming_transform)
        rospy.Subscriber(self.rcamera_ns + "transform",
                         TransformStamped, self._handle_incoming_transform)

    def _get_ros_server_parameters(self):
        """
        Read the necessary for the current node parameters from the ROS
        parameter server.

        """

        # Fetch the origin marker
        origin_marker_ID_param = "{}/origin_marker_ID".format(self.gt_ns)
        assert rospy.has_param(origin_marker_ID_param), "{} doesn't exist. Please set this first and rerun node.  Exiting...\n".format(origin_marker_ID_param)
        self.stat_marker_frame_ID = rospy.get_param(origin_marker_ID_param)
        self.stat_marker_frame_ID.lstrip("/")
        assert(self.stat_marker_frame_ID[0:2] == "mf")

    def _handle_incoming_transform(self, incoming_tf):
        """Send to the TF topic the incoming geometry_msgs.TransformStamped.

        Make sure that the origin marker_ID is the parent of the camera frames
        by reversing the child and parent frames in case the origin marker is
        involved in the transformation

        """

        # Revert the frame IDs so that the stat_marker_frame_ID is the
        # top-level frame
        if incoming_tf.child_frame_id == self.stat_marker_frame_ID:
            # Basic data are the same
            outgoing_tf = TransformStamped()
            outgoing_tf.header.seq = incoming_tf.header.seq
            outgoing_tf.header.stamp = incoming_tf.header.stamp

            # Stap the parent and child frames
            outgoing_tf.child_frame_id = incoming_tf.header.frame_id
            outgoing_tf.header.frame_id = incoming_tf.child_frame_id

            # Translation
            outgoing_tf.transform.translation = incoming_tf.transform.translation
            outgoing_tf.transform.rotation = incoming_tf.transform.rotation

        else:
            outgoing_tf = incoming_tf

        self._broadcaster.sendTransform(outgoing_tf)

    def run(self):
        rate = rospy.Rate(10.0)

        while not rospy.is_shutdown():
                rate.sleep()

def main():
    node_name = "tf2_broadcaster"
    print("Initializing node \"{}\"...".format(node_name))
    rospy.init_node(node_name)

    br = MultiRobotBroadcaster()
    print("{}: Initialized!".format(node_name))
    br.run()

if __name__ == "__main__":
    main()


'''
Created on 2015-08-17

@author: Magee_yang
'''
import os.path
import wx
import config

import time
from wx import BMP_1BPP

try:
    from collections import OrderedDict
except ImportError:
    from utils.compat import OrderedDict

cachedBitmapsCount = 0
cachedBitmaps = OrderedDict()
dontUseCachedBitmaps = False

locationMap = {"pack":os.path.join(config.datePath,"icons"),
               "ships":os.path.join(config.datePath,"icons/ships")}

def stripPath(fname):
    fname = fname.split('/')[-1]
    fname = fname.split('.',1)[0]
    return fname

def getImage(name,location):
    if location in locationMap:
        if location =="pack":
            location = locationMap[location]
            name = stripPath(name)
            filename = "icon{0}.png".format(name)
            path = os.path.join(location,filename)
        else:
            location = locationMap[location]
            filename = "{0}.png".format(name)
            path = os.path.join(location,filename)
    else:
        location = os.path.join(config.eitPath,location)
        filename = "{0}.png".format(name)
        path = os.path.join(location,filename)
    if os.path.exists(path):
        return wx.Image(path)
    else:
        print("Missing icon file: {0}".format(path))

def getBitmap(name,location):
    global cachedBitmaps
    global cachedBitmapsCount
    global dontUseCachedBitmaps

    if dontUseCachedBitmaps:
        img = getImage(name, location)
        if img is not None:
            return img.ConvertToBitmap()

    path = "%s%s" % (name,location)
    MAX_BMPS = 500
    if cachedBitmapsCount == MAX_BMPS:
        cachedBitmaps.popitem(False)
        cachedBitmapsCount -= 1

    if path  not in cachedBitmaps:
        img = getImage(name, location)
        if img is not None:
            bmp = img.ConvertToBitmap()
        else:
            bmp = None
        cachedBitmaps[path]=bmp
        cachedBitmapsCount += 1
    else:
        bmp = cachedBitmaps[path]
    return bmp


import sqlite3
import random
from nltk import sent_tokenize
from nltk import word_tokenize
from reset_db import ResetDb

class WikiGetSentence(object):
    def __init__(self, f_data="/home/mukhlis/machine_learning_nlp"):
        self.filepath = f_data
        try:
            self._db_connection = sqlite3.connect(self.filepath)
            self._db_cur = self._db_connection.cursor()
        except Error as e:
            print(e)

    def query(self, query, params=""):
        return self._db_cur.execute(query, params)

    def generate_list(self, tabel, ukuran, max_count):
        ukur = 0
        daftar_id = []
        toks = []
        l = list(range(max_count))
        random.shuffle(l)
        print("randomize...")
        a = ""
        indeks = 0
        while ((indeks < max_count) and (ukur <= ukuran)):
            self._db_cur.execute(
                "select id,dokumen, ukuran from {df_tabel} where id = {df_acak}+1".format(df_tabel=tabel,
                                                                                df_acak=l[indeks]))
            (id_nya, dokumen, ukuran_data) = self._db_cur.fetchone()
            # select limit 1 offset acak
            # ambil id dan ukuran_data
            daftar_id.append(id_nya)
            toks.append(dokumen.replace('\n', ' '))
            ukur = ukur + ukuran_data
            indeks = indeks + 1
            if indeks % 2000 == 0:
                print("Suffeling {0:.2f}%".format((ukur / ukuran) * 100))
        return toks, daftar_id

    def generate_list_sentences(self, tabel, ukuran, max_word):
        ukur = 0
        toks = []
        max_count = 408734
        l = list(range(max_count))
        random.shuffle(l)
        indeks = 0
        while ((indeks < max_count) and (ukur <= ukuran)):
            self._db_cur.execute(
                "select id,dokumen from {df_tabel} where id = {df_acak}+1".format(df_tabel=tabel, df_acak=l[indeks]))
            (id_nya, document) = self._db_cur.fetchone()

            # sentence tokenize

            token = sent_tokenize(document.replace('\n', ' '))
            temp_kalimat =[]
            for kalimat in token:
                word = word_tokenize(kalimat)
                if len(word) <= max_word:
                    temp_kalimat.append(kalimat)

            token = temp_kalimat
            ukuran_data = len(token)

            # ['My friend holds a Msc.', 'in Computer Science.']
            ukur = ukur + ukuran_data
            toks = toks + token

            indeks = indeks + 1
            if indeks % 2000 == 0:
                print("Suffeling {0:.2f}%".format((ukur / ukuran) * 100))
        toks = toks[:ukuran]
        return toks

    def generate_sentence(self, lang, max_len, size, outputfile=''):
        if lang == 'id':
            generate_id(max_len, size)

        if outputfile == '':
            savedb(lang, sentences)
        else:
            savefile(lang, sentences, outputfile)

    def generate_id(self, max_sentence_len, sentences_count):
        # generate indonesia sentences with max lengh of sentences max_len and count of sentences size
        # examples : sentences = generate_id(80, 5)
        # it should generates sentences with max sentences lenght of 80 with 5 sentences
        #  sentences = ['kalimat 1', 'kalimat 2', 'kalimat 3', 'kalimat 4', 'kalimat 5']
        return self.generate_list_sentences('wiki_id',sentences_count,max_sentence_len)

    def generate_zh(self, max_sentence_len, sentences_count):
        # generate indonesia sentences with max lengh of sentences max_len and count of sentences size
        # examples : sentences = generate_id(80, 5)
        # it should generates sentences with max sentences lenght of 80 with 5 sentences
        #  sentences = ['kalimat 1', 'kalimat 2', 'kalimat 3', 'kalimat 4', 'kalimat 5']
        return self.generate_list_sentences('wiki_zh',sentences_count,max_sentence_len)

    def savedb_id(self, sentences, dbfile):
        # saving sentences list generated by generate sentences to database
        resetdata = ResetDb(dbfile)
        resetdata.create_id_zhcn()
        connection = sqlite3.connect(dbfile)
        cur = connection.cursor()
        for item in sentences:
            cur.execute('''insert into id_zhcn(text_id) values (?)''',[item])
        connection.commit()
        connection.close()
        # INSERT INTO table_name (column1,column2,column3,...)
        # VALUES (value1,value2,value3,...)

    def savedb_zh(self, sentences, dbfile):
        # saving sentences list generated by generate sentences to database
        resetdata = ResetDb(dbfile)
        resetdata.create_id_zhcn()
        connection = sqlite3.connect(dbfile)
        cur = connection.cursor()
        for item in sentences:
            cur.execute('''insert into id_zhcn(text_zhcn) values (?)''',[item])
        connection.commit()
        connection.close()
        # INSERT INTO table_name (column1,column2,column3,...)
        # VALUES (value1,value2,value3,...)

    def savefile(self, sentences, outputfile):
        # saving sentences generated by generate sentences function to text file
        with open(outputfile, 'w') as f:
            for item in sentences:
                f.write("%s\n" % item)

if __name__ == '__main__':
    count_id = 408734
    count_zh = 993061
    sumber_id = 'wiki_id'
    sumber_zh = 'wiki_zh'
    max_sentence_length = 80
    sentences_count = 10
    wikiget = WikiGetSentence()
    # b = wikiget.generate_id(max_sentence_length,sentences_count)
    sent_id = wikiget.generate_id(max_sentence_length,sentences_count)
    sent_zhcn = wikiget.generate_zh(max_sentence_length,sentences_count)
    wikiget.savefile(sent_id,'indonesia_sentences_10.txt')
    wikiget.savedb_id(sent_id,'indonesia_sentences_10.db')
    wikiget.savefile(sent_zhcn,'mandarin_sentences_10.txt')
    wikiget.savedb_zh(sent_zhcn,'mandarin_sentences_10.db')


import json

filepath="F:\\ToolsQAPython\\Test_Data.json"

def get_json_data(file_path=filepath):
    with open(file_path,'r') as file:
        data=file.read()
        file_data=json.loads(data)
    return file_data

'''output=get_json_data()
print(output)
print(output['url'])
print(output['users']['user1']['username'])
'''


from dotenv import load_dotenv
import os
from enum import Enum
from urllib.parse import urlparse
import requests
import re

# load environment variables
load_dotenv()

# environment variables
IGNORE_AFTER_LINE = os.environ.get("IGNORE_AFTER_LINE").strip()
IGNORE_AFTER_LINE_METHOD = os.environ.get("IGNORE_AFTER_LINE_METHOD").strip()
IGNORE_UNTIL_BLANK_LINE_PREFIXES = [x.strip() for x in os.getenv("IGNORE_UNTIL_BLANK_LINE_PREFIXES", "").strip().split(',')]

class BDInfoType(Enum):
  QUICK_SUMMARY = 1
  PLAYLIST_REPORT = 2

class PasteParser():

  class Section(Enum):
    QUICK_SUMMARY = 1
    MEDIAINFO = 2
    PLAYLIST_REPORT = 3
    EAC3TO_LOG = 4

  class Section2(Enum):
    PLAYLIST_VIDEO = 1
    PLAYLIST_AUDIO = 2
    PLAYLIST_SUBTITLES = 3

  class Section3(Enum):
    PLAYLIST_INNER_VIDEO = 1
    PLAYLIST_INNER_AUDIO = 2

  def parse(self, text):
    bdinfo = dict()
    bdinfo['video'] = list()
    bdinfo['audio'] = list()
    bdinfo['subtitle'] = list()
    mediainfo = list()
    eac3to = list()
    eac3to_index = -1

    sect = None
    sect2 = None
    sect3 = None

    # parse bdinfo
    lines = text.splitlines()
    ignore_next_lines, did_first_mediainfo, did_first_bdinfo = False, False, False
    for l in lines:
      # break after ignore line
      if self._isIgnoreAfterLine(l):
        break

      if not l.strip():
        # don't ignore input after blank line
        ignore_next_lines = False
        # skip blank lines
        continue

      if ignore_next_lines:
        continue

      if IGNORE_UNTIL_BLANK_LINE_PREFIXES and IGNORE_UNTIL_BLANK_LINE_PREFIXES[0] != '':
        l3 = l.strip().lower()
        for x in IGNORE_UNTIL_BLANK_LINE_PREFIXES:
          if l3.startswith(x):
            ignore_next_lines = True
            break

      l2 = l.strip().lower()

      # determine current section
      # limit to first bdinfo and mediainfo
      if l2.startswith("quick summary"):
        if did_first_bdinfo:
          sect = None
        else:
          sect = self.Section.QUICK_SUMMARY
          bdinfo['type'] = BDInfoType.QUICK_SUMMARY
          did_first_bdinfo = True
      elif l2.startswith("playlist report"):
        if did_first_bdinfo:
          sect = None
        else:
          sect = self.Section.PLAYLIST_REPORT
          bdinfo['type'] = BDInfoType.PLAYLIST_REPORT
          did_first_bdinfo = True
      elif l2.startswith("eac3to v"):
        sect = self.Section.EAC3TO_LOG
        eac3to.append(list())
        eac3to_index += 1
      elif l2.startswith("general"):
        if did_first_mediainfo:
          sect = None
        else:
          sect = self.Section.MEDIAINFO
          did_first_mediainfo = True

      if sect == self.Section.QUICK_SUMMARY:
        if l2.startswith("video:"):
          track_name = l.split(':', 1)[1]
          track_name = self._format_video_track_name(track_name)
          bdinfo['video'].append(track_name)
        elif l2.startswith("audio:"):
          audio_name = l.split(':', 1)[1].strip()
          if "ac3 embedded" in audio_name.lower():
            audio_parts = re.split("\(ac3 embedded:", audio_name, flags=re.IGNORECASE)
            bdinfo['audio'].append(self._format_track_name(audio_parts[0]))
            compat_track = "Compatibility Track / Dolby Digital Audio / " + audio_parts[1].strip().rstrip(")")
            bdinfo['audio'].append(self._format_track_name(compat_track))
          else:
            if "(" in l:
              l = l.split("(")[0]
            l = l.strip()
            bdinfo['audio'].append(self._format_track_name(l.split(':', 1)[1]))
        elif l2.startswith("subtitle:"):
          bdinfo['subtitle'].append(self._format_track_name(l.split(':', 1)[1]))

      elif sect == self.Section.PLAYLIST_REPORT:

        if l2.startswith("video:"):
          sect2 = self.Section2.PLAYLIST_VIDEO
        elif l2.startswith("audio:"):
          sect2 = self.Section2.PLAYLIST_AUDIO
        elif l2.startswith("subtitles:"):
          sect2 = self.Section2.PLAYLIST_SUBTITLES

        if l2.startswith("-----"):
          if sect2 == self.Section2.PLAYLIST_VIDEO:
            sect3 = self.Section3.PLAYLIST_INNER_VIDEO
          elif sect2 == self.Section2.PLAYLIST_AUDIO:
            sect3 = self.Section3.PLAYLIST_INNER_AUDIO
        else:
          # skip tracks that start with minus sign
          if l.startswith("-"):
            continue

          if sect2 == self.Section2.PLAYLIST_VIDEO and sect3 == self.Section3.PLAYLIST_INNER_VIDEO:
            # format video track name with slashes
            try:
              parts = l.split()
              kbps_i = parts.index("kbps")
              before = " ".join(parts[:kbps_i - 1]).strip()
              after = " ".join(parts[kbps_i + 1:]).strip()
              track_name = before + " / " + parts[kbps_i - 1] + " " + parts[kbps_i] + " / " + after
              track_name = self._format_video_track_name(track_name)
              bdinfo['video'].append(track_name)
            except ValueError:
              continue

          elif sect2 == self.Section2.PLAYLIST_AUDIO and sect3 == self.Section3.PLAYLIST_INNER_AUDIO:
            name = self._name_from_parts(l)
            bdinfo['audio'].append(self._format_track_name(name))

            if "ac3 embedded" in l.lower():
              audio_parts = re.split("\(ac3 embedded:", l, flags=re.IGNORECASE)
              compat_track = "Compatibility Track / Dolby Digital Audio / " + "/".join(audio_parts[1].split("/")[:-1]).strip().rstrip(")")
              bdinfo['audio'].append(self._format_track_name(compat_track))

      elif sect == self.Section.MEDIAINFO:
        mediainfo.append(l)

      elif sect == self.Section.EAC3TO_LOG:
        if l.startswith("Done."):
          sect = None
        else:
          eac3to[eac3to_index].append(l)

    return bdinfo, mediainfo, eac3to

  def _name_from_parts(self, l):
    l2 = l
    if "(" in l:
      l2 = l.split("(")[0]
    l2 = l2.strip()
    l_parts = l2.split(" / ")
    l_parts0 = l_parts[0].strip().split()
    l_parts1 = " / ".join(l_parts[1:]).strip()
    name = " ".join(l_parts0[:-4]) + " / " + l_parts0[-1] + " / " + l_parts1
    return name

  def _format_video_track_name(self, name):
    track_name = self._remove_3d(name)
    track_name = self._format_track_name(track_name)
    track_name = self._video_fps_force_decimal(track_name)
    return track_name

  def _format_track_name(self, name):
    # remove multiple and trailing spaces
    track_name = ' '.join(name.split()).strip()
    # remove dialog normalization text
    track_name = self._remove_dialog_normalization(track_name)
    return track_name

  def _remove_dialog_normalization(self, name):
    if 'DN' in name.upper():
      return name.rpartition(' / ')[0]
    return name

  def _remove_3d(self, name):
    name = name.replace(" / Left Eye", "")
    name = name.replace(" / Right Eye", "")
    return name

  def _video_fps_force_decimal(self, name):
    # bdinfo force decimal instead of comma in fps
    new_name = name.split('/')
    new_name[3] = new_name[3].replace(',', '.')
    new_name = "/".join(new_name)
    return new_name

  def _isIgnoreAfterLine(self, l):
    if IGNORE_AFTER_LINE_METHOD == "equals":
      if IGNORE_AFTER_LINE == l:
        return True
    elif IGNORE_AFTER_LINE_METHOD == "contains":
      if IGNORE_AFTER_LINE in l:
        return True
    return False


import re
def checkio(expression):

    bracket_pattern = "[\(\[\{\}\]\)]"
    opening_pattern = "[\(\[\{]"
    oppose = {"(": ")", ")": "(",
              "[": "]", "]": "[",
              "{": "}", "{": "}"}
    opening_bracket = []

    # If no brackets, return True
    if re.search(bracket_pattern, expression) is None:
        return True
    else:
        for c in expression:
            if re.match(bracket_pattern, c):
                # If its an opening bracket, put it on top of opening brackets pile
                if re.match(opening_pattern, c):
                    opening_bracket.append(c)
                # If its a closing bracket, it should be the opposite of the last opening bracket and the opening pile should not be empty
                elif len(opening_bracket) == 0 or not c == oppose[opening_bracket.pop()]:
                    return False
        """ If it goes here, every closing bracket has an corresponding opening bracket, just have to check if there is
            no opening bracket alone """
        if len(opening_bracket) > 0:
            return False
        else:
            return True

#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio(u"[1+1]+(2*2)-{3/3}") == True, "Different operators"
    assert checkio(u"2+3") == True, "No brackets, no problem"
    assert checkio(u"((5+3)*2+1)") == True, "Simple"
    assert checkio(u"{[(3+1)+2]+}") == True, "Different types"
    assert checkio(u"(3+{1-1)}") == False, ") is alone inside {}"
    assert checkio(u"(({[(((1)-2)+3)-3]/3}-3)") == False, "One is redundant"


import itertools
import random
from time import time
import pdb
import json
from joblib import Parallel, delayed
import os

def greedy(x_list, target):
    # sort all inputs from large to small
    # add in numbers from large to small if fit. It not fit, don't add
    # greedy algorithm runs in O(n) time
    optimal = 0
    x_list.sort(reverse=True)
    for x in x_list:
        if optimal + x <= target:
            optimal += x
        if optimal == target:
            break
    return optimal

def inner_loop(line, index):
#    pdb.set_trace()
    split = line.split(',')
    target = int(split.pop(0))
    split[-1] = split[-1].replace('\n','')
    x_list = [int(i) for i in split]

    gd = greedy(x_list, target)
    print(f'finished line {index}')
    return (gd, len(x_list))

def main():
    input_f = open('input.txt', 'r')
    rline = input_f.readlines()
    input_f.close()

    usable_cores = os.sched_getaffinity(0)
    gd_opt = Parallel(n_jobs=len(usable_cores))(delayed(inner_loop)(line, rline.index(line)) for line in rline)
    with open(f'data/greedy.json', 'w') as f:
        json.dump(gd_opt, f, indent=4)

if __name__ == '__main__':
    main()


def two_sum(nums, target):
    """
    Beats 100% of the solutions on LeetCode 01/03/18. ;)
    """

    my_set = set()

    for i in range(0, len(nums)):
        if target - nums[i] in my_set:
            if target - nums[i] != nums[i]:
                return nums.index(target - nums[i]), nums.index(nums[i])
            else:
                return [x for x, el in enumerate(nums) if el == nums[i]][:2]
        else:
            my_set.add(nums[i])

# test_arr = [2, 7, 11, 15]
# test_arr = [3, 4, 5, 10]
# test_arr = [3, 2, 4]
# test_arr = [3, 3]
test_arr = [3, 2, 3]
print(two_sum(test_arr, target=6))


# WHILE

# multiple assessment in line 3
# add keyword 'end' to prevent carriage return

a, b = 1,2
while a < 4:
    print("number ", a,end=",")
    a, b = a+b, b

# test auto space vars
a = "world"
print("hello",a)

# IF STATEMENT
a = 5
if a == 5:
    print("five")
else:
    print("not five")

# another IF
x = 2
# x = int(input("enter #"))
if x < 0:
    x = 0
    print("no negs")
elif x == 0:
    print("zero")
elif x == 1:
    print("one")
else:
    print("more than 1")

# FOR STATEMENTS
words = ['one','two','three']
for w in words:
    print(w,len(w))

# RANGE function
for i in range(5):
    print(i)

# by twos
for i in range(0,10,2):
    print(i)

# create array and loop
arr = ['one','two','three']
for i in range(0, len(arr)):
    print(i,arr[i])

# range is an object
# use list to list
x = list(range(10))
print("listed",x)

# range is an object
x = range(5)
print("just a range", x)

# break, continue
x = range(0,10)
print("new range function:")
for y in x:
    print(y)
    if(y == 5):
        print("there is five!")
       # break
        continue

def ask_ok(prompt, retries=4, reminder='Please try again!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise ValueError('invalid user response')
        print(reminder)

# call method 1
ask_ok('Do you really want to quit?')
# call method 2
ask_ok('huh?',2)


#!/usr/bin/python

import re,os
import string
import pickle
from collections import OrderedDict

MESSENGER_VAR = 'Messenger'

CMDS = {'@begin':('NES',False),			# o
		'@end':('NES',False),			# o
		'@loop':('LOOP',False),			# o
		'@while':('LOOP',True),			# o
		'@endloop':('LOOP',False),		# o
		'@if':('COND',True),			# o
		'@elseif':('COND',True),		# o
		'@else':('COND',False),			# o
		'@endif':('COND',False),		# o
		'@var':('DECL',True),			# o
		'@ass':('DECL',True),			# o
		'@ass*':('DECL',True),			# o
		'@ass&':('DECL',True),			# o
		'@del':('DECL',True),			# o
		'@let':('DECL',True),			# o
		'@vass':('DECL',True),			# o
		'@vass*':('DECL',True),			# o
		'@vass&':('DECL',True),			# o
		'@vdel':('DECL',True),			# o
		'@pass':('GRAM',False),			# o
		'@mouse':('EXEC',True),			# o
		'@exec':('EXEC',True),			# o
		'@jmp':('SIGHT',True),			# o
		'@exit':('SIGHT',True),			# o
		'@input':('SIGHT',True),		# o
		'@console':('SIGHT',True),		# o
		'@msg':('SIGHT',True),			# o
		'@wait':('SIGHT',True),			# o
		'@ndef':('RETURN',True),		# o		global function
		'@def':('RETURN',True),			# o		global function
		'@return':('RETURN',True),		# o
		'@call':('RETURN',True),		# o		global function call
		'@alloc':('RETURN',True),		# o		global function call
		'//':('COMMENT',False),			# o
		'#namespace':('INCLUDE',False)	# o
		}

class Preprocessor(object):
	def __init__(self):
		self.start_flag = 0
		self.indent 	= 0
		self.is_if		= 0
		self.keep		= 0
		self.loop		= []
		self.cond		= []
		self.jmp		= []
		self.func		= []
		self.namespace	= True
		self.funcaddr	= OrderedDict()
		self.execute 	= []
	def __tokenize(self,script_path,present):
		lineno 		= 0
		self.total	= 0
		with open(script_path,'r') as file:
			for line in file:
				lineno 		+= 1
				self.total  += 1
				pvc = line.strip().split(' ',1)
				if pvc[0] == '//' or pvc == ['']:
					self.total -= 1
					continue
				elif pvc[0] == '@begin' and script_path == present:
					self.indent += 1
					self.start_flag += 1
					self.namespace	= script_path
					self.keep		= self.namespace
					self.__insert_line(lineno,pvc)
					self.__insert_line(lineno,['@var',"str {0} = null".format(MESSENGER_VAR)])
					continue
				elif pvc[0] == '@begin':
					self.indent += 1
					self.start_flag += 1
					self.namespace	= script_path
					self.keep		= self.namespace
				elif self.start_flag and pvc[0] == '#namespace':
					return [None,"{0}: namespace keyword cannot be used in body area.".format(lineno)]
				elif not self.start_flag and pvc[0] == '#namespace':
					sc = present.split(os.sep)
					sc.pop(-1)
					sc = str.join(os.sep,sc)
					if os.path.exists(pvc[1]) == True:
						ret = self.__tokenize(pvc[1],present)
						if ret[0] == None:return ret
					elif os.path.exists(sc+os.sep+pvc[1]) == True:
						ret = self.__tokenize(sc+os.sep+pvc[1],present)
						if ret[0] == None:return ret
					else:return [None,"{0}: cannot found file '{1}'.".format(lineno,pvc[1])]
					continue
				elif pvc[0] == '@end' and self.start_flag:
					self.start_flag -= 1
					if self.start_flag:continue
				elif pvc[0] in ['@loop','@while']:
					self.loop.append(self.total)
				elif pvc[0] == '@endloop':
					try:
						cur = self.loop.pop()
						pvc = ['@jmp',-self.total+cur-1]
						self.execute[cur-1][2] = self.total
					except:return [None,"{0}: cannot found loop/while statement(s) boundary area.".format(lineno)]
				elif pvc[0] in ('@if','@elseif','@else'):
					self.cond.append([pvc[0],self.total])
				elif pvc[0] == '@endif':
					try:
						cur = self.cond.pop()
						self.execute[cur[1]][2] = self.total
					except:return [None,"{0}: cannot found if statement(s) boundary area.".format(lineno)]
				elif pvc[0] == '@jmp':
					try:self.jmp.append([self.total,lineno,int(pvc[1])])
					except:return [None,"{0}: jumping out of range".format(lineno)]
				elif pvc[0] == '@ndef':
					if   len(pvc)<=1:return [None,"{0}: There is no function name.".format(lineno)]
					elif len(pvc)==2:param = None
					else:return [None,"{0}: too many parameter".format(lineno)]
					self.func.append([self.total,pvc[1],1])
					self.funcaddr.update({pvc[1]:[pvc[1],self.total,self.total,pvc[1],param]})
					self.namespace = pvc[1]
				elif pvc[0] == '@def':
					if   len(pvc)<=1:return [None,"{0}: There is no function name.".format(lineno)]
					elif len(pvc)==2:param = None
					elif len(pvc)==3:param = pvc[2]
					else:return [None,"{0}: too many parameter".format(lineno)]
					self.func.append([self.total,pvc[1],0])
					self.funcaddr.update({pvc[1]:[pvc[1],self.total,self.total,pvc[1],param]})
					self.namespace = pvc[1]
				elif pvc[0] == '@return':
					try:
						cur = self.func.pop()
						self.execute[cur[0]-1][2] = self.total
						sem = pvc[1].split(' ',1)
						cur = self.funcaddr.pop(cur[1])
						self.funcaddr.update({cur[0]:[cur[0],cur[1],self.total,cur[3],cur[4]]})
						self.namespace = self.keep
						if sem[0] == 'void':self.__insert_line(lineno,['@pass'])
						else:self.__insert_line(lineno,['@vass*',"{0} {1} = {2}".format(sem[0],MESSENGER_VAR,sem[1])])
						continue
					except:return [None,lineno]
				elif pvc[0] == '@call':
					try:
						pointer = self.funcaddr.get(pvc[1])
						cursor	= pointer[1]
						while True:
							if pointer[2]-cursor<0:break
							self.execute.append(self.execute[cursor])
							cursor 		+= 1
							self.total  += 1
						self.keep = self.namespace
						continue
					except:return [None,lineno]
				elif pvc[0] == '@alloc':
					pvc = pvc[1].strip().split('=')
					if len(pvc)!=2:return [None,lineno]
					try:
						pointer = self.funcaddr.get(pvc[1].strip())
						cursor	= pointer[1]
						while True:
							if pointer[2]-cursor<=0:
								val = self.execute[cursor-1][4]
								val = val.split(' ',1)
								self.__insert_line(lineno,['@ass*',"{0} {1} = {2}".format(val[0],pvc[0].strip(),MESSENGER_VAR)])
								break
							self.execute.append(self.execute[cursor])
							cursor 		+= 1
							self.total  += 1
						self.keep = self.namespace
						continue
					except:return [None,lineno]
				elif pvc[0] == '@del':
					if pvc[1].strip() == MESSENGER_VAR:
						return [None,"{0}: It is not allowed removing '{1}' variable .".format(lineno,MESSENGER_VAR)]
				elif pvc[0] == '@let':
					tvr = pvc[1].strip().split('=')[0].split()[1].strip()
					if tvr == MESSENGER_VAR:
						return [None,"{0}: It is not allowed declaring '{1}' variable in lib.".format(lineno,MESSENGER_VAR)]
				line = [lineno,self.indent,self.total]+pvc+[self.namespace]
				self.execute.append(line)
				for i in self.jmp:
					if lineno==(i[2]):
						self.execute[i[0]-1] = [i[1],self.indent,self.total,'@jmp',self.total-i[0]]
						self.jmp.remove(i)
						break
		return self.execute
	def __insert_line(self,lineno,pvc):
		self.execute.append([lineno,+self.indent,self.total]+pvc+[self.namespace])

	def __check_line(self,line,niro):
		if   line == None:niro = False
		elif line[0] == None:return line[1]
		elif line[3] not in CMDS.keys():return 'nokeyword'
		else:
			if CMDS.get(line[3],False)[1] == True:
				if len(line)!=6:return 'formaterror'
			return 0
	def compile(self,file):
		print ('[Compiler] : Read script from "{0}"...'.format(file))
		present	= file
		niro = True
		try:lines 	= self.__tokenize(file,present)
		except:
			print ('[Compiler] : Error emerged while tokenization')
			return False
		for line in lines:
			print(line)
			error = self.__check_line(line,niro)
			if niro == False:return line
			if error:
				print ('[Compiler] : < Error Code {0} > {1} : Script grammar error '.format(error,line))
				return line
		lines[-1][1] = -1
		file = file.split('.')[0]
		with open(file+'.tlc', 'wb') as handle:
			pickle.dump(lines, handle)
		print ('[Compiler] : Compiled Compeleted.')
		return True

if __name__ == '__main__':

	comp = Preprocessor()
	comp.compile('syscall')