from __future__ import division

import numpy as np

from _npcompat import linalg_inv

def fermi(x, beta):
    """Fermi function"""
    arg = np.asarray(float(beta) * x)
    result = np.empty_like(arg)

    # Create a piece-wise function in the argument: in the asymptotic region,
    # where |Re(beta*x)| > 50, the Fermi function is approximated by a step.
    # This is to quiet the warning for invalid divisions. np.where does not
    # do the trick because it does not short-circuit. In principle, one could
    # rewrite the function in terms of the tanh, however one runs into numpy
    # bug #5518 for complex numbers.
    inner_region = np.asarray(np.abs(arg.real) < 50)
    result[...] = arg < 0
    result[inner_region] = 1/(1. + np.exp(arg[inner_region]))
    return result

def fft_from_iw(aiw, fft_len=None, axis=-1):
    """Convert Masubara to FFT convention over the doubled interval.

    >>> fft_from_iw(np.array([1, 2, 3, 4]), 12)
    array([0, 3, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2])
    """
    if axis != -1:
        aiw = np.rollaxis(aiw, axis, aiw.ndim)

    niw = aiw.shape[-1]
    if niw % 2:
        raise ValueError("Number of frequencies must be even")
    iw_zero = niw // 2

    if fft_len is None:
        fft_len = 2 * niw
    elif fft_len % 4:
        raise ValueError("Illegal FFT length")

    # Only use part of the axis
    niw_fft = niw
    if niw_fft > fft_len // 2:
        niw_fft = fft_len // 2

    ahat = np.zeros(aiw.shape[:-1] + (fft_len,), aiw.dtype)
    ahat[..., 1:niw_fft:2] = aiw[..., iw_zero:iw_zero+niw_fft//2]
    ahat[..., -niw_fft+1::2] = aiw[..., iw_zero-niw_fft//2:iw_zero]
    return ahat

def iw_from_fft(ahat, niw=None, fft_len=None, axis=-1):
    """Extract the Matsubara axis from an FFT over the doubled interval.

    >>> iw_from_fft(np.array([0, 3, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2]), 4)
    array([1, 2, 3, 4])
    """
    if fft_len is None:
        fft_len = ahat.shape[-1]
    elif fft_len > ahat.shape[-1]:
        raise ValueError("Forced FFT length exceeds provided length")
    if fft_len % 4:
        raise ValueError("Illegal FFT length")

    niw_fft = fft_len // 2
    if niw is None:
        niw = niw_fft
    if niw_fft > niw:
        niw_fft = niw    # Ensure that we don't copy over

    if niw % 2:
        raise ValueError("Number of frequencies must be even")
    iw_zero = niw // 2

    aiw = np.zeros(ahat.shape[:-1] + (niw,), ahat.dtype)
    aiw[..., iw_zero:iw_zero+niw_fft//2] = ahat[..., 1:niw_fft:2]
    aiw[..., iw_zero-niw_fft//2:iw_zero] = ahat[..., -niw_fft+1::2]

    if axis != -1:
        aiw = np.rollaxis(aiw, -1, axis)
    return aiw

def tau_from_fft(a, beta, axis=-1):
    """Extract the positive tau points from the FFT over the doubled array."""
    if a.shape[-1] % 2:
        raise ValueError("Illegal FFT axis")

    # This is to give the complete tau axis, i.e., from 0 ... beta, both
    # inclusive. While for the FT, this is redundant, as there is strict
    # anti-symmetry between the two points, it is useful for the later addition
    # of the tau-model.
    ntau = a.shape[-1]//2 + 1
    atau = a[..., :ntau]/beta

    if axis != -1:
        atau = np.rollaxis(atau, -1, axis)
    return atau

def fft_from_tau(atau, beta, axis=-1):
    """Convert tau values to the FFT convention"""
    if axis != -1:
        atau = np.rollaxis(atau, axis, atau.ndim)

    # The axis runs from 0, beta, both inclusive!
    ntau_cut = atau.shape[-1] - 1
    fft_len = 2 * ntau_cut

    # Here, don't fill the endpoint, otherwise the normalisation gets confused
    # (alternatively, we could anti-symmetrise over the two points).
    a = np.zeros(atau.shape[:-1] + (fft_len,), atau.dtype)
    a[..., :ntau_cut] = atau[..., :-1]

    # The FT to Matsubara is given by the inverse FFT in the numpy convention,
    # which carries a normalisation factor we have to cancel here.
    a *= 2 * beta
    return a

def fft_from_taubins(atau, beta, axis=-1):
    """Convert tau bin centres to FFT convention over the quadrupled array"""
    if axis != -1:
        atau = np.rollaxis(atau, axis, atau.ndim)

    n = atau.shape[-1]
    fft_len = 4 * n
    result = np.zeros(atau.shape[:-1] + (fft_len,), atau.dtype)
    result[..., 1:2*n:2] = atau

    # The FT to Matsubara is given by the inverse FFT in the numpy convention,
    # which carries a normalisation factor we have to cancel here.
    result *= 4 * beta
    return result

def iw_from_tau(atau, beta, niw=None, axis=-1):
    """Compute quantity on the Matsubara axis from tau values"""
    return iw_from_fft(
                np.fft.ifft(fft_from_tau(atau, beta, axis)),
                niw, None, axis)

def iw_from_taubins(atau, beta, niw=None, axis=-1):
    """Compute quantity on the Matsubara axis from tau-binned values"""
    return iw_from_fft(
                np.fft.ifft(fft_from_taubins(atau, beta, axis)),
                niw, 2 * atau.shape[axis], axis)

def tau_from_iw(aiw, beta, ntau=None, axis=-1):
    """Compute quantity on an equispaced tau grid from Matsubara axis"""
    if ntau % 2 != 1:
        raise ValueError("number of tau points must be odd (including beta)")

    return tau_from_fft(
                np.fft.fft(fft_from_iw(aiw, 2*(ntau-1), axis)),
                beta, axis)

def euler(n, x):
    """Returns the value at `x` of the Euler polynomial of order `n`"""
    if n == 0:
        return np.ones_like(x)
    elif n == 1:
        return x - 0.5
    elif n == 2:
        return (x - 1) * x
    else:
        raise NotImplementedError("Well ...")

def pmodel_tau(moments, tau, beta, axis=-1):
    """Generate model function for moments, transformed to the tau axis"""
    moments = np.asarray(moments)
    tau = np.asarray(tau)
    if tau.ndim != 1:
        raise ValueError("Expect 1D array of tau points")

    # We make use of the formula:
    #
    #     1/\beta \sum_\nu exp(-i\nu\tau) / (i\nu)^(n+1)
    #                          = (-1)^(n+1)/2 \beta^n/(n!) E_n(\tau/beta),
    #
    # where E_n(x) is the n-th Euler polynomial (this can easily be proven
    # using the identities DLMF 24.8.4 and 24.8.5.
    prefactor = -0.5
    model = np.zeros(moments.shape[1:] + tau.shape, moments.dtype)
    for n, moment in enumerate(moments):
        if n != 0:
            prefactor *= -beta/n
        model += prefactor * euler(n, tau/beta) * moment[..., None]

    if axis != -1:
        model = np.rollaxis(model, -1, axis)
    return model

def pmodel_iw(moments, iw, axis=-1):
    """Generate model function for moments on the Matsubara axis"""
    moments = np.asarray(moments)
    iw = np.asarray(iw)
    if iw.ndim != 1:
        raise ValueError("Expect 1D array of iw points")

    # Horner scheme, yo!
    model = np.zeros(moments.shape[1:] + iw.shape, complex)
    for moment in reversed(moments):
        model += moment[..., None]
        model /= 1j * iw

    if axis != -1:
        model = np.rollaxis(model, -1, axis)
    return model

def moments_from_density(step, dens, beta):
    """Get moment for a function modelling a certain density"""
    return [step, (step - 2*dens) * (2./beta)]

def moments_from_borders(zero_val, beta_val, beta):
    """Get moment for a function modelled after border values"""
    return [-zero_val - beta_val, (beta_val - zero_val) * (2./beta)]

def fmodel_tau(epsilon, tau, beta, axis=-1):
    """Generate model of type `1/(iw - epilson)` on the imaginary time axis"""
    epsilon = np.asarray(epsilon)
    tau = np.asarray(tau)
    if epsilon.shape != (epsilon.shape[0],) * 2:
        raise ValueError("Expecting square array for epsilon")
    if tau.ndim != 1:
        raise ValueError("Expect 1D array of iw points")

    tau_neg = tau < 0
    tau = np.where(tau_neg, tau + beta, tau)
    ev, eb = np.linalg.eigh(epsilon)
    occ = fermi(ev, beta)

    forward = ev > 0
    backward = ~forward
    model = np.einsum('ij,tj,jk->ikt',
                eb[:, forward],
                np.exp(-tau[...,None] * ev[forward]) * (-1 + occ[forward]),
                eb[:, forward].conj().T)
    model += np.einsum('ij,tj,jk->ikt',
                eb[:, backward],
                np.exp((beta - tau[...,None]) * ev[backward]) * -occ[backward],
                eb[:, backward].conj().T)

    model[..., tau_neg] = -model[..., tau_neg]
    if axis != -1:
        model = np.rollaxis(model, -1, axis)
    return model

def fmodel_iw(epsilon, iw, axis=-1):
    """Generate model of type `1/(iw - epilson)` on the Matsubara axis"""
    epsilon = np.asarray(epsilon)
    iw = np.asarray(iw)
    if epsilon.shape != (epsilon.shape[0],) * 2:
        raise ValueError("Expecting square array for epsilon")
    if iw.ndim != 1:
        raise ValueError("Expect 1D array of iw points")

    model = linalg_inv(iw[:,None,None] - epsilon).transpose(1,2,0)
    if axis != -1:
        model = np.rollaxis(model, -1, axis)
    return model


import json
import boto3
import urllib3

def lambda_handler(event, context):
    for item_event in event["Records"]:
        item_event_body = json.loads(item_event["body"])

        job_name = item_event_body["job_guid"]
        url = item_event_body["audio_url"]

        bucket = "voice-recognition-213123"
        key = f"uploaded_files/{job_name}.mp3"
        s3_url = f"s3://{bucket}/{key}"

        s3=boto3.client('s3')
        http=urllib3.PoolManager()

        k = s3.upload_fileobj(http.request("GET", url,preload_content=False), bucket, key)

        client = boto3.client("transcribe")

        recognition_job = client.start_transcription_job(
            TranscriptionJobName=job_name,
            LanguageCode="en-US",
            MediaFormat=url.split(".")[-1],
            Media={
                "MediaFileUri": s3_url,
            },
            OutputBucketName = bucket
        )
        dynamodb = boto3.resource("dynamodb")
        table = dynamodb.Table("Transcribtions")
        table.put_item(
            Item={
                "pk": job_name,
                "audio_url": url,
                "transcription_url": key,
                "sentences": item_event_body["sentences"]
            }
        )

    return True


from sqlalchemy import create_engine, event
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlite3 import Connection as SQLite3Connection

__author__ = 'Alex Haslehurst'

class MediaContext:
    Base = declarative_base()

    def __init__(self, connection_string, echo=False):
        self._Engine = create_engine(connection_string, echo=echo)
        event.listen(self._Engine, 'connect', MediaContext._set_sqlite_pragma)
        self.SessionMaker = sessionmaker(bind=self._Engine)

    def drop_and_create(self):
        meta = self.Base.metadata
        meta.drop_all(self._Engine)
        meta.create_all(self._Engine)

    # Check we are using sqlite3 on connect and if so, enable foreign keys.
    @staticmethod
    def _set_sqlite_pragma(dbapi_connection, connection_record):
        if isinstance(dbapi_connection, SQLite3Connection):
            cursor = dbapi_connection.cursor()
            cursor.execute("PRAGMA foreign_keys=ON;")
            cursor.close()


#criar app que leia dois numeros, logo apos apareça menu de opções, 1-soma 2-subtrai 3-multiplica 4- dividi 5-escrever novos numeros 6- sair da calculadora e fazer opeção solicitada
from time import sleep

numero1 = int(input('Digite o primeiro numero: '))
numero2 = int(input('Digite o segundo numero: '))
opcao = 0

while opcao != 5:
    print('''Selecione a opção desejada
            1- Somar
            2-Multiplicar
            3-Maior
            4-Novos números
            5-Sair do programa
            Opção selecionada: ''')
    opcao = int(input('Opção desejada: '))

    if opcao == 1:
        print('A soma de {} + {} é igual a: {} '.format(numero1, numero2, numero2+numero1))
    elif opcao == 2:
        print('A multiplicação de {} X {} é igual a: {}'.format(numero1, numero2, numero2 * numero1))
    elif opcao == 3:
        if numero1 > numero2:
            print('O maior numero digitado foi {}'.format(numero1))
        elif numero2 > numero1:
            print('O maior numero digitado foi {}'.format(numero2))
        else:
            print('Os numeros digitados são iguais')
    elif opcao == 4:
        print('Opção 4 selecionada, digite os novos numeros')
        numero1 = int(input('Digite o primeiro numero: '))
        numero2 = int(input('Digite o segundo numero: '))
    elif opcao == 5:
        print('Fechando programa ...')
        sleep(2)
        print('Programa fechado, até mais!!')
    else:
        print('Opção inválida, tente novamente')


#---------------------------------------------------------------
#
#   This script contains the functions to
#   receive a new pattern and modify
#   according the existent rule base.
#
#   To avoid unnecessary processing,
#   the function " intersected_connected_sets "
#   find which of the original connected sets
#   are intersected by the new pattern.
#
#  Those connected sets together with the new pattern
#  form a " new (connected) set" which will be cut
#  following the maximum volume heuristic
#
#  The resulting rule base is build with the partition
#  of the new connected_set + the partitions comming from
#  the not_intersected connected sets.
#
#----------------------------------------------------------------

import json

from splitR_version1 import *  #  CURRENT VERSION  #
from optimum_partition_for_Q import *
from rulex_2 import *                   #    if necessary . . .

# Read a json file ---------------------
def read(file_name):
    with open(file_name) as json_data:
        file_content = json.load(json_data)
        return file_content
#---------------------------------------------------
# Read files with all_connected_sets and their indexes
all_connected_sets = read('all_connected_sets.json')
#indexes_all_connected_sets = read('indexes_connected_sets.json')
#for i in all_connected_sets: print(i)

# Find wich of the original connected_sets are intersected by the new instance
# get its indexes
def intersected_connected_sets( new_pattern, all_connected_sets ):
    indexes_of_intersected_sets = [ ]
    intersected_sets = []
    index_counter = -1
    for connected_set in all_connected_sets:
        index_counter += 1
        include_set = False
        for rule in connected_set:
            print(new_pattern, rule)
            #intersects = intersection(new_pattern, rule) # INTERSECTIONS OF ALREADY RULEXED INSTANCES
            # Function that considers intersection or possible rule formation with Rulex
            intersects = intersection_or_possible_rule_formation( new_pattern, rule, 1 )
            print('Intersection with this rule: ', intersects)
        if intersects == True:
            include_set = True
        if include_set == True:
            indexes_of_intersected_sets.append(index_counter)
            intersected_sets.append(connected_set)
    return [ intersected_sets,  indexes_of_intersected_sets ]
#   NEW INSTANCE
#pattern = ( 2, 5, 'A' )

#[ intersected_sets,  indexes_of_intersected_sets ] = intersected_connected_sets( pattern, all_connected_sets)

#Create new set with the new pattern + its intersections
def pattern_plus_intersections(pattern, intersected_sets):
        new_set = []
        for intersected_set in intersected_sets:
            for rule in intersected_set:
                new_set.append(rule)
        new_set.append(pattern)
        return new_set

#print('This is the set to cut : ' )
#new_set = pattern_plus_intersections(pattern, intersected_sets)
#print(new_set)

#print('This is the set without inconsistencies among the rules: ')
#new_set = optimum_partition( new_set )
#print(new_set)

#------------------------------------------------------------------------------------
#                           Exclude from optimim partitions
#                           the indexes_of_intersected_sets
#                           keep the rest of the partitions
#------------------------------------------------------------------------------------
optimum_partitions = read('optimum_partitions.json')
optimum_partitions_indexes = read('connected_rules_indexes.json')  #  They share indexes
lonly_rules = read('lonly_rules.json')
lonly_rules_indexes = read('lonly_rules_indexes.json')

#print('------------------')
#print('indexes of intersected sets :  ' , indexes_of_intersected_sets)
#print('optimum_partitions_indexes',optimum_partitions_indexes)
#print('lonly_rules_indexes', lonly_rules_indexes)

#  compare the indexes of optimum partitions (partitions for the connected rules) and lonly rules
#  with the indexes of the intersected sets
#  if they match, eliminate the entrance either in the optimim_partitions of in the lonly_rules
#  return as final set {lonly_rules, optimum_partitions}\{elements_at_indexes_of_intersected_rules}
def remaining_partitions(optimum_partitions, optimum_partitions_indexes, lonly_rules, lonly_rules_indexes, indexes_of_intersected_sets):
    kept_partitions = []
    kept_lonly = []

    for i in range( len(optimum_partitions_indexes) ):
        index = optimum_partitions_indexes[i]
        flag = index in indexes_of_intersected_sets
        if flag == False:
            kept_partitions = kept_partitions + optimum_partitions[i]

    for i in range( len(lonly_rules_indexes) ):
        index = lonly_rules_indexes[i]
        flag = index in indexes_of_intersected_sets
        if flag == False:
            kept_lonly.append(lonly_rules[i])
    return [ kept_partitions, kept_lonly ]

#print( 'REMAINING PARTITIONS : ')

#not_intersected = remaining_partitions(optimum_partitions, optimum_partitions_indexes, lonly_rules, lonly_rules_indexes, indexes_of_intersected_sets)
#print(not_intersected)

#---------------------------------------------------------------
#    The resulting rule base incorporating the new parrern
#    is the set { remaining_partitions U new_set }
#
#---------------------------------------------------------------
def not_intersected_union_new_set(not_intersected, new_set):
    union = []
    for i in not_intersected:
        union = union + i
    for i in new_set:
        union.append(i)
    return union
#print('result: ')
#print( not_intersected_union_new_set(not_intersected, new_set) )

#-----------------------------------------------------------------
#
#           PROCESS  ---   NEW  ---  PATTERN
#
#-----------------------------------------------------------------
#    Write json data
#--------------------------------------
def write(file_name,data):
    with open (file_name, 'w') as f:
        json.dump(data,f)

def as_tuple(iterable):
    _list = []
    for item in iterable:
        if type(item) == list:
            item = tuple(item)
            _list.append(item)
        else:
            _list.append(item)
            the_tuple = tuple(_list)
    return the_tuple

def format_new_set(new_set):
    formatted = []
    for i in new_set:
        i = as_tuple(i)
        formatted.append(i)
    return formatted

def as_list(new_set):
    _list = []
    for i in new_set:
        i = list(i)
        _list.append(i)
    return _list

def remove_risk(new_set):
    _list = []
    for rule in new_set:
        rule.pop()
        _list.append(rule)
    return _list

#--------------------------------------
def process_new_pattern(pattern):
    all_connected_sets = read('all_connected_sets.json')
    [ intersected_sets, indexes_of_intersected_sets ] = intersected_connected_sets( pattern,  all_connected_sets )
    new_set = pattern_plus_intersections(pattern, intersected_sets)
    # print('new set = pattern + intersected_Sets', new_set)

    # Add risk parameter to the new (connected) set for Rules
    for rule in new_set: rule.append(1)
    #print('New connected set without RULEX', new_set)
    #FORMART INTO TUPLES
    new_set = format_new_set(new_set)
    new_set = rulex(new_set)
    print('New set after RULEX', new_set)

    new_set = as_list(new_set)
    new_set = remove_risk(new_set)  ###################
    print( 'New set for cut', new_set )
    new_set = optimum_partition( new_set )
    print('New set optimum partition', new_set)

    optimum_partitions = read('optimum_partitions.json')
    optimum_partitions_indexes = read('connected_rules_indexes.json')
    lonly_rules = read('lonly_rules.json')
    lonly_rules_indexes = read('lonly_rules_indexes.json')

    not_intersected = remaining_partitions(optimum_partitions, optimum_partitions_indexes, lonly_rules, lonly_rules_indexes,indexes_of_intersected_sets)
    print('Not intersected connected sets : ', not_intersected)
   # for j in not_intersected:
    #    print('j',j)
     #   for k in j: print(k)
    if new_set != False:
        new_rule_base = not_intersected_union_new_set(not_intersected,new_set)
    else:
        print('The new pattern do not intersect any connected set')
        del pattern[-1]
        not_intersected.append( [pattern] )
        new_rule_base = not_intersected
    return new_rule_base

#pattern = [ 2,  5,  'A' ]
#print('new rule base: ', process_new_pattern(pattern))


# https://www.hackerrank.com/challenges/30-data-types/problem
"""
Sample Input

12
4.0
is the best place to learn and practice coding!
"""

i = 4
d = 4.0
s = 'HackerRank '
# Declare second integer, double, and String variables.
i_2, d_2, s_2 = int(12), float(4.0), str(
    'is the best place to learn and practice coding!')
# Read and save an integer, double, and String to your variables.

# Print the sum of both integer variables on a new line.
print(i + i_2)
# Print the sum of the double variables on a new line.
print(d + d_2)
# Concatenate and print the String variables on a new line
# The 's' variable above should be printed first.
print(s + s_2)


#!/usr/bin/env python
# encoding: utf-8
"""
*Modal*

:Author:
    David Young
"""
import sys
import os

def modal(
    modalHeaderContent="",
    modalBodyContent="",
    modalFooterContent="",
    htmlId=False,
    centerContent=False,
    htmlClass=False
):
    """
    *generate a modal to by generated with a js event*

    **Key Arguments**

      - ``modalHeaderContent`` -- the heading for the modal
      - ``modalBodyContent`` -- the content (form or text)
      - ``modalFooterContent`` -- the foot (usually buttons)
      - ``htmlId`` -- id for button to hook onto with href
      - ``centerContent`` - center the content in the form?
      - ``htmlClass`` - htmlClass for the form

    **Return**

    - ``modal`` -- the modal

    """
    if htmlClass is False:
        htmlClass = ""

    if htmlId is False:
        htmlId = ""
    else:
        htmlId = """id="%(htmlId)s" """ % locals()
    if centerContent is False:
        centerContent = ""
    else:
        centerContent = "center-content"

    ## VARIABLES ##
    modal = """

        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>

%(modalHeaderContent)s

        %(modalBodyContent)s

        %(modalFooterContent)s

""" % locals()

    return modal


# -*- coding: utf-8 -*-
"""The Virtual File System (VFS) stat object interface."""

from __future__ import unicode_literals

# Note that if this file is name stat.py it will cause naming conflicts
# if used in combination with 'import stat'.

# Note that the stat object is currently kept around for backwards
# compatibility. Having a file (entry) attribute object might be more
# flexible in dealing with e.g. NTFS attributes.

from dfvfs.lib import definitions

class VFSStat(object):
  """Class that implements the VFS stat object interface."""

  TYPE_DEVICE = definitions.FILE_ENTRY_TYPE_DEVICE
  TYPE_DIRECTORY = definitions.FILE_ENTRY_TYPE_DIRECTORY
  TYPE_FILE = definitions.FILE_ENTRY_TYPE_FILE
  TYPE_LINK = definitions.FILE_ENTRY_TYPE_LINK
  TYPE_SOCKET = definitions.FILE_ENTRY_TYPE_SOCKET
  TYPE_PIPE = definitions.FILE_ENTRY_TYPE_PIPE

  def __init__(self):
    """Initializes the stat object."""
    super(VFSStat, self).__init__()

    # File data stat information.
    self.size = None

    # Date and time stat information.
    self.atime = None
    self.ctime = None
    self.mtime = None

    # Ownership and permissions stat information.
    self.mode = None
    self.uid = None
    self.gid = None

    # File entry type stat information.
    self.type = None

    # Other stat information.
    # self.ino = None
    # self.dev = None
    # self.nlink = None
    self.fs_type = None
    self.is_allocated = True


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

"""
@File  : fan-zhuan-lian-biao-lcof.py
@Author: swift
@Date  : 2021/02/10 23:10
@Link  : https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
@Desc  : 剑指 Offer 24. 反转链表
@Method:
"""

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        new_head = None
        while head:
            tmp = head.next
            head.next = new_head
            new_head = head
            head = tmp
        return new_head


from compoyse.midi.MIDIExceptions import ValueNotValidRhythmicValue
import unittest
from compoyse.midi.Meter import _Meter

class TestMeter(unittest.TestCase):
    def setUp(self):
        self.test_meter = _Meter()
        self.test_meter._set_length_of_quarter_in_seconds(60)
        return

    def test_computeRhythmicValueLengthInSeconds_givenArrayOfRhythmicValues_shouldComputeCorrectLength(self):
        test_rhythm = ['quarter', 'quarter']
        test_length = self.test_meter._compute_rhythmic_value_length_in_seconds(test_rhythm)
        self.assertEqual(test_length, 2, 'Rhythm length in seconds is 2.')
        return

    def test_computeRhythmicValueLengthInSeconds_givenArrayOfRhythmicValuesWithTuplet_shouldComputeCorrectLength(self):
        test_rhythm = [3, 'quarter', 'quarter']
        test_length = self.test_meter._compute_rhythmic_value_length_in_seconds(test_rhythm)
        self.assertEqual(test_length, (2/3), 'Rhythm length in seconds is (2/3).')
        return

    def test_computeRhythmicValueLengthInSeconds_givenInvalidRhythmicValue_shouldRaiseValueNotValidRhythmicValueException(self):
        test_rhythm = ['thisisaninvalidrhythm']
        self.assertRaises(ValueNotValidRhythmicValue, self.test_meter._compute_rhythmic_value_length_in_seconds, test_rhythm)
        return

    def test_computeRhythmicValueLengthInSeconds_givenInvalidTupletRhythmicValue_shouldRaiseValueNotValidRhythmicValueException(self):
        test_rhythm = ['quarter', 3]
        self.assertRaises(ValueNotValidRhythmicValue, self.test_meter._compute_rhythmic_value_length_in_seconds, test_rhythm)
        return


import tkinter as tk

def focus1():
    inpt1.focus()

def focus2():
    inpt2.focus()

def erasetext():
    inpt3.delete(0 , tk.END)

def insertext():
    inpt3.insert(tk.INSERT, " Inserted text")

def appendtext():
    inpt3.insert(tk.END, " Appended Text")

window = tk.Tk()
window.title("Input Field Methods")
window.geometry("400x400")

lbl1 = tk.Label(window, text="What function available for Entry Widget ?")
lbl2 = tk.Label(window, text="We have a function to focus to a specific entry")
inpt1 = tk.Entry(window, width = 20)
inpt2 = tk.Entry(window, width = 20)
btn1 = tk.Button(window, text="Focus on First Entry",command = focus1)
btn2 = tk.Button(window, text="Focus on Second Entry", command = focus2)
lbl3 = tk.Label(window, text="We can also configure the text inside the entry using several functions")
inpt3 = tk.Entry(window, width = 20)
btn3 = tk.Button(window, command = erasetext, text="Erase Text")
btn4 = tk.Button(window, command = insertext, text="Insert Text (depends on cursor position)")
btn5 = tk.Button(window, command = appendtext, text="Append Text (always from last position of text)")
lbl4 = tk.Label(window, text = "By using insert function, we can have a default text available for the entry")
inpt4 = tk.Entry(window, width = 20)
inpt4.insert(0, "Enter Your Name")

lbl1.pack()
lbl2.pack()
inpt1.pack()
inpt2.pack()
btn1.pack()
btn2.pack()
lbl3.pack()
inpt3.pack()
btn3.pack()
btn4.pack()
btn5.pack()
lbl4.pack()
inpt4.pack()

window.mainloop()


import FWCore.ParameterSet.Config as cms
import FWCore.ParameterSet.VarParsing as VarParsing
import copy

options = VarParsing.VarParsing('analysis')
#options = VarParsing("python")

# Variables one can control from the multicrab configuration file.
# When connecting a variable you need to tell the module certain information
# about the object.
#                   - Object name.
#                   - Default value.
#                   - Is object a single number or a list.
#                   - Object type.
#                   - Details of object.
#

# ===== Register new variables =====
#options.register('optionTriggerInfo', False,
#VarParsing.VarParsing.multiplicity.singleton,
#VarParsing.VarParsing.varType.bool,
#"Bool for accessing and keeping trigger info in MC")
#options.optionTriggerInfo = True #Set to true for tt+jets

options.register('ofName',
'tempName',
VarParsing.VarParsing.multiplicity.singleton,
VarParsing.VarParsing.varType.string,
"Name for output file."
)

options.register("deterministicSeeds",
True,
VarParsing.VarParsing.multiplicity.singleton,
VarParsing.VarParsing.varType.bool,
"create collections with deterministic seeds" )

options.register("electronRegression",
"GT",
VarParsing.VarParsing.multiplicity.singleton,
VarParsing.VarParsing.varType.string,
"'GT' or an absolute path to a sqlite file for electron energy regression")

options.register("electronSmearing",
"Moriond17_23Jan",
VarParsing.VarParsing.multiplicity.singleton,
VarParsing.VarParsing.varType.string,
"correction type for electron energy smearing" )

# Changed to True for Data configs
options.register("realData",
False,
VarParsing.VarParsing.multiplicity.singleton,
VarParsing.VarParsing.varType.bool,
"input dataset contains real data" )

# ===== Get & parse any command line arguments =====
options.parseArguments()

#####
##   Initial standard configs
#####
process = cms.Process("Demo")
process.load("FWCore.MessageService.MessageLogger_cfi")
process.MessageLogger = cms.Service("MessageLogger", destinations = cms.untracked.vstring('info'), info = cms.untracked.PSet(threshold = cms.untracked.string('DEBUG')), default = cms.untracked.PSet(limit = cms.untracked.int32(-1)), debugModules = cms.untracked.vstring("TNT"))
process.load('Configuration.Geometry.GeometryRecoDB_cff')
process.load("TrackingTools/TransientTrack/TransientTrackBuilder_cfi")
process.load("Configuration.StandardSequences.MagneticField_38T_cff")
process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")
process.GlobalTag.globaltag = '80X_mcRun2_asymptotic_2016_TrancheIV_v8'
process.prefer("GlobalTag")
process.load('Configuration.StandardSequences.Services_cff')
process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi')

#####
##   Input files
#####
process.source = cms.Source("PoolSource",
  fileNames = cms.untracked.vstring(
    ## ttH synch file
    '/store/mc/RunIISummer16MiniAODv2/ttHToNonbb_M125_TuneCUETP8M2_ttHtranche3_13TeV-powheg-pythia8/MINIAODSIM/PUMoriond17_80X_mcRun2_asymptotic_2016_TrancheIV_v6-v1/120000/3C70EB0A-6BBE-E611-B094-0025905A606A.root'
    ##ttjets Synch File
    #'/store/mc/RunIISummer16MiniAODv2/TT_TuneCUETP8M2T4_13TeV-powheg-pythia8/MINIAODSIM/PUMoriond17_80X_mcRun2_asymptotic_2016_TrancheIV_v6-v1/50000/0693E0E7-97BE-E611-B32F-0CC47A78A3D8.root'
  ),
  skipEvents = cms.untracked.uint32(0)
)
#>>>> Set limit on number events to process (for testing purposes only) <<<<
process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(50) )

#======= Object Collections =======
#Default Collections
electronCollection = cms.InputTag("slimmedElectrons", "", "PAT")
photonCollection   = cms.InputTag("slimmedPhotons", "", "PAT")
muonCollection     = cms.InputTag("slimmedMuons", "", "PAT")
tauCollection      = cms.InputTag("slimmedTaus", "", "PAT")
METCollection      = cms.InputTag("slimmedMETs", "", "PAT")
METPuppiCollection = cms.InputTag("slimmedMETsPuppi")
jetCollection      = cms.InputTag("slimmedJets", "", "PAT")
jetPuppiCollection = cms.InputTag("slimmedJetsPuppi", "", "PAT")
fatjetCollection   = cms.InputTag("slimmedJetsAK8")
topsubjetCollection = cms.InputTag("slimmedJetsCMSTopTagCHSPacked", "SubJets")
#==================================

'''# ===== Implementation of Deterministic seed =====

if options.deterministicSeeds:
    process.load("PhysicsTools.PatUtils.deterministicSeeds_cfi")
    process.deterministicSeeds.produceCollections = cms.bool(True)
    process.deterministicSeeds.produceValueMaps   = cms.bool(False)
    process.deterministicSeeds.electronCollection = electronCollection
    process.deterministicSeeds.muonCollection     = muonCollection
    process.deterministicSeeds.tauCollection      = tauCollection
    process.deterministicSeeds.photonCollection   = photonCollection
    process.deterministicSeeds.jetCollection      = jetCollection
    process.deterministicSeeds.METCollection      = METCollection
    # overwrite output collections
    electronCollection = cms.InputTag("deterministicSeeds", "electronsWithSeed", process.name_())
    muonCollection     = cms.InputTag("deterministicSeeds", "muonsWithSeed", process.name_())
    tauCollection      = cms.InputTag("deterministicSeeds", "tausWithSeed", process.name_())
    photonCollection   = cms.InputTag("deterministicSeeds", "photonsWithSeed", process.name_())
    jetCollection      = cms.InputTag("deterministicSeeds", "jetsWithSeed", process.name_())
    METCollection      = cms.InputTag("deterministicSeeds", "METsWithSeed", process.name_())

# ===== Implementation of Electron Regression =====
if options.electronRegression:
    if options.electronRegression == "GT":
        from EgammaAnalysis.ElectronTools.regressionWeights_cfi import regressionWeights
        process = regressionWeights(process)
    else:
        from EgammaAnalysis.ElectronTools.regressionWeights_local_cfi import GBRDWrapperRcd
        GBRDWrapperRcd.connect = cms.string("sqlite_file:" + options.electronRegression)
        process.regressions = GBRDWrapperRcd
        process.regressions.DumpStat = cms.untracked.bool(False)
        process.es_prefer_regressions = cms.ESPrefer("PoolDBESSource", "regressions")
    process.load("EgammaAnalysis.ElectronTools.regressionApplication_cff")

    # set the electron and photon sources
    process.slimmedElectrons.src = electronCollection
    process.slimmedPhotons.src = photonCollection
    # overwrite output collections
    electronCollection = cms.InputTag("slimmedElectrons", "", process.name_())
    photonCollection = cms.InputTag("slimmedPhotons", "", process.name_())

# ===== Implementation of Electron Smearing =====
if options.electronSmearing and options.electronRegression:
    # the smearing procedure requires a preselection
    process.selectedElectrons = cms.EDFilter("PATElectronSelector",
        src = electronCollection,
        cut = cms.string("pt>5 && abs(superCluster.eta)<2.5")
    )
    electronCollection = cms.InputTag("selectedElectrons", "", process.name_())

    # setup the smearing
    process.load("EgammaAnalysis.ElectronTools.calibratedPatElectronsRun2_cfi")
    from EgammaAnalysis.ElectronTools.calibratedPatElectronsRun2_cfi import files
    process.calibratedPatElectrons.isMC           = cms.bool(not options.realData)
    process.calibratedPatElectrons.correctionFile = cms.string(files[options.electronSmearing])
    process.calibratedPatElectrons.electrons      = electronCollection

    # use our deterministic seeds or a random generator service
    if options.deterministicSeeds:
        process.calibratedPatElectrons.seedUserInt = process.deterministicSeeds.seedUserInt
    else:
        process.load("Configuration.StandardSequences.Services_cff")
        process.RandomNumberGeneratorService = cms.Service("RandomNumberGeneratorService",
            calibratedPatElectrons = cms.PSet(
                initialSeed = cms.untracked.uint32(81),
                engineName  = cms.untracked.string("TRandom3")
            )
        )

    # overwrite output collections
    electronCollection = cms.InputTag("calibratedPatElectrons", "", process.name_())'''

#####
##   ELECTRON ID SECTION
#####
# Set up everything that is needed to compute electron IDs and
# add the ValueMaps with ID decisions into the event data stream
# Load tools and function definitions
from PhysicsTools.SelectorUtils.tools.vid_id_tools import *
switchOnVIDElectronIdProducer(process, DataFormat.MiniAOD)
my_id_modules = ['RecoEgamma.ElectronIdentification.Identification.cutBasedElectronID_Summer16_80X_V1_cff',
                 'RecoEgamma.ElectronIdentification.Identification.heepElectronID_HEEPV70_cff',
                 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring15_25ns_nonTrig_V1_cff',
                 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring15_25ns_Trig_V1_cff',
                 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_GeneralPurpose_V1_cff',
                 'RecoEgamma.ElectronIdentification.Identification.mvaElectronID_Spring16_HZZ_V1_cff'
                ]
# Add them to the VID producer
for idmod in my_id_modules:
    setupAllVIDIdsInModule(process,idmod,setupVIDElectronSelection)

# update some VID modules to work with potentially changed electron collections
'''process.egmGsfElectronIDs.physicsObjectSrc = electronCollection
process.electronRegressionValueMapProducer.srcMiniAOD = electronCollection
process.electronMVAValueMapProducer.srcMiniAOD = electronCollection'''

#####
##   BTAGGING WITH HIP MITIGATION
#####
process.load("Configuration.StandardSequences.MagneticField_cff")
process.load("Configuration.Geometry.GeometryRecoDB_cff")
from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection
updateJetCollection(
  process,
  jetSource = jetCollection,
  jetCorrections = ('AK4PFchs', cms.vstring(['L1FastJet','L2Relative','L3Absolute']), 'None'),
  btagDiscriminators = ['pfCombinedInclusiveSecondaryVertexV2BJetTags', 'pfCombinedMVAV2BJetTags', 'pfJetProbabilityBJetTags', 'pfCombinedCvsLJetTags', 'pfCombinedCvsBJetTags'],
  runIVF=True,
  btagPrefix = 'new' # optional, in case interested in accessing both the old and new discriminator values
)
process.options = cms.untracked.PSet( allowUnscheduled = cms.untracked.bool(True) )

#####
##   For tt+X
#####
# Setting input particle collections to be used by the tools
genParticleCollection = "prunedGenParticles"
genJetCollection      = "slimmedGenJets"
jetFlavourInfos       = "genJetFlavourInfos"
jetAlgo               = "AntiKt"
rParam                = 0.4
genJetPtMin           = 20.
genJetAbsEtaMax       = 2.4
from PhysicsTools.JetMCAlgos.HadronAndPartonSelector_cfi import selectedHadronsAndPartons
process.selectedHadronsAndPartons = selectedHadronsAndPartons.clone(
  particles = genParticleCollection
)
from PhysicsTools.JetMCAlgos.AK4PFJetsMCFlavourInfos_cfi import ak4JetFlavourInfos
process.genJetFlavourInfos = ak4JetFlavourInfos.clone(
    jets         = genJetCollection,
    rParam       = cms.double(rParam),
    jetAlgorithm = cms.string(jetAlgo)
)
from PhysicsTools.JetMCAlgos.GenHFHadronMatcher_cff import matchGenBHadron
process.matchGenBHadron = matchGenBHadron.clone(
  genParticles = genParticleCollection,
  jetFlavourInfos = jetFlavourInfos
)
from PhysicsTools.JetMCAlgos.GenHFHadronMatcher_cff import matchGenCHadron
process.matchGenCHadron = matchGenCHadron.clone(
  genParticles = genParticleCollection,
  jetFlavourInfos = jetFlavourInfos
)

#=======================
#===== Output file =====
#=======================
# Must be EDM output files - output files produced by PoolOutputModule in DBS.
# Notice that for publication to be possible, the corresponding output files
# have to be transferred to the permanent storage element.
options.ofName += ".root"
process.TFileService = cms.Service("TFileService",
  fileName = cms.string("OutTree.root")
)

#####
##   Analysis parameters
#####
process.TNT = cms.EDAnalyzer("BSM3G_TNT_Maker",
  #### Running options
  # Choose which trigger you want (do NOT need to put * as it will consider all the versions by default)
  ifevtriggers      = cms.bool(False), # True means you want to require the triggers
  maxtriggerversion = cms.double(10), # please leave it as a double
  evtriggers        = cms.vstring(

    # ttH SL and DL triggers Jan 2017
    'HLT_IsoMu22_v',
    'HLT_IsoTkMu22_v',
    'HLT_IsoMu24_v',
    'HLT_IsoTkMu24_v',
    'HLT_Ele27_eta2p1_WPTight_Gsf_v',
    'HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v',
    'HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_DZ_v',# Not in ttjets reHLT
    'HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_v',
    'HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ_v',# Not in ttjets reHLT
    'HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_v',
    'HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_v',
    'HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_v',
    'HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ_v',
    'HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ_v',
     #Electron
     'HLT_Ele17_Ele12_CaloIdL_TrackIdL_IsoVL_DZ_v',
     #Muon
     'HLT_IsoMu20_v',
     'HLT_Mu17_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v',
     'HLT_Mu8_TrkIsoVVL_Ele17_CaloIdL_TrackIdL_IsoVL_v',
    #TTHLep
     #Electron
     'HLT_Ele23_WPLoose_Gsf_v', #Data
     'HLT_Ele23_CaloIdL_TrackIdL_IsoVL_v', #MC
     'HLT_Ele27_WPTight_Gsf_v',
     'HLT_Ele25_eta2p1_WPTight_Gsf_v',
     #Muon
     'HLT_IsoTkMu20_v',
     'HLT_IsoMu22_eta2p1_v',
     'HLT_IsoTkMu22_eta2p1_v',
     #Cross Ele-Mu
     'HLT_DiMu9_Ele9_CaloIdL_TrackIdL_v',
     'HLT_Mu8_DiEle12_CaloIdL_TrackIdL_v',
     'HLT_TripleMu_12_10_5_v',
     'HLT_Ele16_Ele12_Ele8_CaloIdL_TrackIdL_v',
     'HLT_Mu23_TrkIsoVVL_Ele8_CaloIdL_TrackIdL_IsoVL_v',
     'HLT_Mu23_TrkIsoVVL_Ele8_CaloIdL_TrackIdL_IsoVL_DZ_v',
     #Other
     'HLT_DoubleEle33_CaloIdL_GsfTrkIdVL_v',
     'HLT_Mu50_v',
     'HLT_TkMu50_v',
     'HLT_Ele115_CaloIdVT_GsfTrkIdT_v',
  ),
  # Choose which information you want to use
  fillgeninfo           = cms.bool(True),
  fillgenHFCategoryinfo = cms.bool(True),
  filleventinfo         = cms.bool(True),
  filltriggerinfo       = cms.bool(True), #F, for samples without trigger
  fillPVinfo            = cms.bool(True),
  fillmuoninfo          = cms.bool(True),
  fillelectronpatinfo   = cms.bool(True),
  filltauinfo           = cms.bool(True),
  filljetinfo           = cms.bool(True),
  filltthjetinfo        = cms.bool(False), #F
  fillBoostedJetinfo    = cms.bool(True),
  fillTopSubJetinfo     = cms.bool(False), #F
  fillTauJetnessinfo    = cms.bool(True),
  fillBJetnessinfo      = cms.bool(True),
  fillBJetnessFVinfo    = cms.bool(True),
  fillBTagReweight      = cms.bool(True),
  fillPileupReweight    = cms.bool(True),
  fillMETinfo           = cms.bool(True),
  fillphotoninfo        = cms.bool(False), #F
  analysisFilter        = cms.bool(True),
  # Choose format
  MiniAODv2 = cms.bool(True),
  is_data   = cms.bool(False),
  debug_    = cms.bool(False),
  super_TNT = cms.bool(False),
  AJVar     = cms.bool(False),
  tthlepVar = cms.bool(True),
  bjetnessselfilter = cms.bool(False),
  bjetnessproducer  = cms.bool(True),
  PuppiVar  = cms.bool(False),
  qglVar    = cms.bool(True),
  # Input tags
  bits                = cms.InputTag("TriggerResults","","HLT"),
  prescales           = cms.InputTag("patTrigger"),
  objects             = cms.InputTag("selectedPatTrigger"),
  vertices            = cms.InputTag("offlineSlimmedPrimaryVertices"),
  beamSpot            = cms.InputTag("offlineBeamSpot"),
  muons               = muonCollection,
  patElectrons        = electronCollection,
  electronVetoIdMap   = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-veto"),
  electronLooseIdMap  = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-loose"),
  electronMediumIdMap = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-medium"),
  electronTightIdMap  = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-tight"),
  eleMVATrigIdMap        = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring15-25ns-Trig-V1-wp80"),
  eleMVAnonTrigIdMap     = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring15-25ns-nonTrig-V1-wp80"),
  eleMVATrigwp90IdMap    = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring15-25ns-Trig-V1-wp90"),
  eleMVAnonTrigwp90IdMap = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring15-25ns-nonTrig-V1-wp90"),
  eleMVAGPwp90IdMap = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp90"),
  eleMVAGPwp80IdMap  = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-GeneralPurpose-V1-wp80"),
  eleMVAHZZwpLooseIdMap = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring16-HZZ-V1-wpLoose"),
  eleHEEPIdMap                 = cms.InputTag("egmGsfElectronIDs:heepElectronID-HEEPV70"),
  elemvaValuesMap_nonTrig      = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring15NonTrig25nsV1Values"),
  elemvaCategoriesMap_nonTrig  = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring15NonTrig25nsV1Categories"),
  elemvaValuesMap_Trig         = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring15Trig25nsV1Values"),
  elemvaCategoriesMap_Trig     = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring15Trig25nsV1Categories"),
  elemvaValuesMap_GP           = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16GeneralPurposeV1Values"),
  elemvaCategoriesMap_GP       = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16GeneralPurposeV1Categories"),
  elemvaValuesMap_HZZ          = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16HZZV1Values"),
  elemvaCategoriesMap_HZZ      = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Spring16HZZV1Categories"),
  taus                = tauCollection,
  jets                = jetCollection,
  jetsPUPPI           = jetPuppiCollection,
  fatjets             = fatjetCollection,
  topsubjets          = topsubjetCollection,
  mets                = METCollection,
  metsPUPPI           = METPuppiCollection,
  metFilterBits       = cms.InputTag("TriggerResults", "", "PAT"),
  photons             = photonCollection,
  packedPFCandidates  = cms.InputTag("packedPFCandidates"),
  pruned              = cms.InputTag("prunedGenParticles"),
  # =========== JER (Only applied to MC) ============
  jerAK4PFchs     =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_PtResolution_AK4PFchs.txt"),
  jerAK4PFchsSF   =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_SF_AK4PFchs.txt"),
  jerAK4PFPuppi   =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_PtResolution_AK4PFPuppi.txt"),
  jerAK4PFPuppiSF =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_SF_AK4PFPuppi.txt"),
  jerAK8PFchs     =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_PtResolution_AK8PFchs.txt"),
  jerAK8PFchsSF   =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_SF_AK8PFchs.txt"),
  jerAK8PFPuppi   =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_PtResolution_AK8PFPuppi.txt"),
  jerAK8PFPuppiSF =  cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_SF_AK8PFchs.txt"),
  # ===========  JEC - CORRECTIONS ON FLY ===========
  #=== MC ===
  # L1FastJet
  # L2Relative
  # L3Absolute
  # MC_Uncertainty
  jecPayloadNamesAK4PFchsMC1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L1FastJet_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsMC2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L2Relative_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsMC3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L3Absolute_AK4PFchs.txt"),
  #jecPayloadNamesAK4PFchsMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_Uncertainty_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_UncertaintySources_AK4PFchs.txt"),
  jecPayloadNamesAK4PFPuppiMC1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L1FastJet_AK4PFPuppi.txt"),
  jecPayloadNamesAK4PFPuppiMC2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L2Relative_AK4PFPuppi.txt"),
  jecPayloadNamesAK4PFPuppiMC3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L3Absolute_AK4PFPuppi.txt"),
  #jecPayloadNamesAK4PFPuppiMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_Uncertainty_AK4PFPuppi.txt"),
  jecPayloadNamesAK4PFPuppiMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_UncertaintySources_AK4PFPuppi.txt"),
  jecPayloadNamesAK8PFchsMC1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L1FastJet_AK8PFchs.txt"),
  jecPayloadNamesAK8PFchsMC2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L2Relative_AK8PFchs.txt"),
  jecPayloadNamesAK8PFchsMC3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L3Absolute_AK8PFchs.txt"),
  #jecPayloadNamesAK8PFchsMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_Uncertainty_AK8PFchs.txt"),
  jecPayloadNamesAK8PFchsMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_UncertaintySources_AK8PFchs.txt"),
  #=== DATA ===
  # Note that this is a config for MC.
  # The following Data JEC will not be
  # used but are needed to prevent the
  # BSMFramework code from crashing.
  jecPayloadNamesAK4PFchsDATA1   = cms.FileInPath('BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L1FastJet_AK4PFchs.txt'),
  jecPayloadNamesAK4PFchsDATA2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2Relative_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsDATA3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L3Absolute_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsDATA4   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2L3Residual_AK4PFchs.txt"),
  #jecPayloadNamesAK4PFchsDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_Uncertainty_AK4PFchs.txt"),
  jecPayloadNamesAK4PFchsDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_UncertaintySources_AK4PFchs.txt"),
  jecPayloadNamesAK8PFchsDATA1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L1FastJet_AK4PFPuppi.txt"),
  jecPayloadNamesAK8PFchsDATA2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2Relative_AK4PFPuppi.txt"),
  jecPayloadNamesAK8PFchsDATA3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L3Absolute_AK4PFPuppi.txt"),
  jecPayloadNamesAK8PFchsDATA4   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2L3Residual_AK4PFPuppi.txt"),
  #jecPayloadNamesAK8PFchsDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_Uncertainty_AK4PFPuppi.txt"),
  jecPayloadNamesAK8PFchsDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_UncertaintySources_AK4PFPuppi.txt"),
  jecPayloadNamesAK4PFPuppiDATA1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L1FastJet_AK8PFchs.txt"),
  jecPayloadNamesAK4PFPuppiDATA2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2Relative_AK8PFchs.txt"),
  jecPayloadNamesAK4PFPuppiDATA3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L3Absolute_AK8PFchs.txt"),
  jecPayloadNamesAK4PFPuppiDATA4   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2L3Residual_AK8PFchs.txt"),
  #jecPayloadNamesAK4PFPuppiDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_Uncertainty_AK8PFchs.txt"),
  jecPayloadNamesAK4PFPuppiDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_UncertaintySources_AK8PFchs.txt"),
  # PILEUP REWEIGHTING
  PUReweightfile      = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/PUReweight/PileUpReweightingMoriond17.root"),
  # BTAG REWEIGHTING
  BTAGReweightfile1   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/BTAGReweight/2017csvSFs/csv_rwt_fit_hf_v2_final_2017_1_10test.root"),
  BTAGReweightfile2   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/BTAGReweight/2017csvSFs/csv_rwt_fit_lf_v2_final_2017_1_10test.root"),
  BTAGReweightfile3   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/BTAGReweight/2017csvSFs/CSVv2_Moriond17_B_H.csv"),
  # Object selection
  # Primary vertex cuts
  Pvtx_ndof_min   = cms.double(4.),
  Pvtx_vtx_max    = cms.double(24.),
  Pvtx_vtxdxy_max = cms.double(24.),
  # Obj primary vertex cuts
  vtx_ndof_min        = cms.int32(4),
  vtx_rho_max         = cms.int32(2),
  vtx_position_z_max  = cms.double(24.),
  # Muon cuts
  Muon_pt_min         = cms.double(5.), #25.),#5.),
  Muon_eta_max        = cms.double(50), #2.1),#50),
  # Electron cuts
  patElectron_pt_min  = cms.double(5.), #30.),#5.),
  patElectron_eta_max = cms.double(50), #2.1),#50),
  # Tau cuts
  Tau_pt_min          = cms.double(15.), #30),#15.),
  Tau_eta_max         = cms.double(50), #2.1),#50.),
  # Jet cuts
  Jet_pt_min = cms.double(10.),#20.),#10.),
  # Photon cuts
  Photon_pt_min   = cms.double(5.0),
  Photon_eta_max  = cms.double(5.0),
  # ttHFCategorization
  genJetPtMin               = cms.double(genJetPtMin),
  genJetAbsEtaMax           = cms.double(genJetAbsEtaMax),
  genJets                   = cms.InputTag(genJetCollection),
  genBHadJetIndex           = cms.InputTag("matchGenBHadron", "genBHadJetIndex"),
  genBHadFlavour            = cms.InputTag("matchGenBHadron", "genBHadFlavour"),
  genBHadFromTopWeakDecay   = cms.InputTag("matchGenBHadron", "genBHadFromTopWeakDecay"),
  genBHadPlusMothers        = cms.InputTag("matchGenBHadron", "genBHadPlusMothers"),
  genBHadPlusMothersIndices = cms.InputTag("matchGenBHadron", "genBHadPlusMothersIndices"),
  genBHadIndex              = cms.InputTag("matchGenBHadron", "genBHadIndex"),
  genBHadLeptonHadronIndex  = cms.InputTag("matchGenBHadron", "genBHadLeptonHadronIndex"),
  genBHadLeptonViaTau       = cms.InputTag("matchGenBHadron", "genBHadLeptonViaTau"),
  genCHadJetIndex           = cms.InputTag("matchGenCHadron", "genCHadJetIndex"),
  genCHadFlavour            = cms.InputTag("matchGenCHadron", "genCHadFlavour"),
  genCHadFromTopWeakDecay   = cms.InputTag("matchGenCHadron", "genCHadFromTopWeakDecay"),
  genCHadBHadronId          = cms.InputTag("matchGenCHadron", "genCHadBHadronId"),
  badGlobalMuonTagger       = cms.InputTag("badGlobalMuonTagger"),
  cloneGlobalMuonTagger     = cms.InputTag("cloneGlobalMuonTagger"),

)

#####
##   Dump gen particle list
#####
process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi")
process.printGenParticleList = cms.EDAnalyzer("ParticleListDrawer",
  maxEventsToPrint = cms.untracked.int32(-1),
  printVertex = cms.untracked.bool(True),
  src = cms.InputTag("prunedGenParticles")
)

#process.p = cms.Path(process.printGenParticleList)
#BJetness producer
process.load('BJetnessTTHbb.BJetness.BJetness_cfi')
process.BJetness = cms.EDProducer('BJetness')
process.BJetness.is_data = cms.bool(False)
process.BJetness.vertices = cms.InputTag("offlineSlimmedPrimaryVertices")
process.BJetness.eleMVAnonTrigIdMap = cms.InputTag("egmGsfElectronIDs:mvaEleID-Spring15-25ns-nonTrig-V1-wp80")
process.BJetness.electronTightIdMap  = cms.InputTag("egmGsfElectronIDs:cutBasedElectronID-Summer16-80X-V1-tight")
process.BJetness.patElectrons = electronCollection
process.BJetness.muons = muonCollection
process.BJetness.jets = jetCollection
process.BJetness.jecPayloadNamesAK4PFchsMC1 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L1FastJet_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsMC2 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L2Relative_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsMC3 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_L3Absolute_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsMCUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/MC/Summer16_23Sep2016V4_MC/Summer16_23Sep2016V4_MC_UncertaintySources_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsDATA1 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L1FastJet_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsDATA2 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2Relative_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsDATA3 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L3Absolute_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsDATA4 = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_L2L3Residual_AK4PFchs.txt")
process.BJetness.jecPayloadNamesAK4PFchsDATAUnc = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JEC/DATA/Summer16_23Sep2016BCDV4_DATA/Summer16_23Sep2016BCDV4_DATA_UncertaintySources_AK4PFchs.txt")
process.BJetness.jerAK4PFchs   = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_PtResolution_AK4PFchs.txt")
process.BJetness.jerAK4PFchsSF = cms.FileInPath("BSMFramework/BSM3G_TNT_Maker/data/JER/Spring16_25nsV10_MC_SF_AK4PFchs.txt")
#QG likelihood
process.load('BSMFramework.BSM3G_TNT_Maker.QGTagger_cfi')
process.QGTagger.srcJets       = jetCollection
process.QGTagger.jetsLabel     = cms.string('QGL_AK4PFchs')

# Access badGlobalMuonTagger and cloneGlobalMuonTagger
# "_cff" files need to be associated with the process before you can access them/their methods via your process object.
# In order to do so one needs to make a clone of the python script template:

process.load("RecoMET.METFilters.BadPFMuonFilter_cfi")
from RecoMET.METFilters.BadPFMuonFilter_cfi import BadPFMuonFilter
process.BadPFMuonFilter = BadPFMuonFilter.clone(
    muons = muonCollection,
    PFCandidates = cms.InputTag("packedPFCandidates"),
)

process.load("RecoMET.METFilters.BadChargedCandidateFilter_cfi")
from RecoMET.METFilters.BadChargedCandidateFilter_cfi import BadChargedCandidateFilter
process.BadChargedCandidateFilter = BadChargedCandidateFilter.clone(
    muons = muonCollection,
    PFCandidates = cms.InputTag("packedPFCandidates"),
)

process.load("RecoMET.METFilters.badGlobalMuonTaggersMiniAOD_cff")
from RecoMET.METFilters.badGlobalMuonTaggersMiniAOD_cff import badGlobalMuonTaggerMAOD

process.badGlobalMuonTagger = badGlobalMuonTaggerMAOD.clone(
    taggingMode = cms.bool(True),
)

from RecoMET.METFilters.badGlobalMuonTaggersMiniAOD_cff import cloneGlobalMuonTaggerMAOD
process.cloneGlobalMuonTagger = cloneGlobalMuonTaggerMAOD.clone(
    taggingMode = cms.bool(True),
)

#Run analysis sequence
process.p = cms.Path(
#process.regressionApplication
#*process.calibratedPatElectrons
process.selectedHadronsAndPartons
*process.genJetFlavourInfos
*process.matchGenCHadron
*process.matchGenBHadron
*process.egmGsfElectronIDSequence
*process.BJetness
*process.BadPFMuonFilter
*process.BadChargedCandidateFilter
*process.badGlobalMuonTagger
*process.cloneGlobalMuonTagger
*process.TNT
)
#process.e = cms.EndPath(process.out)


import asyncio
from datetime import datetime, timedelta
import numpy as np
import pandas_market_calendars as mcal

# Create a calendar
from pandas import DatetimeIndex

# nyse = mcal.get_calendar('NYSE')
# holidays = nyse.holidays()
# dt2021 = np.datetime64(datetime(2021,1 ,1))
# for holiday in holidays.holidays:
#     if np.datetime64(datetime(2021,12,31)) > holiday > np.datetime64(datetime(2021,1 ,1)):
#         print(holiday)
#         print(type(holiday))
#
# day = datetime(2021,12,24)
# print(day)
#функция выдает Nй торговый день отсчитывая от start_day
async def next_business_day(start_day, business_days):
    nyse = mcal.get_calendar('NYSE')
    holidays = nyse.holidays().holidays
    ONE_DAY = timedelta(days=1)
    temp_day = start_day
    for i in range(0, business_days):
        next_day = temp_day + ONE_DAY
        # now_holiday = np.datetime64(next_day.date())
        # isholiday = now_holiday in holidays
        while next_day.weekday() in [5, 6] or np.datetime64(next_day.date()) in holidays:
            next_day += ONE_DAY
        temp_day = next_day
    print(temp_day)

    print(type(temp_day))
    return temp_day

async def count_tdays(start_day, last_day):
    nyse = mcal.get_calendar('NYSE')
    holidays = nyse.holidays().holidays
    ONE_DAY = timedelta(days=1)
    temp_day = start_day
    count = 0
    while temp_day < last_day:
        next_day = temp_day + ONE_DAY
        if temp_day.weekday() in [5, 6] or np.datetime64(next_day.date()) in holidays:
            temp_day = next_day
            continue
        count += 1
        temp_day = next_day
    print(count)
    return count

# asyncio.run(next_business_day(datetime.utcnow() + timedelta(days=-3), 4))
# asyncio.run(count_tdays(datetime.utcnow() + timedelta(days=-1), datetime.utcnow() + timedelta(days=+1)))


import sqlite3
from datetime import datetime
from dateutil.relativedelta import relativedelta

def get_db_connection():
    conn = sqlite3.connect('expense_tracker.db')
    conn.row_factory = sqlite3.Row
    return conn

user_id = 1
with get_db_connection() as conn:
    data = conn.execute("SELECT expenses.name, expenses.description, expenses.amount, expenses_category.category, expenses.date FROM expenses INNER JOIN expenses_category ON expenses.category = expenses_category.id WHERE user_id = ? AND expenses.date >= ? AND expenses.date < ? ORDER BY date DESC", (user_id, datetime.today().replace(day=1), (datetime.today() + relativedelta(day=31)))).fetchall()

dict = {}
for record in data:
    if record["category"] not in dict:
        dict[record["category"]] = float(record["amount"])
    else:
        dict[record["category"]] += float(record["amount"])

chart = []
chart.append(["Category", "Amount"])
for key, value in dict.items():
    chart.append([key, value])

print(len(chart))

print(datetime.today().replace(day=1))


print("    LOJA SUPER BARATÃO\n", "-" * 25)

custo_total = contador = mais_barato = 0
nome_mais_barato = ""

rodando = True
while rodando:
    nome = input("Nome do produto: ").strip().title()
    preco = float(input("Preço: R$"))
    custo_total += preco

    if custo_total == preco:
        mais_barato = preco
        nome_mais_barato = nome
    else:
        if preco < mais_barato:
            mais_barato = preco
            nome_mais_barato = nome
    if preco > 1000:
        contador += 1

    while True:
        resposta = input("Quer continuar? [S/N] ").strip().upper()
        if resposta == "S":
            break
        elif resposta == "N":
            rodando = False
            break

print(f"O total da compra foi R${custo_total:.2f}\nTemos {contador} produto(s) custando mais de R$1000.00")
print(f"O produto mais barato foi {nome_mais_barato} que custa R${mais_barato:.2f}")


import bpy
import random
from math import sqrt

L1=[] #hold list
L2=[] #main list
BallNumber=40

for i in range(3):
    x=random.randrange(0,16)
    L2.append(x)

while len(L2) < 3*BallNumber:
    for i in range(3):
        #coordinates
        x=random.randrange(0,16)
        L1.append(x)

    for i in range(0,len(L2),3):
        sayac = 1

        if(sqrt((L2[i]-L1[0])**2 + (L2[i+1]-L1[1])**2 + (L2[i+2]-L1[2])**2) <2):
            sayac=sayac-1
            break;

    if(sayac == 1):
        L2.append(L1[0])
        L2.append(L1[1])
        L2.append(L1[2])

    L1.clear()
    print ('Liste2tekrar' , L2)

    #create
for i in range(0,len(L2),3):
    bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(L2[i], L2[i+1], L2[i+2]), scale=(1, 1, 1))


import datetime
import re
import htmlentitydefs
import urllib

from pyramid.security import authenticated_userid
from pyramid.traversal import resource_path
from repoze.lemonade.content import create_content
from karl.models.interfaces import IContainerVersion
from karl.models.interfaces import IObjectVersion

from repoze.folder import Folder
from zope.interface import implements

from pyramid.traversal import resource_path
from pyramid.url import resource_url

from karl.models.tool import ToolFactory
from karl.models.interfaces import IToolFactory

from karl.content.models.adapters import extract_text_from_html
from karl.content.interfaces import IWiki
from karl.content.interfaces import IWikiPage

pattern = re.compile(r'\(\(([\w\W]+?)\)\)') # wicked-style
WICKED = '((%s))'

def _ijoin(a,b):
    """yield a0,b0,a1,b1.. if len(a) = len(b)+1"""
    yield(a[0])
    for i in range(1,len(a)):
        yield(b[i-1])
        yield(a[i])

class Wiki(Folder):
    implements(IWiki)
    title = text = u'Wiki'

    def __init__(self, creator):
        super(Wiki, self).__init__()
        self.creator = creator
        self._create_front_page()

    def _create_front_page(self):
        self['front_page'] = create_content(
            IWikiPage,
            u'Front Page',
            FRONT_PAGE_CONTENT,
            FRONT_PAGE_DESCRIPTION,
            self.creator,
            )

    def __delitem__(self, name):
        super(Wiki, self).__delitem__(name)
        if name == 'front_page':
            self._create_front_page()

_rm_chars = re.compile('[\W]', re.U)
def _eq_loose(s1, s2):
    """
    Performs a 'loose' string comparison--case insenstitive, ignoring
    non-alphanumeric characters and unescaping any html entities.
    """
    s1 = _unescape(s1)
    s2 = _unescape(s2)
    s1 = _rm_chars.sub('', s1.lower())
    s2 = _rm_chars.sub('', s2.lower())
    return s1 == s2

def _unescape(text):
    def fixup(m):
        text = m.group(0)
        if text[:2] == "&#":
            # character reference
            try:
                if text[:3] == "&#x":
                    return unichr(int(text[3:-1], 16))
                else:
                    return unichr(int(text[2:-1]))
            except ValueError:
                pass
        else:
            # named entity
            try:
                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
            except KeyError:
                pass
        return text # leave as is
    return re.sub("&#?\w+;", fixup, text)

class WikiPage(Folder):
    implements(IWikiPage)
    modified_by = None

    def __init__(self, title=u'', text=u'', description=u'', creator=u''):
        super(WikiPage, self).__init__()
        self.title = unicode(title)
        if text is None:
            self.text = u''
        else:
            self.text = unicode(text)
        if description is None:
            self.description = u''
        else:
            self.description = unicode(description)
        self.creator = unicode(creator)
        self.modified_by = self.creator

    def change_title(self, title):
        title = unicode(title)
        if not pattern.match(WICKED % title):
            raise ValueError(title)
        pages = self.__parent__.values()

        for page in pages:
            if page is not self and page.title == title:
                raise ValueError('Duplicate page title "%s"' % title)

        for page in pages:
            subs = []
            chunks = pattern.split(page.text)
            for linked_name in chunks[1::2]:
                if _eq_loose(self.title, linked_name):
                    subs.append(WICKED % title)
                else:
                    subs.append(WICKED % linked_name)
            page.text = u''.join(_ijoin(chunks[::2], subs))
        self.title = title

    def cook(self, request):

        chunks = pattern.split(self.text)
        if len(chunks) == 1: # fastpath
            return self.text

        subs = []

        # Every other chunk is a wiki link
        for wikilink in chunks[1::2]:
            cleaned = extract_text_from_html(wikilink)
            for page in self.__parent__.values():
                if _eq_loose(page.title, cleaned):
                    url = resource_url(page, request)
                    subs.append(WIKI_LINK % (url, wikilink))
                    break
            else:
                quoted = urllib.quote(cleaned.encode('UTF-8'))
                subs.append(ADD_WIKIPAGE_LINK % (
                        wikilink, quoted))

        # Now join the two lists (knowing that len(text) == subs+1)
        return u''.join(_ijoin(chunks[::2], subs))

    def fix_links(self):
        """Change all loose wiki links to exact links.

        Returns a list of changes: [(old link, new link)]
        """
        changes = []  # [(old link, new link)]

        def replace(match):
            old_link = match.group(1)
            link = old_link.strip()
            page = self.__parent__.get(link)
            if page is None:
                for page in self.__parent__.values():
                    if _eq_loose(page.title, link):
                        link = page.title
                        break
            if link != old_link:
                changes.append((old_link, link))
            return "((%s))" % link

        new_text = pattern.sub(replace, self.text)
        if changes:
            self.text = new_text
        return changes

    def get_attachments(self):
        return self

    def revert(self, version):
        # catalog document map blows up if you feed it a long int
        self.docid = int(version.docid)
        self.created = version.created
        self.title = version.title
        self.description = version.description
        self.modified = version.modified
        self.text = version.attrs['text']
        self.creator = version.attrs['creator']
        self.modified_by = version.user

FRONT_PAGE_CONTENT = u"""\
This is the front page of your wiki.
"""

FRONT_PAGE_DESCRIPTION = u"""\
This is the front page of your wiki.
"""

ADD_WIKIPAGE_LINK = (
u'%s '
 '+'
)

WIKI_LINK = (
u'%s'
)

class WikiToolFactory(ToolFactory):
    implements(IToolFactory)
    name = 'wiki'
    interfaces = (IWiki, IWikiPage)
    def add(self, context, request):
        creator = authenticated_userid(request)
        wiki = create_content(IWiki, creator)
        context['wiki'] = wiki

    def remove(self, context, request):
        del context['wiki']

wiki_tool_factory = WikiToolFactory()

class WikiPageVersion(object):
    implements(IObjectVersion)

    def __init__(self, page):
        self.title = page.title
        self.description = page.description
        self.created = page.created
        self.modified = page.modified
        self.docid = page.docid
        self.path = resource_path(page)
        self.attrs = dict((name, getattr(page, name)) for name in [
            'text',
            'creator',
        ])
        self.attachments = None
        self.klass = page.__class__ # repozitory can't detect we are a shim
        self.user = page.modified_by
        if self.user is None:
            self.user = page.creator
        self.comment = None

class WikiContainerVersion(object):
    implements(IContainerVersion)

    def __init__(self, wiki):
        self.container_id = wiki.docid
        self.path = resource_path(wiki)
        self.map = dict((name, page.docid) for name, page in wiki.items())
        self.ns_map = {}

class WikiPageContainerVersion(object):
    implements(IContainerVersion)

    def __init__(self, page):
        self.container_id = page.docid
        self.path = resource_path(page)
        self.map = dict((name, attachment.docid)
                        for name, attachment in page.items())
        self.ns_map = {}


from tf_agents.environments import TFPyEnvironment
from tf_agents.policies import PolicySaver, policy_saver
import tensorflow as tf
from tf_agents.drivers.dynamic_step_driver import DynamicStepDriver
import numpy as np

from SnakeEnv import SnakeEnv

policy_dir = 'Policy_2023-07-17_80000'
saved_policy = tf.saved_model.load(policy_dir)

env = SnakeEnv()
env.seed(43)
env.reset()
np.random.seed(42)
tf_env = TFPyEnvironment(env)

total_score2 = 0

def save_frames(trajectory):
    global total_score2
    total_score2 += tf_env.pyenv.current_time_step().reward[0]

watch_driver = DynamicStepDriver(
    tf_env,
    saved_policy,
    observers=[save_frames],
    num_steps=10000)
final_time_step, final_policy_state = watch_driver.run()
print(f'\nafter training score: {total_score2}')


# Name: Gerardo Palacios
# Date: 11/26/2020
# Honor Statement: I have not given or received any unauthorized assistance on this assignment
# YouTube Link: https://youtu.be/DXaabepMEvw

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

class SixSidedDie:
    """A simulation of a six-sided dice.

    Attributes
    ----------
    face_value : int
        Current face value of the simulated dice

    num_sides : int
        Number of sides of the simulated dice"""

    face_value = int()
    num_sides = 6

    def roll(self):
        """Simulate rolling the dice and return face value."""

        self.face_value = random.randint(1, self.num_sides)
        return self.face_value

    def getFaceValue(self):
        """Read the current face value of the dice."""

        return self.face_value

    def __repr__(self):
        """Canonical string representation of class name and current face value"""

        repr_msg = '{}({})'.format(self.__class__.__name__, self.face_value)
        return repr_msg

class TenSidedDie(SixSidedDie):
    """A simulation of a ten-sided dice.

    Attributes
    ----------
    face_value : int
        Current face value of the simulated dice

    num_sides : int
        Number of sides of the simulated dice"""

    num_sides = 10

class TwentySidedDie(SixSidedDie):
    """A simulation of a twenty-sided dice.

    Attributes
    ----------
    face_value : int
        Current face value of the simulated dice

    num_sides : int
        Number of sides of the simulated dice"""

    num_sides = 20

class SimulatedData:
    """Simulation data handler."""

    def __init__(self):
        # initialize empty attributes

        self.parameters = {}
        self.data = pd.DataFrame({
            'actors': [],
            'jailed': [],
            'wealth': [],
            'thieves': [],
            'lieutenants': [],
            'jailed_thieves': [],
            'jailed_lieutenants': [],
            'collected': [],
            'recovered': [],
            'bribes': []
        })
        self.heists = pd.DataFrame({
            'heist_value': [],
            'solve_probability': [],
            'detective_assigned': [],
            'recovered_wealth': [],
        })
        self.weekly_collection = 0
        self.weekly_thieves = 0
        self.weekly_lieutenants = 0
        self.weekly_jailed_thieves = 0
        self.weekly_jailed_lieutenants = 0
        self.weekly_recovered_assets = 0

    def load_parameters(self, filename):
        """Load parameters from work directory csv file."""
        self.parameters = pd.read_csv(filename).to_dict('records')[0]

    def add_new_row(self, df, new_row):
        """Adds new row data frame.

        Parameters
        ----------
        df : str
            Name of data frame to add new row
        new_row
            Data for new row
        """

        if df == 'data':
            self.data = self.data.append(new_row, ignore_index=True)

        elif df == 'heists':
            self.heists = self.heists.append(new_row, ignore_index=True)

    def replace_row(self, df, row_index, new_row, columns=None):
        """Replaces elements for entire row or row and column.

        Parameters
        ----------
        df : str
            Name of data frame

        row_index : int
            Row index for data frame to look at.

        new_row : int or list of ints
            Data to replace row

        columns : str optional(default=None)
            Name of column to replace in row

        """

        if df == 'data':
            if columns is None:
                self.data.loc[row_index] = new_row
            else:
                self.data.loc[row_index:row_index, columns] = new_row

        elif df == 'heists':
            if columns is None:
                self.heists.loc[row_index] = new_row
            else:
                self.heists.loc[row_index:row_index, columns] = new_row

    def get_row(self, df, row_index):
        """Returns a pandas data frame for the given row index.

        Parameters
        ----------
        df : str
            Name of data frame to add new row

        row_index : int
            Row index for data frame to look at.
        """

        if df == 'data':
            return self.data.loc[row_index]

        elif df == 'heists':
            return self.heists.loc[row_index]

    def create_potential_heists(self):
        """Creates a randomly generated data frame for potential heists."""

        # calculate number of potential heists
        num_heists = int(self.data['thieves'].sum() - self.data['jailed_thieves'].sum())

        # Create random data frame
        self.heists = pd.DataFrame({
            'heist_value': [self.parameters['heist_coefficient']*(twenty_sided.roll()**2) for i in range(num_heists)],
            'solve_probability': np.random.rand(num_heists).tolist(),  # Create a list of n random numbers
            'detective_assigned': [-1] * num_heists,  # start out with no detectives assigned to heist
            'recovered_wealth': [0] * num_heists,  # start out with no recovered wealth
        })

    def reset_stats(self):
        """Resets weekly collected stats."""

        self.weekly_collection = 0
        self.weekly_thieves = 0
        self.weekly_lieutenants = 0
        self.weekly_jailed_thieves = 0
        self.weekly_jailed_lieutenants = 0
        self.weekly_recovered_assets = 0

    def save_results(self, filename, columns=('actors', 'jailed', 'wealth', 'bribes')):
        """Save results to csv file

        Parameters
        ----------

        filename : str
            File name including file extension '.csv'
        columns : list of str optional(default=['actors', 'jailed', 'wealth', 'bribes'])
            Columns to be saved to file. Default are actors, jailed, wealth, and bribes

        """
        df = self.data.loc[:, columns]
        df.to_csv(filename)

    def plot_time_series(self, title, stat):
        """Pleasantly displays current board"""

        plt.title(title)
        if isinstance(stat, list):
            for var in stat:
                plt.plot(self.data.index, self.data[var], linestyle='solid')
        else:
            plt.plot(self.data.index, self.data[stat], linestyle='solid')

        plt.yticks(rotation=45)
        plt.xticks(rotation=45)
        plt.show()

class Thief:
    """Low ranking actor in Mr. Biggs crime syndicate

    Attributes
    ----------

    wallet : int
        Collected profits for thief.

    jail : bool
        Boolean if thief has been apprehended
    """

    def __init__(self):
        self.wallet = 0
        self.jail = False
        self.new_recruit()

    def new_recruit(self):
        """Add a new recruit to the weekly stats."""

        simulated_data.weekly_thieves += 1

    def collect_heist(self):
        """Collect bounty from random heist."""

        select = None
        # initialize the total number of heists available
        number_of_heists = int(simulated_data.data['thieves'].sum() - simulated_data.data['jailed_thieves'].sum())

        # Assign a random heist that has not been assigned yet
        while select in crymland.syndicate.heists_assigned or select is None:
            select = random.randint(0, number_of_heists - 1)

        # Record assigned heist
        crymland.syndicate.heists_assigned.update({select: True})
        # Get heist data
        heist_data = simulated_data.get_row('heists', select)
        kickback = self.check_collection(heist_data, select)
        return kickback

    def check_collection(self, heist_data, row_index):
        """Evaluates if thief gets away or gets arrested. Returns kickback to boss.

        Parameters
        ----------
        heist_data : pandas data frame
            Assigned heist data

        row_index : int
            Assigned heist data frame row index
        """

        if heist_data['heist_value'] == -1:  # Detective solved this crime
            taken_away = heist_data['recovered_wealth'] + self.wallet  # Bounty AND wealth is recovered
            simulated_data.replace_row('heists', row_index, taken_away, 'recovered_wealth')  # Saved recovered to df
            simulated_data.weekly_jailed_thieves += 1  # add 1 to weekly stats
            simulated_data.weekly_recovered_assets += self.wallet
            self.wallet = 0  # Zero out wallet
            self.jail = True  # Set jail to true
            return -1

        else:  # Thief got away!
            simulated_data.weekly_collection += heist_data['heist_value']  # Save total collected
            profit = heist_data['heist_value'] * 0.50  # Keep half, kickback half
            self.wallet += profit
            return profit

class Lieutenant(Thief):
    """Mid ranking actor in Mr. Biggs crime syndicate.

    Attributes
    ----------

    wallet : int
        Collected profits for thief.

    jail : bool
        Boolean if thief has been apprehended

    thieves : dict of Thief class
        Dictionary of Thieves being managed.

    lieutenants : dict of Lieutenant class
        Dictionary of Lieutenants being managed.

    in_jail : int
        Number of actors on team that are in jail.

    """

    def __init__(self):
        super().__init__()
        self.thieves = {i: Thief() for i in range(simulated_data.parameters['num_thieves'])}
        self.lieutenants = {}
        self.in_jail = 0
        self.new_recruit()

    def new_recruit(self):
        """Add a new recruit to the weekly lieutenant stats."""

        simulated_data.weekly_lieutenants += 1

    def collect_heist(self):
        """Collect kickbacks from team."""

        collection = self.check_collection(self.check_thieves() + self.check_lieutenants())
        self.promote_thieves()

        return collection

    def check_thieves(self):
        """Collect kickbacks from low ranking actors. Returns total thief kickbacks"""

        collection = 0  # initialize empty collection variable
        remove_thieves = []  # initialize empty list
        for thief in self.thieves:  # iterate through thief list
            value = self.thieves[thief].collect_heist()

            if value > 0:  # Thief gave you proper kickback
                collection += value * 0.50
            else:  # He got caught
                self.in_jail += 1  # Record jailed actor
                remove_thieves.append(thief)  # Add actor in jail to list

        for thief in remove_thieves:  # Remove jailed actors from team
            self.thieves.pop(thief)

        return collection

    def check_lieutenants(self):
        """Collect kickbacks from mid ranking actors. Returns total lieutenant kickbacks"""

        collection = 0  # initialize empty collection variable
        remove_lieutenants = []  # initialize empty list
        for lieutenant in self.lieutenants:  # iterate through lieutenant list
            value = self.lieutenants[lieutenant].collect_heist()  # Check kickbacks

            if value > 0:  # Lieutenant gives proper kickback
                collection += value * 0.50
            else:  # Lieutenant in jail
                self.in_jail += 1
                remove_lieutenants.append(lieutenant)

        for lieutenant in remove_lieutenants:  # Remove jailed lieutenants from team
            self.lieutenants.pop(lieutenant)

        return collection

    def promote_thieves(self):
        """Promote a low-ranking thief to a mid-ranking lieutenant."""
        remove = []  # initialize empty list
        if not self.in_jail:  # Can't promote from jail
            for thief in self.thieves:  # iterate through thieves

                # if thieves have achieved a personal wealth greater than set parameter... promote
                if self.thieves[thief].wallet >= simulated_data.parameters['promotion_wealth']:
                    self.lieutenants.update({thief: Lieutenant()})  # create a new lieutenant
                    self.lieutenants[thief].wallet = self.thieves[thief].wallet  # transfer wealth
                    remove.append(thief)

            for remove_thief in remove:  # remove promoted thief from thief team. No longer commit heists.
                self.thieves.pop(remove_thief)

    def check_collection(self, collection, **kwargs):
        """Checks if collected actors talked in jail. Returns False or kickbacks."""

        # if thieves/LTs have grouped more than given parameter. go to jail.

        if self.in_jail >= simulated_data.parameters['jailed_thieves']:  # Too many members talked
            simulated_data.weekly_jailed_lieutenants += 1
            simulated_data.weekly_recovered_assets += self.wallet + collection
            self.jail = True
            self.wallet = 0
            return -1
        else:
            self.wallet += collection  # Add to personal wealth
            return collection

class Syndicate:
    """Mr. Biggs crime syndicate.

    Attributes
    ----------

    bigg : object
        Object of class Lieutenant. Mr. Bigg.

    heists_assigned : dict
        dictionary of already assigned heists.

    successful_bribes : int
        Number of successful bribes

    """

    def __init__(self):
        self.bigg = Lieutenant()
        self.heists_assigned = {}
        self.successful_bribes = 0

    def reset_stats(self):
        """Reset heists assigned."""

        self.heists_assigned = {}

    def initiate_heists(self):
        """Inform syndicate to being heists."""

        self.bigg.collect_heist()

    def bribes(self):
        """Attempt to bribe detectives that have seized large portion of assets."""

        for detective in crymland.academy.detectives:  # Iterate through detectives
            # Get parameters
            detective = crymland.academy.detectives[detective]
            assets = detective.get_recovered_assets()
            first, after = simulated_data.parameters['seizes_first'], simulated_data.parameters['seizes_thereafter']
            bribe_rate, weekly_collection = simulated_data.parameters['initial_bribe'], simulated_data.weekly_collection

            # Whenever a detective first seizes a total of $1,000,000 from thieves or lieutenants, and every
            # $1,000,000 thereafter, Mr. Bigg attempts to bribe the detective

            if assets >= first and assets >= first + after * self.successful_bribes:
                if detective.evaluate_bribe(bribe_rate * weekly_collection):
                    self.successful_bribes += 1

class Academy:
    """Detective Agency.

    Attributes
    ----------

    detectives : dict
        Dictionary of dedicated detectives.

    """

    def __init__(self):
        self.detectives = {i: Detective() for i in range(simulated_data.parameters['num_detectives'])}
        self.detectives_assigned = {}

    def reset_stats(self):
        """Resets stats."""

        self.detectives_assigned = {}
        for detective in self.detectives:
            self.detectives[detective].bribe_assets = 0

    def assign_heists(self):
        """Assigned detectives on team a heist to investigate."""

        for detective in self.detectives:  # Iterate through each detective
            select = None  # Initialize empty variable
            number_of_heists = int(  # Calculate total number of current heists.
                simulated_data.data['thieves'].sum() - simulated_data.data['jailed_thieves'].sum())

            if detective < number_of_heists:  # As long as there heists left to assign
                while select in self.detectives_assigned or select is None:  # assign a random heist
                    select = random.randint(0, number_of_heists - 1)

                # Record assigned heist
                self.detectives_assigned.update({select: detective})
                # Assign heist
                simulated_data.replace_row('heists', select, detective, 'detective_assigned')

                # Order detective to investigate heist
                self.detectives[detective].investigate(select)

    def review_recovered_assets(self):
        """Review and tally recovered assets from detectives."""

        for detective in self.detectives:  # iterate through detectives
            recovered = simulated_data.heists.loc[  # get data assigned from heist
                simulated_data.heists['detective_assigned'] == detective]

            # Tally the recovered assets
            if recovered['recovered_wealth'].to_list():
                self.detectives[detective].new_recovered_assets(int(recovered['recovered_wealth']))

    def fight_corruption(self):
        """Replace corrupt detectives with an uncorrupted detective."""

        for detective in self.detectives:  # iterate through detectives
            if self.detectives[detective].bribed:  # if corrupted
                search_chance = random.random()

                if search_chance <= self.detectives[detective].discovery_risk:  # attempt to catch
                    self.detectives.update({detective: Detective()})
                else:
                    self.detectives[detective].discovery_risk += twenty_sided.roll() / 100
                    # increase chances of discovery

class Detective:
    """Dedicated detective.

    Attributes
    ----------

    solve_rate : float
        probability detective solves heist.

    solve_cap : float
        max probability detective can solve a heist.

    bribed : bool
        Boolean if detective is bribed.

    bribe_assets : float
        Value of accepted bribe.

    recovered_assets : float
        Value of total recovered assets from investigations.

    discovery_risk : float
        Probability of being caught as a corrupted detective.

    """

    def __init__(self):
        self.solve_rate = simulated_data.parameters['solve_init']
        self.solve_cap = simulated_data.parameters['solve_cap']
        self.bribed = False
        self.bribe_assets = 0
        self.recovered_assets = 0
        self.discovery_risk = 0

    def get_recovered_assets(self):
        """Return the total recovered assets from detective"""

        return self.recovered_assets

    def gain_experience(self):
        """Improve investigation experience."""

        self.solve_rate += ten_sided.roll() / 100  # increase experience

        if self.solve_rate >= self.solve_cap:  # Cap experience
            self.solve_rate = self.solve_cap

    def investigate(self, heist_index):
        """Investigate assigned heist"""

        heist = simulated_data.get_row('heists', heist_index)  # Get heist data
        if not self.bribed and heist['solve_probability'] <= self.solve_rate:  # If not corrupted. Attempt to solve
            saved = heist['heist_value']  # Collect heist_value
            simulated_data.replace_row('heists', heist_index, saved, ['recovered_wealth'])  # Add to recovered wealth
            simulated_data.replace_row('heists', heist_index, -1, ['heist_value'])  # negate heist value
            self.gain_experience()  # Gain experience due to successful investigation

    def new_recovered_assets(self, new):
        """Add to current recovered assets."""

        self.recovered_assets += new
        return self.recovered_assets

    def evaluate_bribe(self, bribe):
        """Evaluate bribe from Mr.Biggs. Returns True if bribe is accepted """

        # Evaluate bribe
        if bribe <= 10000:
            probability = .05

        elif bribe <= 100000:
            probability = .1

        elif bribe <= 1000000:
            probability = .25

        else:
            probability = .5
        # calculate probability
        random_prob = random.random()
        if random_prob <= probability:

            # Accept bribe and become a corrupted detective
            self.bribed = True
            self.bribe_assets += bribe
            self.discovery_risk = simulated_data.parameters['initial_risk']

            return True
        else:
            return False

class Crymland:
    """Land of Crymland.

    Attributes
    ----------

    syndicate : object
        Object of class Syndicate.
    academy : object
        Object of class Academy

    """

    def __init__(self):
        self.syndicate = Syndicate()
        self.academy = Academy()

    def run_sim(self, weeks):
        """Run simulation for the given number of weeks."""

        # Begin with starting stats
        self.record_weekly_stats()
        i = 0
        # Do until end of simulation or until the syndicate has been taken down.
        while i <= weeks and not self.syndicate.bigg.jail:
            simulated_data.create_potential_heists()                        # Create random potential heists
            self.academy.assign_heists()                                    # The Academy assign detectives to the cases
            self.syndicate.initiate_heists()                                # Syndicate begins heists
            self.academy.review_recovered_assets()                          # Detectives review their recovered assets
            self.syndicate.bribes()                                         # Syndicate attempts to bribe detectives
            self.academy.fight_corruption()                                 # The Academy attempts to fight corruption
            self.record_weekly_stats()                                      # Log stats
            i += 1                                                          # Iterate the next week

    def record_weekly_stats(self):
        """Record stats for current week."""

        # Calculate total jailed
        total_jailed = simulated_data.data['jailed_thieves'].sum() + simulated_data.data['jailed_lieutenants'].sum()
        total_jailed += simulated_data.weekly_jailed_thieves + simulated_data.weekly_jailed_lieutenants

        total_actors = simulated_data.data['thieves'].sum() + simulated_data.data['lieutenants'].sum()
        total_actors += simulated_data.weekly_thieves + simulated_data.weekly_lieutenants - 1

        # Create new row to add to data frame
        new_row = {
            'actors': total_actors - total_jailed,
            'jailed': total_jailed,
            'wealth': self.syndicate.bigg.wallet,
            'thieves': simulated_data.weekly_thieves,
            'lieutenants': simulated_data.weekly_lieutenants,
            'jailed_thieves': simulated_data.weekly_jailed_thieves,
            'jailed_lieutenants': simulated_data.weekly_jailed_lieutenants,
            'collected': simulated_data.weekly_collection,
            'recovered': simulated_data.weekly_recovered_assets,
            'bribes': sum([self.academy.detectives[detective].bribe_assets for detective in self.academy.detectives])
        }

        # add new row to data frame
        simulated_data.add_new_row('data', new_row)

        # Reset weekly stats
        simulated_data.reset_stats()
        self.academy.reset_stats()
        self.syndicate.reset_stats()

if __name__ == '__main__':
    # Sample parameters1.csv file to upload data from.

    # weeks,num_thieves,heist_coefficient,promotion_wealth,jailed_thieves,num_detectives,solve_init,solve_cap,seizes_first,seizes_thereafter,initial_risk,initial_bribe
    # 500,7,1000,1000000,3,3,.25,0.75,1000000,1000000,0.05,0.1

    # Generate a twenty sided and ten sided die
    twenty_sided = TwentySidedDie()
    ten_sided = TenSidedDie()

    scenarios = ['parameters/parameters1.csv', 'parameters/parameters2.csv', 'parameters/parameters3.csv']

    for i in range(len(scenarios)):
        # Create Data handler
        simulated_data = SimulatedData()

        # load data parameters
        simulated_data.load_parameters(scenarios[i])

        # Create Crymland
        crymland = Crymland()

        # Run simulation
        crymland.run_sim(simulated_data.parameters['weeks'])

        # Plot results
        simulated_data.plot_time_series('Syndicate Size vs Total Apprehended', ['actors', 'jailed'])
        simulated_data.plot_time_series('Personal Wealth of Mr.Bigg', 'wealth')
        simulated_data.plot_time_series('Accepted Bribes', 'bribes')

        # Save results
        simulated_data.save_results('results/simulation_results{}.csv'.format(i))