import logging
import os

from optparse import make_option

from django.core.management.base import CommandError

from multiprocessing import Pool, cpu_count

from softwarecollections.management.commands import LoggingBaseCommand
from softwarecollections.scls.models import OtherRepo

logger = logging.getLogger(__name__)

def centos_sync(args):
    repo, timeout = args
    logger.info('Syncing {}'.format(repo))
    try:
        repo.sync(timeout)
    except Exception as e:
        logger.error('Failed to sync {}: {}'.format(repo, e))
        return 1
    return 0

class Command(LoggingBaseCommand):
    option_list = LoggingBaseCommand.option_list + (
        make_option(
            '-P', '--max-procs', action='store', dest='max_procs', default=cpu_count(),
            help='Run up to MAX_PROCS processes at a time (default {})'.format(cpu_count())
        ),
        make_option(
            '-t', '--timeout', action='store', dest='timeout', default=None,
            help='Timeout in seconds for each step of centos (repocentos, rpmbuild, createrepo, dump_provides)',
        ),
    )

    help = 'Refresh other repos information.'

    def handle(self, *args, **options):
        self.configure_logging(options['verbosity'])
        timeout = options['timeout'] and int(options['timeout'])
        with Pool(processes=int(options['max_procs'])) as pool:
            errors = sum(pool.map(
                centos_sync,
                [(repo, timeout) for repo in OtherRepo.objects.all()],
            ))
            if errors > 0:
                raise CommandError('Failed to sync other repos: {} error(s)'.format(errors))


# KunShan Assignment 6
# q1a
def natureNumbers(n: int) -> None:
    def natureNumber(n: int) -> None:
        if n <= 1:
            print('1', end=' ')
        else:
            natureNumber(n - 1)
            print(n, end=' ')
    natureNumber(n)
    print()

# q2a
def alt(s: str, t: str) -> str:
    if len(s) == 0 or len(s) != len(t):
        return ''
    else:
        return s[0]+t[0]+alt(s[1:], t[1:])

# q2
def factorial(n: int) -> int:
    res = 1
    for i in range(1, n+1):
        res *= i
    return res

def factorialRecur(n: int) -> int:
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorialRecur(n - 1)

def checkTime(func, arg):
    t1 = time.time()
    func(arg)
    t2 = time.time()
    return t2 - t1

if __name__ == '__main__':
    # q1a
    natureNumbers(10)
    natureNumbers(100)
    # q1b
    print(alt('hello', 'world'))
    print(alt('hello,', 'world!'))
    print(alt('hello', 'world!'))
    # q2
    import matplotlib.pyplot as plt
    import time
    k, step = 2_000, 1
    x = [n for n in range(0, k, step)]
    lst1 = [checkTime(factorial, n) for n in x]
    lst2 = [checkTime(factorialRecur, n) for n in x]
    plt.plot(x, lst1, label='Iter')
    plt.plot(x, lst2, label='Recu')
    plt.legend()
    plt.show()


# LC146. LRU Cache, top100
class LRUCache:
    def __init__(self, capacity: int): # use ordered dict, language specific
        self.capacity = capacity
        self.values = collections.OrderedDict()
    def get(self, key: int) -> int:  # O(1)
        if key not in self.values: return -1
        self.values.move_to_end(key)  # O(1)  # last is new, first is old
        return self.values[key]
    def put(self, key: int, value: int) -> None:  # O(1)
        if key in self.values: self.values.move_to_end(key) # update
        self.values[key] = value
        if len(self.values) > self.capacity: self.values.popitem(last=False)  # O(1)

# LC460. LFU Cache, BBG
class LFUCache:
    def __init__(self, capacity: int):
        self.capa = capacity
        self.k2freq = {} # key to node
        self.f2kv = defaultdict(dict)  # count to node
        self.minf = 1
    def get(self, key: int) -> int:
        if key not in self.k2freq: return -1
        x = self.k2freq.pop(key) # get freq
        v = self.f2kv[x].pop(key) # get value
        self.k2freq[key] = x + 1 # update freq
        self.f2kv[x+1][key] = v # move to new freq
        if not self.f2kv[x] and self.minf == x:
            self.minf += 1 # if x is only min, bump up
        return v
    def put(self, key: int, value: int) -> None:
        if self.capa <= 0: return
        if key in self.k2freq:
            self.get(key) # update status
            self.f2kv[self.k2freq[key]][key] = value
            return
        if len(self.k2freq) >= self.capa:
            k = next(iter(self.f2kv[self.minf])) # first in dict
            self.f2kv[self.minf].pop(k)
            self.k2freq.pop(k)
        self.k2freq[key] = 1
        self.f2kv[1][key] = value
        self.minf = 1

# LC432. All O`one Data Structure - we need 2 markers, minf and max, string counters
class Node(object):
    def __init__(self, val, prev=None, next=None):
        self.val = val # counter
        self.prev = prev # double linked list
        self.next = next
        self.keys = set() # keys with this freq

class AllOne: # O(1) for all ops
    def __init__(self):
        self.head = Node(0) # min on head, max on tail
        self.tail = Node(0, self.head)
        self.head.next = self.tail
        self.key2node = defaultdict(lambda: self.head)
    def inc(self, key: str) -> None:
        cur = self.key2node[key] # get curr count, key to freq
        cur.keys.discard(key)
        if cur.val + 1 == cur.next.val: new = cur.next
        else:
            new = Node(cur.val + 1, cur, cur.next)
            new.prev.next = new.next.prev = new
        new.keys.add(key)
        self.key2node[key] = new # inc counter
        if not cur.keys and cur.val != 0: # delete curr count node if empty
            cur.prev.next, cur.next.prev = cur.next, cur.prev
    def dec(self, key: str) -> None:
        if not key in self.key2node: return
        cur = self.key2node[key]
        cur.keys.discard(key)
        self.key2node.pop(key)
        if cur.val > 1:
            if cur.val - 1 == cur.prev.val: new = cur.prev
            else:
                new = Node(cur.val - 1, cur, cur.next)
                new.prev.next = new.next.prev = new
            new.keys.add(key)
            self.key2node[key] = new
        if not cur.keys:
            cur.prev.next, cur.next.prev = cur.next, cur.prev # delete
    def getMaxKey(self) -> str:
        if not self.tail.prev.val: return ''
        return next(iter(self.tail.prev.keys))
    def getMinKey(self) -> str:
        if not self.head.next.val: return ''
        return next(iter(self.head.next.keys))


# -*- coding: utf-8 -*-
"""
parrot plugin: Sends out messages to MUC or JID.

"""

__author__ = "Petr Morávek (xificurk@gmail.com)"
__copyright__ = ["Copyright (C) 2007 Kevin Smith",
                 "Copyright (C) 2009-2011 Petr Morávek"]
__license__ = "GPL 3.0"

__version__ = "0.5.0"

import logging

log = logging.getLogger(__name__)
__ = lambda x: x # Fake gettext function

class parrot:
    def __init__(self, bot, config):
        self.send_message = bot.send_message
        self.get_our_nick = bot.get_our_nick
        self.gettext = bot.gettext
        self.ngettext = bot.ngettext

        bot.add_command("say", self.say, __("Send message into MUC"), __("Bot sends the groupchat message into the specified MUC."), __("room@server text"))
        bot.add_command("tell", self.tell, __("Send message to JID"), __("Bot sends the message to the specified JID."), __("user@server text"))

    def say(self, command, args, msg, uc):
        if args.count(" ") >= 1:
            room, text = args.split(" ", 1)
        else:
            return self.gettext("You've forgot to specify the MUC.", uc.lang)
        if self.get_our_nick(room) is None:
            return self.gettext("I'm not in the room {}.", uc.lang).format(room)
        self.send_message(room, text, mtype="groupchat")
        return self.gettext("Sent", uc.lang)

    def tell(self, command, args, msg, uc):
        if args.count(" ") >= 1:
            jid, text = args.split(" ", 1)
        else:
            return self.gettext("You've forgot to specify the JID.", uc.lang)
        self.send_message(jid, text, mtype="chat")
        return self.gettext("Sent", uc.lang)


#!/usr/bin/env python3
from Crypto.Cipher import AES
import requests
import time
import string

def encrypt(payload):
    url = "http://aes.cryptohack.org/ecb_oracle/encrypt/"
    r = requests.get(url + payload + '/')
    return r.json()['ciphertext']

def print_blk(hex_blks, sz):
   for i in range(0, len(hex_blks), sz):
       print(hex_blks[i:i+sz], ' ', end='')
   print()

def bruteforce():
    flag = ''
    total = 32 - 1
    alphabet = '_'+'@'+'}'+string.digits+string.ascii_lowercase+string.ascii_uppercase

    while True:
        payload = '1' * (total-len(flag))
        expected = encrypt(payload.encode().hex())
        print('E', '', end='')
        print_blk(expected, 32)

        for c in alphabet:
            res = encrypt(bytes.hex((payload + flag + c).encode()))
            print(c, '', end='')
            print_blk(res, 32)
            if res[32:64] == expected[32:64]:
                flag += c
                print(flag)
                break
            time.sleep(1)

        if flag.endswith('}'): break

    print(flag)

bruteforce()


#Escreva um programa que pergunte o salário de um funcionário e calcule o valro do seu aumento.
#Para salários superiores R$ 1.250,00 calcule um aumento de 10%.
#Para salários inferiores ou iguais o aumento é de 15%.

salario = float(input('Qual é o seu salário? '))

if salario > 1250:
    salario = salario*1.1
    print('O seu novo salário é de {:.2f}R$'.format(salario))
else:
    salario = salario*1.15
    print('O seu novo salário é de {:.2f}R$'.format(salario))


from tkinter import *
window=Tk()
window.geometry("500x500")
window.title("Registration Form")

def printt():
    print("demo tkinter")

def exit1():
    exit()

label1=Label(window,text="registration form",relief="solid",width=20,font=("arial",19,"bold"))
label1.place(x=90,y=53)

label2=Label(window,text="first name :",width=20,font=("arial",10,"bold"))
label2.place(x=80,y=130)

label3=Label(window,text="last name :",width=20,font=("arial",10,"bold"))
label3.place(x=80,y=150)

b1=Button(window,text="login",width=12,bg='brown',fg='white',command=printt)
b1.place(x=150,y=380)

b2=Button(window,text="exit",width=12,bg='brown',fg='white',command=exit1)
b2.place(x=280,y=380)

window.mainloop()


# -*- coding: utf-8 -*-
"""
Created on Wed Sep 14 11:15:52 2022
@authors: landon, Alvin, Aidan
"""
import math
import random

CANDIDATE_TESTS = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37)
# added a couple primes past 13 for better actual prime chance
# may impact performance with the addition of more numbers. can this be fixed?

# Prime number generator
# Extra options included for performance & security tuneup
def genPrimes(floor=500000,ceil=5000000,cand_num=500,fermat_num=50):
    sufficient = False
    while not sufficient:
        cand = []
        for i in range(cand_num):
            x = random.randint(floor,ceil)
            if not False in [x % t != 0 for t in CANDIDATE_TESTS]:
                # If these conditions are passed the number may be prime
                cand.append(x)
        # Candidates generated, filter them down using Fermat's test
        cand_f = [i for i in cand if fermat(i, fermat_num)]
        # If at least 2 pseudoprimes have been generated, the list is sufficient.
        # If not, do it over again.
        sufficient = True if len(cand_f) >= 2 else False
    # Return two non-repeating pseudoprimes from the list at random.
    p = cand_f.pop(random.randint(0,len(cand_f)-1))
    q = cand_f.pop(random.randint(0,len(cand_f)-1))
    return p, q

# Fermat's Test
# Pseudoprime candidate verification.
def fermat(n, tests=50):
    a = 0
    for foo in range(tests):
        # Select a in the lower half of n such that a and n are
        # relatively prime. This should work immediately if n is
        # truly prime, but it doesnt't hurt to make sure.
        while math.gcd(a, n) != 1:
            a = random.randint(2, n//2)
        # Apply Fermat's Little Theorem.
        # If any number a between 0 and n does not satisfy
        # a^(n-1) % n = 1, then the number is definitely not prime.
        if pow(a, n-1, n) != 1:
            return False
    return True

# (Extended) Euclid's Algorithm
# Keypair generation (publickey, privatekey)
# Publickey: (e, n)   Privatekey: (d, n)
def genKeypair(p, q):
    n = p*q
    e = 0
    phi = (p-1)*(q-1)

    # should not take long; e is usually a single-digit number
    for x in range(phi):
        if(math.gcd(x,phi) == 1 and x > 1):
            e = x
            break

    # generate d using extended euclid gcd
    d = extended_gcd(e, phi)[0] % phi
    # pubkey, privkey
    return ((e, n), (d, n))

# Extended GCD Utility
def extended_gcd(a=1, b=1):
    if b == 0:
        return (1, 0, a)
    (x, y, d) = extended_gcd(b, a%b)
    return y, x - a//b*y, d

# Encrypt per chunk
def encrypt(publickey, msg, chars = 4, bits = 8):
    if type(msg) == str:
        msg = chunkify(msg, chars, bits)
    return [pow(c, publickey[0], publickey[1]) for c in msg]

# Decrypt per chunk
def decrypt(privatekey, data, chars = None, bits = None):
    result = [pow(i, privatekey[0], privatekey[1]) for i in data]
    if chars and bits:
        result = dechunkify(result, chars, bits)
    return result

# Test code for consolidating 4 characters at a time into an integer
# sum([ord("test"[i]) << 8 * i for i in range(4)])

# Chunkify
# **NOT** ENCRYPTION!!!
# Turns sets of (chars) characters at a time into single integers
# with the same binary representation in memory.
# Default is 32-bit integers. (8 bits per character, 4 characters per chunk)
# Meant to deter the use of frequency analysis on per-character encryption.
def chunkify(msg, chars = 4, bits = 8):
    chunks = []
    for i in range(math.ceil(len(msg) / chars)):
        chunk = msg[chars*i : chars*(i+1)] # can take out of bounds indices, for some reason. ok!
        chunk += '\x00' * (chars - len(chunk)) # add null characters if too short
        chunkbytes = []
        for j in range(chars):
            codepoint = ord(chunk[j])
            if codepoint > 2**bits-1: # too big for given bit count?
                raise OverflowError(f"Character '{chunk[j]}': Value too large to be represented")
            chunkbytes.append(codepoint << bits * j) # shift n*j bits to the left
        chunks.append(sum(chunkbytes))
    return chunks

# Dechunkify
# **NOT** DECRYPTION!!!
# Chunkify in reverse. Chars and bits must be the same.
def dechunkify(chunks, chars = 4, bits = 8):
    result = ""
    mask = 2**bits-1
    for chunk in chunks:
        for i in range(chars):
            result += chr((chunk >> bits * i) & mask)
    return result.strip("\x00")

#Signature Encryption
def sigEncrypt(c, privKey):
    s = pow(int(c),privKey[0],privKey[1])
    return s

#Signature Decryption
def sigDecrypt(s, pubKey):
    i = pow(s,pubKey[0],pubKey[1])
    return i

if __name__ == "__main__":

    sigList = []
    publicList = []
    privateList = []
    #wtf is N
    (p, q) = genPrimes()
    print (p, q)
    pubKey, privKey = genKeypair(p, q)
    print ("RSA keys have been generated.")

    while 1:

        print("Please select your user type:")
        print("\t1. A public user")
        print("\t2. The owner of the keys")
        print("\t3. Exit program ")

        choice = input()

        while choice == "1":
            print("As a public user, what would you like to do?")
            print("\t1. Send an encrypted message")
            print("\t2. Authenticate a digital signature")
            print("\t3. Exit")
            choice2 = input()

            if choice2 == "1":
                message = input("Enter a message > ")
                publicList.append(message)
                #encryption of message letter by letter
                msg_chunks = chunkify(message)
                msg_c = encrypt(pubKey, msg_chunks)
                print("Message encrypted and sent")
                privateList.append(msg_c)
                print(msg_c)
                break

            elif choice2 == "2":
                print("Signature Authentication has been selected.")
                if len(sigList) == 0:
                    print("There are no signatures to authenticate")
                    break
                else:
                    print("The following messages are available: ")
                    count = 0
                    for x in sigList:
                        print(count, ". ", x)
                        count+=1
                    sigChoice = int(input("Enter your choice: "))
                    sig = sigList[sigChoice]
                    decrypSig = sigDecrypt(sig[0], pubKey)
                    print("Decrypted:", decrypSig, "Original:", sig[1])

                    if (sig[1] == decrypSig):
                        print("Signature verified.")
                    else:
                        print("Signature is not Valid")

                break

            elif choice2 == "3":
                choice = "0"
                break

        while choice == "2":
            print("As the owner of the keys, what would you like to do?")
            print("\t1. Decrypt a received message ")
            print("\t2. Digitally sign a message")
            print("\t3. Exit")
            choice2 = input()

            if choice2 == "1":
                if msg_c is None:
                    print("There are no messages available")
                else:
                    print("The following messages are available:")
                    for x in range(len(privateList)):
                        print("- Message #{0}".format(x)) # is this intentional? - aidan
                        #print(x + 1, "Message #", x + 1, ": ") should we use this one? - Alvin
                    messageChoice = int(input("Enter your choice: "))

                    if messageChoice < len(privateList):
                        decrypMessage = dechunkify(decrypt(privKey, privateList[messageChoice]))
                        print("Decrypted message:", decrypMessage)

                break

            elif choice2 == "2":
                signature = input("Enter a message:")
                numSig = 0
                for x in signature:
                    # this was a string cast - was this ever intentional?
                    numSig += ord(x)
                sigList.append((sigEncrypt(numSig, privKey), numSig))
                print("Message signed and sent.")
                break

            elif choice2 == "3":
                choice = 0
                break

        if choice == "3":
            print("Bye for now!")
            break


"""Action Handler Module."""
from collections import deque

from ..context import context
from ._action import Action, HandlerAction, ReversibleAction

class ActionHandler:
    """Action Handler Class.

    Implements action execution and Undo/Redo functionality.
    """

    DEFAULT_MAX_UNDO = 100

    def __init__(self, target, max_undo: int = DEFAULT_MAX_UNDO) -> None:
        """Initialize the action handler."""
        self.target = target
        self.max_undo = max_undo
        self.undo_history: deque[ReversibleAction] = deque(maxlen=max_undo)
        self.redo_history: deque[ReversibleAction] = deque(maxlen=max_undo)

    def do(self, action: Action) -> None:  # pylint: disable=invalid-name
        """Process and perform action."""
        action.target = self.target
        action.do()
        if isinstance(action, HandlerAction):
            return
        if isinstance(action, ReversibleAction):
            self.undo_history.append(action)
        context.previous_action = action
        self.redo_history.clear()

    def redo(self) -> None:
        """Redo action."""
        if len(self.redo_history) == 0:
            return
        last_action = self.redo_history.pop()
        last_action.redo()
        self.undo_history.append(last_action)

    def undo(self) -> None:
        """Undo action."""
        if len(self.undo_history) == 0:
            return
        last_action = self.undo_history.pop()
        last_action.undo()
        self.redo_history.append(last_action)


f = open("./27_B.txt")
n = int(f.readline())

sm = 0  # сумма элементов от начала списка
max_sm, min_ln = 0, n
lst = [-1] * 43  # суммы для соответствующих остатков
pos = [-1] * 43  # мин возм позиции для этих сумм
for i in range(n):
    num = int(f.readline())
    sm += num  # сумма эл-тов до текущей i-той позиции
    ost = sm%43
    if ost==0:
        max_sm = sm
        min_ln = i+1
    else:
        if lst[ost]==-1:
            lst[ost] = sm
            pos[ost] = i
        else:
            if sm-lst[ost] == max_sm:
                min_ln = min(min_ln, i-pos[ost])
            if sm-lst[ost] > max_sm:
                max_sm = sm-lst[ost]
                min_ln = i-pos[ost]

print(min_ln)
f.close()


import json
import os
import requests
import time

from kafka import KafkaProducer

def fetch() -> dict:
    endpoint = 'https://api.coindesk.com/v1/bpi/currentprice.json'
    res = requests.get(endpoint)
    res_json = json.loads(res.text)
    return res_json

def clean_record(raw: dict) -> dict:
    return {
        'time': raw['time']['updated'],
        'currenty': raw['bpi']['USD']['code'],
        'rate': raw['bpi']['USD']['rate_float']
    }

def publish_record(producer: KafkaProducer) -> None:
    res = fetch()
    cleaned_response = clean_record(res)

    producer.send('bpi-raw-stream', cleaned_response)

if __name__ == '__main__':
    KAFKA_BROKER_URL = os.environ.get('KAFKA_BROKER_URL')

    producer = KafkaProducer(
        bootstrap_servers=KAFKA_BROKER_URL,
        value_serializer=lambda x: json.dumps(x).encode('utf-8')
        )

    while True:
        publish_record(producer)
        producer.flush()
        time.sleep(1)


#!/usr/bin/python3

# COMP3311 22T3 Assignment 2
# Print a list of character roles played by an actor/actress

import sys
import psycopg2

### Globals

db = None
usage = f"Usage: {sys.argv[0]} FullName"

### Command-line args

if len(sys.argv) < 2:
   print(usage)
   exit(1)

# process the command-line args ...
name  = sys.argv[1]

### Queries
qry1 = """
   select p.id
   from People p
   where p.name = %s
   order by p.id
   ;
"""

qry2 = """
   select pl.role, m.title, m.year
   from People p
   join Principals pr on pr.person = p.id
   join Movies m on m.id = pr.movie
   join Playsrole pl on pl.inMovie = pr.id
   where (p.id = %s) and (pr.job = 'self' or pr.job = 'actor' or pr.job = 'actress')
   order by m.year, m.title, pl.role
   ;
"""

### Manipulating database
db = psycopg2.connect("dbname=ass2")
cur = db.cursor()

try:
   # your code goes here
   cur.execute(qry1, [name])
   person = cur.fetchall()

   countPerson = 0
   if not person:
      print("No such person")
      exit(0)
   else:
      countPerson = len(person)

   for p in person:
      cur.execute(qry2,person[0])

   roles = cur.fetchall()
   numRoles = len(roles)

   if countPerson == 1 :
      if numRoles == 0:
         print("No acting roles")
      else:
         for r in roles:
            print(f"{r[0]} in {r[1]} ({r[2]})")

   else :
      counter = 1
      for p in person:
         cur.execute(qry2,[p[0]])
         roles = cur.fetchall()
         numRoles = len(roles)
         print(f"{name} #{counter}")
         counter +=1
         if numRoles == 0:
            print(f"No acting roles")
         else:
            for r in roles:
               print(f"{r[0]} in {r[1]} ({(r[2])})")

except Exception as err:
   print("DB error: ", err)
finally:
   if db:
      db.close()


def parser():
    global position
    position = 0

    try:
        while position < len(tokens) and tokens[position][0] != 'end':
            statement()

        match('end')
        match('.')
        print('Código compilado com sucesso.')
    except SyntaxError as e:
        print('Erro de sintaxe:', e)

def statement():
    if tokens[position][0] == 'var':
        match('var')
        match(':')
        match('Tipo de variavel')
        match(';')
    else:
        raise SyntaxError('Comando inválido')


import os

# pylint: disable=g-direct-tensorflow-import
from tensorflow.dtensor.python import config
from tensorflow.dtensor.python.tests import test_util
from tensorflow.python.eager import context
from tensorflow.python.framework import device as tf_device
from tensorflow.python.platform import test as tf_test
# pylint: enable=g-direct-tensorflow-import

class ConfigTest(tf_test.TestCase):

  def setUp(self):
    super().setUp()
    test_util.reset_logical_devices('CPU', 2)
    if test_util.is_gpu_present():
      test_util.reset_logical_devices('GPU', 2)

  def tearDown(self):
    os.environ.pop(config._DT_JOBS, [])
    super().tearDown()

  def test_env_vars(self):
    self.assertEqual(config.client_id(), 0)
    self.assertEqual(config.num_clients(), 1)
    self.assertEqual(config.job_name(), 'localhost')
    self.assertEqual(config.full_job_name(), 'localhost/replica:0/task:0')
    self.assertEqual(config.jobs(), [])

  def test_list_devices(self):
    device_type = config.preferred_device_type()

    local_devices = [
        tf_device.DeviceSpec.from_string(
            f'/job:localhost/replica:0/task:0/device:{device_type}:0'),
        tf_device.DeviceSpec.from_string(
            f'/job:localhost/replica:0/task:0/device:{device_type}:1'),
    ]

    self.assertEqual(config.local_devices(device_type), local_devices)
    self.assertEqual(config.num_local_devices(device_type), 2)
    self.assertEqual(config.num_global_devices(device_type), 2)
    # The eager context should not be initialized by any of the calls
    self.assertFalse(context.context()._initialized)  # pylint: disable=protected-access

  def test_sort_jobs_with_bns_names(self):
    # bns names must be sorted in the bns order.
    dtensor_jobs = [
        '/bns/localhost/{task_id}'.format(task_id=i) for i in range(16)
    ]
    os.environ[config._DT_JOBS] = ','.join(dtensor_jobs)
    self.assertListEqual(dtensor_jobs, config.jobs())

    dtensor_jobs = [
        '/bns/localhost/{task_id}:8888'.format(task_id=i) for i in range(16)
    ]
    os.environ[config._DT_JOBS] = ','.join(dtensor_jobs)
    self.assertListEqual(dtensor_jobs, config.jobs())

    dtensor_jobs = [
        '/bns/localhost/{task_id}'.format(task_id=100 - i) for i in range(16)
    ]
    os.environ[config._DT_JOBS] = ','.join(dtensor_jobs)
    with self.assertRaisesRegex(ValueError, 'Unexpected DTENSOR_JOBS'):
      config.jobs()

  def test_jobs_with_ip_port(self):
    # The ip port format is not a bns address, and not required to sorted.
    dtensor_jobs = ['localhost:{port}'.format(port=16 - i) for i in range(16)]
    os.environ[config._DT_JOBS] = ','.join(dtensor_jobs)
    self.assertListEqual(dtensor_jobs, config.jobs())

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


import pprint
import pandas as pd
from sklearn.metrics import roc_auc_score, average_precision_score

def score_counter(val, y_true, y_pred):
    scores = {
            "TP": 0,
            "FP": 0,
            "TN": 0,
            "FN": 0
        }

    for i in range(len(y_pred)):
        if y_pred[i] == val:
            # positives
            if y_true[i] == val:
                scores["TP"] += 1
            else:
                scores["FP"] += 1
        else:
            # negatives
            if y_true[i] == val:
                scores["FN"] += 1
            else:
                scores["TN"] += 1

    for key in scores.keys():
        scores[key] = float(scores[key])

    return scores

def accuracy(scores):
    correct = scores["TP"] + scores["TN"]
    incorrect = scores["FP"] + scores["FN"]
    return correct / (correct + incorrect)

def specificity(scores):
    # TP / TP + FN
    if scores["TP"] == 0: return 0
    return scores["TP"] / (scores["TP"] + scores["FN"])

def sensitivity(scores):
    # TN / FP + TN
    if scores["TN"] == 0: return 0
    return scores["TN"] / (scores["FP"] + scores["TN"])

def positive_predictive_value(scores):
    # TP / TP + FP
    if scores["TP"] == 0: return 0
    return scores["TP"] / (scores["TP"] + scores["FP"])

def negative_predictive_value(scores):
    # TN / TN + FN
    if scores["TN"] == 0: return 0
    return scores["TN"] / (scores["TN"] + scores["FN"])

def to_binary_labels(val, y):
    bin_copy = y.copy()
    for i in range(len(bin_copy)):
        if bin_copy[i] == val:
            bin_copy[i] = 1
        else:
            bin_copy[i] = 0
    return bin_copy

def classification_report(y_true, y_pred, labelEncoder):
    # Returns a dataframe representing a range of scores for each label
    classes = labelEncoder.classes_
    class_report = {
            "Class": [],
            "Accuracy": [],
            "Specificity": [],
            "Sensitivity": [],
            "PPV": [],
            "NPV": [],
            "ROC_AUC": [],
            "Average Precision Score": []
        }
    report_df = pd.DataFrame(data=class_report)
    for i in range(len(classes)):
        scores = score_counter(i, y_true, y_pred)
        print(scores)
        print(y_true, y_pred)
        row = {
                "Class": classes[i],
                "Accuracy": accuracy(scores),
                "Specificity": specificity(scores),
                "Sensitivity": sensitivity(scores),
                "PPV": positive_predictive_value(scores),
                "NPV": negative_predictive_value(scores)
            }
        # ROC AUC is undefined if all values are the same. So verify difference fist
        bin_y_true = to_binary_labels(i, y_true)
        bin_y_pred = to_binary_labels(i, y_pred)
        if len(set(bin_y_true)) > 1 and len(set(bin_y_pred)) > 1:
            row["ROC_AUC"] = roc_auc_score(bin_y_true, bin_y_pred)
            row["Average Precision Score"] = average_precision_score(bin_y_true, bin_y_pred)
        else:
            row["ROC_AUC"] = "undefined"
            row["Average Precision Score"] = "undefined"

        report_df = report_df.append(row, ignore_index=True)

    return report_df


from pathlib import Path
from unittest.mock import mock_open, patch

from gen_unit_tables import write_unit_table

def test_write_unit_table(snapshot):
    with patch.object(Path, "open", mock_open()) as mock_open_file:
        write_unit_table(filename=Path())

    lines = [
        args[0] for args in mock_open_file.return_value.write.call_args_list
    ]
    # Exclude the first line, because it contains "Generated by /home/username/..."
    assert lines[1:] == snapshot


import pandas as pd
import numpy as np
from ACME.utils import clean_list
from ACME.ACME_function import computeACME, build_feature_exploration_table, predictACME
from ACME.ACME_plot import ACME_summary_plot, feature_exploration_plot, ACME_barplot_multicalss
from ACME.ACME_anomaly_detection import build_anomaly_detection_feature_exploration_table, computeAnomalyDetectionImportance
import plotly.express as px
import plotly.graph_objects as go

class ACME():

    def __init__(self, model, target, features=[], cat_features=[], K=50, task='regression', score_function=None):
        '''
        Initialization

        Params:
        ------
        - model: object
            the object of the model
        - target: str
            name of the target_feature
        - features: [str]
            list of the features name in SAME ORDER as the the model input
        - cat_features: [str]
            categorical features name
        - K: int
            number of quantiles to use
        - task: str
            type of model task {'regression','reg','r', 'c','class','classification', 'ad','anomaly detection'}
        - score_function: fun(model, x)
            a function that has in input the model and the input data to realize the prediction. It must return a numeric score

        '''

        self._model = model
        self._target = target
        self._features = features
        self._numeric_features = list(np.setdiff1d(features, cat_features))
        self._cat_features = cat_features
        self._task = task
        self._global_explain = {}
        self._local_explain = {}
        self._K = K
        self._score_function = score_function
        self._class_to_analyze = None
        self._label_class = None

    def explain(self, dataframe, robust = False, label_class = None):
        '''
        Fit the acme explainability.

        Params:
        -------
        - dataframe : pd.DataFrame
            input dataframe
        - robust : bool (default False)
            if True use only quantile from 0.05 and 0.95, if False use from 0 to 1
        - label_class : str,int (default None)
            if task is classification, specify the class of interest
        '''

        # if cat features and numeric features are not specified then all the columns of the dataset (not the target) are used as numeric feature
        if self._numeric_features == [] and self._cat_features == []:
            self._numeric_features = dataframe.drop(columns=self._target).columns.to_list()

        # create the dataframe of numeric feature
        if self._numeric_features == []:
            if self._cat_features == [] :
                self._numeric_features = dataframe.drop(columns= [self._target]).columns.to_list()
            else:
                self._numeric_features = dataframe.drop(columns= [self._target] + self._cat_features ).columns.to_list()

        self._numeric_df = dataframe[ self._numeric_features ].copy()

        # create the dataframe for cat feature
        self._cat_df = None
        if not self._cat_features == []:
           self._cat_df = dataframe[ self._cat_features ].copy()

        # we save the features used by the model in the original order (necessary to correctly compute the predictiom)
        self._features = clean_list( dataframe.columns.to_list(), self._numeric_features + self._cat_features)

        # if the label class is given, find the corrispective position in the model class map
        # else auto set as label class the first class
        # N.B. : label_class is the class name, class_to_analyze is the label_class corrispective number in the model class map
        if self._task  in ['c','class','classification']:
            class_map = np.array(self._model.classes_)
            if label_class is not None:
                try:
                    class_to_analyze = np.where(class_map == label_class)[0][0]
                except:
                    class_to_analyze = np.where(class_map == str(label_class))[0][0]
                self._class_to_analyze = class_to_analyze
            if label_class is None:
                label_class = list(class_map)

            self._label_class = label_class

        # compute local acme for regression or classifiction
        if self._task in ['r','reg','regression'] or self._task in ['ad','anomaly detection']:
            feature_table, importance_table, baseline_pred, baseline, perc_functions = computeACME( model = self._model, task = self._task,
                                                                                features = self._features,
                                                                                numeric_df = self._numeric_df, cat_df = self._cat_df,
                                                                                score_function = self._score_function,
                                                                                K = self._K, robust = robust )
        if self._task  in ['c','class','classification']:

            class_stack_importance = []
            class_stack_feature_table = []
            label_dict = {}

            if type(label_class) is list:
                label_list = range(0,len(label_class))
            else:
                label_list = [class_to_analyze]

            # explore every label

            for lab in label_list:
                label_dict[lab] = class_map[lab]
                feature_table, importance_table, baseline_pred, baseline, perc_functions = computeACME( model = self._model, task = self._task,
                                                                                features = self._features, class_to_analyze = lab,
                                                                                numeric_df = self._numeric_df, cat_df = self._cat_df,
                                                                                score_function = self._score_function,
                                                                                K=self._K, robust = robust )

                # rename the columns in case of multilabel
                if len(label_list) > 1:
                    importance_table.rename( columns = { 'importance' : 'importance_class_' + str(label_class[lab]) }, inplace=True )

                # save the results
                class_stack_importance.append(importance_table)
                class_stack_feature_table.append(feature_table)

            # concat the results
            feature_table = pd.concat(class_stack_feature_table)
            feature_table['class'] = feature_table['class'].map(label_dict)

            class_stack_importance = pd.concat(class_stack_importance,axis=1)
            #if multilabel sum the importance of each feature in each
            if len(label_list) > 1:
                class_stack_importance['importance'] = class_stack_importance.sum(axis=1).values

            class_stack_importance.sort_values('importance', ascending = False, inplace=True)
            importance_table = class_stack_importance

        # create the outputs
        self._global_explain = {'meta':feature_table.copy(),
                                'feature_importance':importance_table.sort_values('importance', ascending = False).copy(),
                                'baseline_pred':baseline_pred,
                                'baseline':baseline,
                                }
        #self._global_meta = feature_table.copy()
        #self._global_feature_importance = importance_table.sort_values('importance', ascending = False).copy()
        #self._global_baseline_pred = baseline_pred
        #self._global_baseline = baseline
        self._perc_functions = perc_functions

        return self

    def explain_local(self, series, label_class = None):
        '''
        Params:
        -------
        - series : pd.Series
            observation on which explain the prediction
        - label_class : str,int (default None)
            if task is classification, specify the class of interest

        Returns:
        --------
        - pd.DataFrame
        '''

        # if the label class is given, find the corrispective position in the model class map
        # else auto set as label class the first class
        # N.B. : label_class is the class name, class_to_analyze is the label_class corrispective number in the model class map

        if len(self._global_explain.keys())==0:
            raise InterruptedError("You must first fit the acme explaination model with the 'explain' command on the same data used to train the model")

        if self._task  in ['c','class','classification']:
            class_map = np.array(self._model.classes_)
            if label_class is not None:
                try:
                    class_to_analyze = np.where(class_map == label_class)[0][0]
                except:
                    class_to_analyze = np.where(class_map == str(label_class))[0][0]
            else:
                class_to_analyze = 0
                label_class = class_map[class_to_analyze]
                print('WARNING: in local interpretation, the label_class must be specified and not None. To default it\'s setted to class:' + str(class_map[0]))

            # save the class to analize and the label
            self._class_to_analyze = class_to_analyze
            self._label_class = label_class

        local_table, local_importance_table, local_baseline_pred, local_baseline = predictACME(model=self._model,
                    series=series,
                    features=self._features,
                    meta_table=self._global_explain['meta'],
                    percentile_functions=self._perc_functions,
                    task=self._task,
                    score_function=self._score_function,
                    class_to_analyze=self._class_to_analyze)

        if self._task in ['c','class','classification']:
            local_table['class'] = local_table['class'].map({class_to_analyze : class_map[class_to_analyze]})

        self._local_explain = {'meta':local_table.copy(),
                                'feature_importance':local_importance_table.sort_values('importance', ascending = False).copy(),
                                'baseline_pred':local_baseline_pred,
                                'baseline':local_baseline,
                                'local_name':series.name}  # save the index of the local observation, it's the name of the series (corrisponding to the dataframe index)

        #self._local_meta = local_table
        #self._local_baseline = local_baseline
        #self._local_importance_table = local_importance_table
        #self._local_baseline_pred = local_baseline_pred

        return self

    def feature_importance(self, local=False, weights = {}):
        '''
        Returns the feature importance calculated by AcME.
        In case of Anomaly Detection task, it provides ad hoc explanation for anomaly detection, studied for local interpretability.
        The score will show what features can altered the prediction from normal to anomalies and viceversa.

        Params:
        ------
        - local : bool
            if true and task is AD, it return the local AD version of feature importance
        - weights : dict
            Dictionary with the importance for each element. Sum must be 1
            * ratio : float
                importance of local score position
            * distance : float
                importance of inter-quantile distance necessary to change
            * change : float
                importance of the possibility to change prediction
            * delta : float
                importance of the score delta

        Return :
        -------
        - pd.DataFrame
        '''

        # if the task is anomaly detection and we have already fitted a local acme
        # calculate the importance for the selected row anomaly detection task
        if self._task in ['ad','anomaly detection'] and local:

            local_table = self._local_explain['meta'].drop(columns='size').copy()
            importance_df = computeAnomalyDetectionImportance(local_table, weights = weights)

            return importance_df

        # if local then we return the local importance
        elif local:
            return self._local_explain['feature_importance']

        # else simply return the importance calculated by acme for global explain
        else:
            return self._global_explain['feature_importance']

    def feature_exploration(self, feature, local=False, plot=False):
        '''
        Generate anomaly detection feature exploration table or a plot for local observation that,
        choosen a specific feature, shows how the anomaly score can change beacuse of the feature.

        Params:
        -------
        - feature : str
            selected feature's name
        - plot : bool
            if true returns the plot, else returs the table

        Returns:
        --------
        - feature_table : pd.DataFrame
        '''

        # extract the desired table
        if local:
            table = self._local_explain['meta']
        else:
            table = self._global_explain['meta']

        # build the correct feature exploration table
        if self._task in ['ad','anomaly detection']:
            feature_table = build_anomaly_detection_feature_exploration_table(table, feature)
        else:
            feature_table = build_feature_exploration_table(table, feature)

        # if plot return plot, else return the table
        if plot:
            fig = feature_exploration_plot(feature_table, feature, self._task)
            return fig
        else:
            return feature_table

    def summary_plot(self, local=False, weights = {}):
        '''
        Generate the recap plot

        Params:
        -------
        - local : bool
            if local or global plot
        - weights : dict
            Dictionary with the importance for each element used in AD. Sum must be 1
                * ratio : float
                    importance of local score position
                * distance : float
                    importance of inter-quantile distance necessary to change
                * change : float
                    importance of the possibility to change prediction
                * delta : float
                    importance of the score delta

        Returns:
        --------
        - plotly figure
        '''

        # if desired explainability is global, task is classification and there are multi label: produce the bar plot
        if self._task in ['c','class','classification'] and type(self._label_class) is list and not local:
            fig = ACME_barplot_multicalss(self._global_explain['feature_importance'], self._label_class)

        # generate the quantile/feature/effect plot
        else:
            meta = dict()
            meta['task'] = self._task
            meta['local'] = False

            if self._task  in ['c','class','classification']:
                meta['label_class'] = self._label_class
                meta['local'] = False

            if local:
                table = self._local_explain['meta']
                meta['local'] = True
                meta['index'] = self._local_explain['local_name']
                meta['baseline'] = self._local_explain['baseline_pred']

                if self._task in ['ad','anomaly detection']:
                    local_table = self._local_explain['meta'].drop(columns='size').copy()
                    importance_df = computeAnomalyDetectionImportance(local_table, weights = weights)
                    table = table.drop(columns=['importance'])
                    table = table.merge(importance_df[['importance']],left_index=True,right_index=True)

            else:
                table = self._global_explain['meta']
                meta['local'] = False

            # prepare for the plotting
            plot_df = table.sort_values(['importance','quantile']).reset_index().rename(columns={'index':'feature'}).copy()

            # if local set the refering x to the local values observation
            # for the global set to 0
            if local:
                meta['x'] = table['baseline_prediction'].values[0]
            else:
                meta['x'] = 0

            # set the top and the bottom of the y-axis (first and last feature)
            meta['y_bottom'] = plot_df['feature'].values[0]
            meta['y_top'] = plot_df['feature'].values[len(plot_df)-1]

            # generate the plot
            fig = ACME_summary_plot(plot_df, meta)

        return fig

    def bar_plot(self, local=False):
        '''
        Feature importance plot
        '''
        if self._task in ['r', 'reg', 'regression']:
            title = 'Barplot of feature importance: regression'
        elif self._task in ['ad','anomaly detection']:
            title = 'Barplot of feature importance: anomaly detection'
        else:
            title = 'Barplot of feature importance: classification'

        if local:
            table = self._local_explain['feature_importance']
            title = 'Local importance observation ID: ' + str(self._local_explain['local_name']) + '.
'+title
        else:
            table = self._global_explain['feature_importance']

        table = round(table.reset_index().sort_values('importance').rename(columns={'index':'feature'}),3)
        fig = px.bar(table,
                    x='importance',
                    y='feature',
                    orientation='h',
                    title = title)

        fig.update_traces(hovertemplate = 'Feature:%{y}
Importance:%{x}')
        return fig.update_layout( title={ 'y':0.9, 'x':0.5, 'xanchor': 'center', 'yanchor': 'top'} )

    def summary_table(self, local=False):
        '''
        Expose the global or local summary table
        '''
        if local:
            return self._local_explain['meta'].drop(columns='size')
        else:
            return self._global_explain['meta'].drop(columns='size')

    def baseline_values(self, local=False):
        '''
        Expose the baseline vector used for AcME
        '''
        if local:
            return self._local_explain['baseline']
        else:
            return self._global_explain['baseline']

    def metadata(self):

        return {'model':self._model,
        'target':self._target,
        'features':self._features,
        'numeric_features':self._numeric_features,
        'cat_features':self._cat_features,
        'task':self._task,
        'global_explain':self._global_explain,
        'local_explain':self._local_explain,
        'K':self._K,
        'score_function':self._score_function}


import json

import src.data_loaders as module_data
import torch
from pytorch_lightning import seed_everything, Trainer
from torch.utils.data import DataLoader
from train import ToxicClassifier

def initialize_trainer(CONFIG):
    seed_everything(1234)
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    def get_instance(module, name, config, *args, **kwargs):
        return getattr(module, config[name]["type"])(*args, **config[name]["args"], **kwargs)

    model = ToxicClassifier(CONFIG)
    model.to(device)

    dataset = get_instance(module_data, "dataset", CONFIG)
    val_dataset = get_instance(module_data, "dataset", CONFIG, train=False)

    data_loader = DataLoader(
        dataset,
        batch_size=CONFIG["batch_size"],
        num_workers=2,
        shuffle=True,
        drop_last=True,
        pin_memory=True,
    )

    valid_data_loader = DataLoader(
        val_dataset,
        batch_size=CONFIG["batch_size"],
        num_workers=2,
        shuffle=False,
    )

    trainer = Trainer(
        gpus=0 if torch.cuda.is_available() else None,
        limit_train_batches=2,
        limit_val_batches=2,
        max_epochs=1,
    )
    trainer.fit(model, data_loader, valid_data_loader)
    results = trainer.test(dataloaders=valid_data_loader)

    return results

def test_trainer():
    CONFIG = json.load(open("configs/Toxic_comment_classification_BERT.json"))
    CONFIG["dataset"]["args"][
        "train_csv_file"
    ] = "tests/dummy_data/jigsaw-toxic-comment-classification-challenge/train.csv"
    CONFIG["dataset"]["args"][
        "test_csv_file"
    ] = "tests/dummy_data/jigsaw-toxic-comment-classification-challenge/test.csv"
    CONFIG["batch_size"] = 2

    results = initialize_trainer(CONFIG)
    print(results)
    assert results[0]["test_acc"] > 0.3

if __name__ == "__main__":
    test_trainer()


import copy
import timeit

#This file contains an implementation of Iterative deepening depth-first search for the solution of n-tile problem.

#Global counter for the number of yields
count=0
def count_yields (value):
    global count
    count = count+1
    if value==0:
        count=0

#Transform state to dictionary
def make_dict (state):
    coordinate_dict = {}
    for x, row in enumerate(state):
        for y, value in enumerate(row):
            coordinate_dict[value] = (x, y)
    return coordinate_dict

#Function that returns a state based on the current state
def move ( state ):
    copy_state = copy.deepcopy(state)
    [i ,j, grid ] = copy_state
    n = len ( grid )
    def move_blank (i ,j , n ):
        #down
        if i +1 < n :
            count_yields(1)
            yield ( i +1 , j )
        #up
        if i -1 >= 0:
            count_yields(1)
            yield (i -1 , j )
        #right
        if j +1 < n :
            count_yields(1)
            yield (i , j +1)
        #left
        if j -1 >= 0:
            count_yields(1)
            yield (i ,j -1)
    for pos in move_blank (i ,j , n ):
        i1 , j1 = pos
        grid [ i ][ j ] , grid [ i1 ][ j1 ] = grid [ i1 ][ j1 ] , grid [ i ][ j ]
        yield [ i1 , j1 , grid ]
        grid [ i ][ j ] , grid [ i1 ][ j1 ] = grid [ i1 ][ j1 ] , grid [ i ][ j ]

#DEPTH FIRST SEARCH
def  dfs_rec(path,goal, depth):
    if path [-1]==goal:
        return  path
    if depth <= 0:
        return None
    else:
        for nextState in move(path[-1]):
            if  nextState  not in path:
                nextPath = path+[nextState]
                solution = dfs_rec(nextPath, goal,depth -1)
                if  solution  != None:
                    return  solution
    return None

#Iterative Deepening based on DEPTH FIRST SEARCH
def IDDFS(path, goal):
    for depth in range(0, 100):
        result = dfs_rec([path], goal,depth)
        # print(f"depth {depth}")
        if result is None:
            continue
        return "",len(result)-1,count
    return 'goal not in graph with depth {}'.format(100),0

#region STATES TO EXAMINE
states1 = [[0, 0, [[0, 7, 1], [4, 3, 2], [8, 6, 5]]],
                    [0, 2, [[5, 6, 0], [1, 3, 8], [4, 7, 2]]],
                    [2, 0, [[3, 5, 6], [1, 2, 7], [0, 8, 4]]],
                    [1, 1, [[7, 3, 5], [4, 0, 2], [8, 1, 6]]],
                    [2, 0, [[6, 4, 8], [7, 1, 3], [0, 2, 5]]],
                    ]

goal1 = [0, 2, [[3, 2, 0], [6, 1, 8], [4, 7, 5]]]

states2 = [[0, 0, [[0, 1, 8], [3, 6, 7], [5, 4, 2]]],
                    [2, 0, [[6, 4, 1], [7, 3, 2], [0, 5, 8]]],
                    [0, 0, [[0, 7, 1], [5, 4, 8], [6, 2, 3]]],
                    [0, 2, [[5, 4, 0], [2, 3, 1], [8, 7, 6]]],
                    [2, 1, [[8, 6, 7], [2, 5, 4], [3, 0, 1]]]
                    ]
goal2 = [2, 2, [[1, 2, 3], [4, 5, 6], [7, 8, 0]]]
#endregion

#msg            return a messagge based on iddfs
#moves          return the number of depth
#c              return the number of moves
#region ITERATE TROUGH STATES
print("First five instances with goal = [0, 2, [[3, 2, 0], [6, 1, 8], [4, 7, 5]]]")
for i in states1:
    start = timeit.default_timer()
    msg,moves,c = IDDFS((i), (goal1))
    stop = timeit.default_timer()
    if msg=="":
        print("Depth= {}".format(moves)+"    Moves={}".format(c)+'    Time= {0:.2f}'.format(stop - start))
        count_yields(0)
    else:
        print("Solution not found!")
print("Next five instances with goal=[2,2,[[1,2,3],[4,5,6],[7,8,0]]]")
for i in states2:
    start = timeit.default_timer()
    msg,moves,c= IDDFS((i), (goal2))
    stop = timeit.default_timer()

    if msg=="":
        print("Depth= {}".format(moves)+"    Moves={}".format(c)+'    Time= {0:.2f}'.format(stop - start))
        count_yields(0)
    else:
        print("Solution not found!")
#endregion


import coloredlogs, logging
coloredlogs.install(fmt='%(levelname)7s %(asctime)s %(hostname)s %(message)s')

import numpy as np
import matplotlib.pyplot as plt

# a combination of different randoms

Bn = 256
Sn = 80

A = np.concatenate((np.random.randn(Bn) * 0.2 + 8, np.random.randn(Bn) * 3 - 10, np.random.randn(Bn), np.random.rand(Bn) + 2, np.random.pareto(3.0, size=Bn)))

# plt.hist(A, 100)
# plt.show()

means = []
stds = []

for k in range(100):
    sample_idx = np.random.choice(A.shape[0], size=Sn * A.shape[0] // 100, replace=False)
    h = A[sample_idx]
    means.append(h.mean())
    stds.append(h.std())

means = np.array(means)
stds = np.array(stds)

print(means.mean(), means.std())
print(stds.mean(), stds.std())


import PySimpleGUI as sg

import planar_projection
import obj_reader
import workarounds

def RGB_2_HEX(x: tuple):
    return f"#{x[0]:02x}{x[1]:02x}{x[2]:02x}"

def refresh_view(RENDER_MODE):
    canvas: sg.Graph = window['-GRAPH-']
    canvas.erase()

    points = my_camera.project_object(my_object)

    if RENDER_MODE == 'LINES':
        if my_object.edges is None:
            canvas.draw_text("No lines data in file!", (0, 0), 'white')
            return

        for p1, p2 in my_camera.get_edges(my_object):
            canvas.draw_line(p1, p2, 'white', 3)

    if RENDER_MODE == 'POINTS':
        if my_object.verts is None:
            canvas.draw_text("No points in file!", (0, 0), 'white')
            return

        for p in points:
            canvas.draw_circle(p, 0.005, 'white', 'white')

    if RENDER_MODE == 'FACES':
        if my_object.faces is None:
            canvas.draw_text("No faces data in file!", (0, 0), 'white')
            return

        for f in my_camera.get_faces(my_object):
            verts = [points[p] for p in f]
            canvas.draw_polygon(verts, 'grey', 'orange', 0.02)

    if RENDER_MODE == 'SHADED':
        if my_object.faces is None:
            canvas.draw_text("No faces data in file!", (0, 0), 'white')
            return

        faces = my_camera.get_faces(my_object)
        for n, f in enumerate(faces):
            c = int(n / len(faces) * 150) + 50
            face_colour = RGB_2_HEX((c, c, c))
            verts = [points[p] for p in f]
            canvas.draw_polygon(verts, face_colour, face_colour, 0.02)

    # if RENDER_MODE == 'POINT_NUMBER':
    #     for n, p in enumerate(points):
    #         canvas.draw_text(str(n), p, 'white')

# Create Scene
my_object = obj_reader.import_obj('example_obj/utah_teapot.obj', rotation=('x', 90), translation=(0, 0, -1.5))
my_camera = planar_projection.Camera_3D(
    focal_distance=-12,
    projection_plane_distance=-10
)

GRAPH_SIZE = (350,350) if sg.running_trinket() else (500,500)
layout = [
    [sg.Graph(GRAPH_SIZE, (-1, -1), (1, 1), 'black', float_values=True, enable_events=True, key='-GRAPH-', drag_submits=True)],
    [sg.Text("R:", size=3), sg.Slider((0, 360), resolution=1, default_value=0, enable_events=True, orientation='horizontal', expand_x=True, key='-O-')],
    [sg.Text("X:", size=3), sg.Slider((-8, 8), resolution=0.1, default_value=0, enable_events=True, orientation='horizontal', expand_x=True, key='-X-')],
    [sg.Text("Y:", size=3), sg.Slider((-3, 3), resolution=0.1, default_value=0, enable_events=True, orientation='horizontal', expand_x=True, key='-Y-')],
    [sg.Text("Z:", size=3), sg.Slider((-3, 3), resolution=0.1, default_value=0, enable_events=True, orientation='horizontal', expand_x=True, key='-Z-')],
    [sg.Text("Render Mode:"), sg.Combo(['POINTS', "LINES", 'FACES', 'SHADED'], 'FACES', key="-REDNER_TYPE-", readonly=True, enable_events=True)]
]

window = sg.Window('3D Viewport', layout)

drag_loc = None
while True:
    event, values = window.read()

    if event == sg.WIN_CLOSED:
        break

    if event in ['-O-', '-X-', '-Y-', '-Z-']:
        my_object.orientation = values['-O-']
        my_object.position = [values['-X-'], values['-Y-'], values['-Z-']]

    if event == '-GRAPH-':
        new_drag_location = values['-GRAPH-']

        if not drag_loc:
            drag_loc = new_drag_location

        my_object.orientation += (drag_loc[0] - new_drag_location[0]) * 360
        my_object.position[0] += (drag_loc[1] - new_drag_location[1]) * -10

        drag_loc = new_drag_location

        window['-O-'].update(my_object.orientation)
        window['-X-'].update(my_object.position[0])

    if event == '-GRAPH-+UP':
        drag_loc = None

    refresh_view(values['-REDNER_TYPE-'])

window.close()


class ParcelKoro:
    def __init__(self,name = "No name set",weight=0):
        self.name = name
        self.product_weight = weight
        self.fee = 0
    def calculateFee(self,location=None):
        if location != None:
            charge = 100
        else:
            charge = 50
        if self.product_weight == 0:
            pass
        else:
            self.fee = (self.product_weight*20)+charge
    def printDetails(self):
        print("Customer Name:",self.name)
        print("Product Weight:",self.product_weight)
        print("Total fee:",self.fee)

print("**********************")
p1 = ParcelKoro()
p1.calculateFee()
p1.printDetails()
print("**********************")
p2 = ParcelKoro('Bob The Builder')
p2.calculateFee()
p2.printDetails()
print("----------------------------")
p2.product_weight = 15
p2.calculateFee()
p2.printDetails()
print("**********************")
p3 = ParcelKoro('Dora The Explorer', 10)
p3.calculateFee('Dhanmondi')
p3.printDetails()


import math

def solution(w,h):
    if w == h:
        return w*h - w
    elif w == 1 or h == 1:
        return 0
    answer = math.ceil(h/w)
    gcd = math.gcd(h,w)
    gcd_h = h // gcd
    gcd_w = w // gcd

    for i in range(1, gcd_w):
        answer += math.ceil((gcd_h/gcd_w) * (i+1)) - math.floor((gcd_h/gcd_w) * i)

    answer *= gcd
    return (w*h) - answer

if __name__ == "__main__":
    w = 8
    h = 12
    print(solution(w, h))


# Convert SVG to Bezier Curves
# from_svg_path(path_str, shape_to_canvas = torch.eye(3), force_close = False):
# Code snippet from https://stackoverflow.com/questions/59059991/svg-path-not-parsing-correctly-svgpathtools-inkscape
# Input:  directory path for an SVG file
# Output: a list of diffsvg paths which are all cubic bezier curves and are the original curves cut into 8 pieces. (8 is a hyperparam)

def getBeziers(svg_path, pieces = 8):
    mydoc = minidom.parse(svg_path)
    path_tag = mydoc.getElementsByTagName("path")
    d_string = path_tag[0].attributes['d'].value
    x = from_svg_path(d_string)
    for curve in x:
        paths = []
        points = curve.points.clone()
        num_control_points = curve.num_control_points.clone()
        points = torch.cat([points, points[0].unsqueeze(0)], dim = 0) # push element 0 to last point
        anchors = np.cumsum(num_control_points.clone() + 1)
        anchors = torch.cat([torch.tensor([0]), anchors], dim = 0)
        # anchors[i] and anchors[i + 1] are indices of anchors, anything in between are control points
        for idx in range(len(anchors) - 1):
            bezierCurve = bezier.Curve(points[anchors[idx] : anchors[idx + 1] + 1, :].T, degree = anchors[idx + 1] - anchors[idx])
            while bezierCurve.degree < 3: # Make sure everything is cubic
                bezierCurve = bezierCurve.elevate()
            # Split curve into 8 parts
            parts = []
            for i in range(pieces):
                parts.append(bezierCurve.specialize(i / 8, (i + 1) / 8))
            paths = np.concatenate([paths, parts], axis = 0)

        newpoints = np.empty((0, 2))
        new_controls = np.empty(0)

        for path in paths: # get paths back into diffsvg format
            newpoints = np.concatenate([newpoints, path.nodes.T[ : -1, :]], axis = 0)
            new_controls = np.concatenate([new_controls, [path.degree - 1]])

        curve.points = torch.tensor(newpoints)
        curve.num_control_points = torch.tensor(new_controls)
        #print(newpoints)
        #print(new_controls)
    #for c in curves:
    #    c.plot(10, ax = plt)
    print(len(x[0].points))

    print(len(x[0].num_control_points))
    return x


"""this file was made for the class that will represent the
database used to store users and their ratings"""
# pylint: disable=E1101
# pylint: disable=C0413
# pylint: disable=W0603
# pylint: disable=W0611
# pylint: disable=W1508
# pylint: disable=R0903
import flask_sqlalchemy
from app import DB

class allusers(DB.Model):
    """this is the class used to objectify the database in python
    i tried changing the name to pascal case but was thrown errors
    that had to do with the db, which is too deep for me to touch
    with this little time left on this project"""
    id = DB.Column(DB.Integer, primary_key=True)
    username = DB.Column(DB.String(), unique=True)
    rating = DB.Column(DB.Integer)

    def __init__(self, name, rate):
        self.username = name
        self.rating = rate


# Given an array of integers, return a new array with each value doubled.
# For example:
# [1, 2, 3] --> [2, 4, 6]
# For the beginner, try to use the map method - it comes in very handy quite a lot so is a good one to know.
# moje poznamka, python sam o sobe nema nic, co by umoznilo rychle vynasobit list konstantou
def maps(a):
    a2 = [(i * 2) for i in a]
    return a2

print(maps([1, 2, 3]))

# ted se pokusim o pristup pomoci funkce map()
def mapa(a):
    f = lambda x: x * 2

    return [
        f(x)
        for x in a
    ]
    # return list(map(f, a))

print(mapa([1, 2, 3]))


from collections import defaultdict
from functools import reduce
def solution(clothes):
    type = defaultdict(int)
    for cloth in clothes:
        type[cloth[1]]+=1
    return reduce(lambda x, y: x * y, [i+1 for i in type.values()])-1

print(solution([["yellow_hat", "headgear"], ["blue_sunglasses", "eyewear"], ["green_turban", "headgear"]]))

# from collections import Counter
# from functools import reduce
# def solution(clothes):
#     c = [a+1 for a in collections.Counter([x[1] for x in c]).values()]
#     answer = reduce(lambda x,y:x*y,c)-1
#     return answer
# reduce(lambda x,y:x*y,[a+1 for a in collections.Counter([x[1] for x in c]).values()])-1


from django.shortcuts import render,redirect
from django.views.generic import ListView,DetailView,TemplateView,CreateView

from car_rent import settings
from main.models import Car,CarClass,Images,AboutUs,Contacts,CarMarka,SendList
from main.forms import OrderDataForm
from django.urls import reverse_lazy
from threading import Thread
from django.template.loader import render_to_string
import json
from django.core.mail import EmailMessage
from django.core.paginator import Paginator

# Create your views here.
class MainPageView(ListView):
    model = Car
    template_name = 'main.html'
    paginate_by = 3
    context_object_name = 'cars'

    def get_context_data(self, *args, **kwargs):
        context = super(MainPageView, self).get_context_data(**kwargs)
        context['classes'] = CarClass.objects.all()
        context['markas'] = CarMarka.objects.all()
        page = self.request.GET.get('page', 1) if self.request.GET.get('page', 1) != '' else 1
        data = self.get_queryset()
        if data:
            paginator = Paginator(data, self.paginate_by)
            results = paginator.page(page)
            index = results.number - 1
            max_index = len(paginator.page_range)
            start_index = index - 5 if index >= 5 else 0
            end_index = index + 5 if index <= max_index - 5 else max_index
            context['page_range'] = list(paginator.page_range)[start_index:end_index]
        return context

class CarDetailView(DetailView):
    model = Car
    template_name = 'detail.html'
    context_object_name = 'car'

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        images = Images.objects.filter(carr__id=self.get_object().pk)
        print(images)
        context['imagess'] = images
        return context

class CreateOrderView(CreateView):
    form_class = OrderDataForm
    template_name = 'form-fill.html'
    success_url='/success'

    # def get_success_url(self):
    #     return render(self.request,'success.html')

    #

    def form_valid(self,form):
        order = form.save(commit=False)
        order.order_data = self.request.POST.get('all-data')
        order.save()
        return super().form_valid(form)

# def send_email():
#     template_name = 'send-email.html'
#     context = {
#         'data': 'data'
#     }
#     msg = render_to_string(template_name, context)
#     subject = 'Новое заявление'
#     user_emails = SendList.objects.all().values_list('email', flat=True)
#     message = EmailMessage(subject=subject, body=msg, from_email=settings.EMAIL_HOST_USER, to=user_emails)
#     message.content_subtype = 'html'
#     message.send()

class OrderSuccessView(TemplateView):
    # Thread(target=send_email).start()
    template_name = 'success.html'

class AboutUsView(TemplateView):
    template_name = 'about-us.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        about = AboutUs.objects.first()
        context['about'] = about
        return context

class ContactPageView(TemplateView):
    template_name = 'contact.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        contacts = Contacts.objects.first()
        context['contacts'] = contacts
        return context


import sys
sys.stdin = open('bj1761.txt','r')

from collections import deque
def LCA(x,y):
    if Depth[x]>Depth[y]:x,y=y,x
    for i in range(20,-1,-1):
        if Depth[y]-Depth[x]>=1<<i:y=Par[y][i]
    if x==y:return x
    for i in range(20,-1,-1):
        if Par[x][i]!=Par[y][i]:
            x=Par[x][i]
            y=Par[y][i]
    return Par[x][0]
N=int(input())
Map=[[]for _ in range(N+1)]
for _ in range(N-1):
    a,b,l=map(int,input().split())
    Map[a].append((b,l))
    Map[b].append((a,l))
Dis=[0]*(N+1)
Depth=[-1]*(N+1)
Depth[1]=0
Q=deque([(1,0,0)])
Par=[[0]*21 for _ in range(N+1)]
while Q:
    a,depth,dis=Q.popleft()
    for n in Map[a]:
        b,d=n
        if Depth[b]!=-1:continue
        Depth[b]=depth+1
        Dis[b]=dis+d
        Par[b][0]=a
        Q.append((b,depth+1,dis+d))
for j in range(1,20):
    for i in range(1,N+1):
        Par[i][j]=Par[Par[i][j-1]][j-1]
for _ in range(int(input())):
    a,b=map(int,input().split())
    x=LCA(a,b)
    print(Dis[a]+Dis[b]-2*Dis[x])


import pygame
import little_ship_function as function
from little_ship_setting import Setting
from little_ship_ship import Little_ship
from pygame.sprite import Group
from rect import Rect

'''这是一个小飞船的游戏'''

def game_run():
    pygame.init()
    settings = Setting()
    screen = pygame.display.set_mode(
        (settings.screen_width, settings.screen_height))
    pygame.display.set_caption('little ship')

    little_ship = Little_ship(settings, screen)
    bullets = Group()
    rect = Rect(screen, settings)

    while True:
        function.check_event_key(settings, screen, little_ship, bullets)
        little_ship.little_ship_update()
        function.update_bullets(bullets, screen)
        function.update_rect(rect)
        function.update_screen(settings, screen, little_ship, bullets, rect)

game_run()


from tkinter import *
import webbrowser
import backend
from pygame import mixer
import pygame

class Frontend(object):
    def __init__(self,window):
        self.window = window
        self.bk = backend.Backend()
        myfont = ('New Times Roman', 18)

        #Create Labels
        self.lbl = Label(master=window, text="MUSIC DATABASE", font='Helvetica 18 bold')
        self.lbl.grid(row=0, column=2)

        self.lbl = Label(master=window, text="Title", font= myfont)
        self.lbl.grid(row=1, column=0)

        self.lbl2 = Label(master=window, text="Singer", font=myfont)
        self.lbl2.grid(row=1, column=2)

        self.lb3 = Label(master=window, text="Year", font=myfont)
        self.lb3.grid(row=2, column=0)

        #Create text label
        self.name_text =StringVar()
        self.et1 = Entry(master = window, textvariable= self.name_text, font =myfont)
        self.et1.grid(row=1, column =1)

        self.singer_text = StringVar()
        self.et2 = Entry(master=window, textvariable=self.singer_text, font=myfont)
        self.et2.grid(row=1, column=3)

        self.date_text = StringVar()
        self.et2 = Entry(master=window, textvariable=self.date_text, font=myfont)
        self.et2.grid(row=2, column=1)

        #Create Listbox
        self.listbox = Listbox(master=window, height=10, width=40, font=("Times New Roman", 15))
        self.listbox.grid(row=5, column=0, rowspan=8, columnspan=2)

        self.listbox.bind('<<ListboxSelect>>', self.get_row)

        self.scroll = Scrollbar(master=window)
        self.scroll.grid(row=5, column=2, rowspan=8, sticky="nsw")

        self.scroll.configure(command=self.listbox.yview)

        #Create buttons
        self.bt1 = Button(master=window, text="View all", width=20, font=myfont, command=self.view_command)
        self.bt1.grid(row=4, column=3)

        self.bt2 = Button(master=window, text="Add", width=20, font=myfont, command=self.add_command)
        self.bt2.grid(row=5, column=3)

        self.bt3 = Button(master=window, text="Delete", width=20, font=myfont, command= self.delete_command)
        self.bt3.grid(row=6, column=3)

        self.bt4 = Button(master=window, text="Search in Youtube", width=20, font=myfont, command = self.openURL)
        self.bt4.grid(row=7, column=3)

        self.bt5 = Button(master=window, text="Download Song", width=20, font=myfont, command=self.download)
        self.bt5.grid(row=8, column=3)

        self.bt1 = Button(master=window, text="Play from computer", width=20, font=myfont, command=self.playextension)
        self.bt1.grid(row=9, column=3)

        self.bt5 = Button(master=window, text="Close", width=20, font=myfont, command=self.close)
        self.bt5.grid(row=10, column=3)

        #Add functions
    def view_command(self):
        self.listbox.delete(0, END)
        rows = self.bk.view_all()
        for line in rows:
            self.listbox.insert(END, line)

    def add_command(self):
        self.listbox.delete(0, END)
        title = self.name_text.get()
        singer = self.singer_text.get()
        year = self.date_text.get()
        self.bk.add(title=title, singer=singer, year=year)
        self.listbox.insert(END, (title, singer, year))

    def get_row(self, event=None):
        index = self.listbox.curselection()[0]
        line = self.listbox.get(index)
        self.name_text.set(line[1])
        self.singer_text.set(line[2])
        self.date_text.set(line[3])
        return line

    def delete_command(self):
        line = self.get_row()
        self.bk.delete(line[0])
        self.view_command()

    def close(self):
        exit(0)

    def openURL(self):
        song = self.name_text.get()
        artist = self.singer_text.get()
        youtube_search= ('https://www.youtube.com/results?search_query=' + song + " " + artist)
        webbrowser.open(youtube_search)

    def download(self):
        song = self.name_text.get()
        artist = self.singer_text.get()
        download_search= ('https://freedsound.io/es/?q=' + song + " " + artist)
        webbrowser.open(download_search)

    def playextension(self):
        extension = self.name_text.get()
        file = "/Users/saraponton/Movies/Music/" + extension + ".mp3"
        pygame.init()
        pygame.mixer.init()
        mixer.init()
        mixer.music.load(file)
        mixer.music.play()
        pygame.mixer.music.get_busy()

window = Tk()

front = Frontend(window)
window.mainloop()


import os
import ujson as json
import pytups as pt
import pandas as pd
import datetime
import numpy as np

def read_json(filename):
    with open(filename, 'r') as f:
        return json.load(f)

def _treat_stop_area(one_stop):
    get_line_time = lambda v: (v['line']['shortName'], v['dateTime'])
    return pt.TupList(one_stop['departures']['departure']).\
        apply(get_line_time).\
        to_dict(1).\
        vapply(sorted)

def write_table(timetable, filename):
    _test = timetable.apply(lambda v: ','.join(v))
    with open( filename ,'w') as f:
        f.write('\n'.join(_test))

def generate_timetable():
    data_dir = 'data_tisseo/stops_schedules/'
    files = os.listdir(data_dir)
    _get_name = lambda v: os.path.splitext(v)[0]
    files_data = \
        pt.TupList(files). \
            to_dict(None). \
            vapply(_get_name). \
            reverse(). \
            vapply(lambda v: data_dir + v). \
            vapply(read_json)

    all_passing = \
        files_data. \
            vapply(_treat_stop_area). \
            to_dictup(). \
            to_tuplist()

    return all_passing

class Node(object):

    # consists of a trip arriving at a stop at a certain time (in a seq)
    def __init__(self, trip_id, stop_sequence, info, hops=0):
        """

        :param trip_id: the trip (mission, bus)
        :param stop_sequence: sequence of the stop in trip
        :param info: static information on the line
        :param int hops: number of previous transfers before getting into this node
        """
        # convert this to integer has a lot to do with R and
        # it being unable to pass integer arguments
        stop_sequence = int(stop_sequence)
        self.seq = stop_sequence
        self.trip = trip_id
        data = info['stop_times'][trip_id][stop_sequence]
        self.stop = data['stop_id']
        self.time = data['arrival_time']
        self.info = info
        self.route = info['trips'][trip_id]['route_id']
        self.hash = hash(self.__key())
        self.hops = hops
        return

    def __repr__(self):
        route_name = self.info['routes'][self.route]['route_short_name']
        stop_name = self.info['stops'][self.stop]['stop_name']
        time = self.time.strftime('%H:%M')
        return repr('{} @ {} Line:{}'.format(stop_name, time, route_name))

    def get_neighbors_in_trip(self, max_time=None):
        data = self.info['stop_times'][self.trip]
        if max_time is not None:
            data = data.clean(func=lambda v: v['arrival_time'] < max_time)
        if not data:
            return []
        last = max(data.keys())
        return [Node(self.trip, seq, self.info, hops=self.hops)
                for seq in range(self.seq+1, last+1)]

    def get_neighbors_in_stop(self, max_time=None, delta_min=10, walk_speed=5):
        # we take a look for other trips in the same stop filtered by time (5 min wait?)
        # also: they should not share the same route_id.
        _max_time = self.time + datetime.timedelta(minutes=delta_min)
        if max_time is None:
            max_time = _max_time
        else:
            max_time = min(_max_time, max_time)
        # we get the pandas data frame corresponding to that stop or close stops
        # and filter it accordingly
        neighbors = self.info['stops_neigh'][self.stop]
        other_lines = self.info['stop_times_2'].loc[neighbors.keys()]
        other_lines['max_time'] = max_time

        # the minimum time will depend on the distance to that stop
        # other_lines['min_time'] = self.time + datetime.timedelta(minutes=1)
        other_lines['min_time_delta'] = other_lines.index.map(neighbors) * 60/walk_speed + 1
        other_lines['min_time'] = self.time + pd.to_timedelta(other_lines.min_time_delta, unit='minute')

        _filter = (other_lines.arrival_time >= other_lines.min_time) & \
                  (other_lines.arrival_time <= other_lines.max_time) & \
                  (other_lines.route_id != self.route)
        candidates = other_lines[_filter]
        return table_to_candidates(candidates, info=self.info, hops=self.hops+1)

    def __key(self):
        return (self.trip, self.seq)

    def __hash__(self):
        return self.hash

    def __eq__(self, other):
        return self.__key() == other.__key()

def table_to_candidates(stop_times, **kwargs):
    candidates = stop_times[['trip_id', 'stop_sequence']].to_records(index=False)
    return [Node(*can, **kwargs) for can in candidates]

def read_table(name, directory):
    return pd.read_csv(directory + name + '.txt', dtype=str)

def get_tables(directory = 'data_tisseo/tisseo_gtfs/'):
    names = pt.TupList(['stop_times', 'trips', 'routes', 'stops', 'calendar'])
    return names.to_dict(None).vapply(read_table, directory=directory)

def get_info_object(tables, day_of_week='monday', min_hour='11:00:00', max_hour='12:00:00',
                    max_dist_km_walk = 0.5, **kwargs):

    trips = tables['trips']
    calendar = tables['calendar']
    calendar_r = calendar[calendar[day_of_week] == '1']
    trips = trips.merge(calendar_r, on='service_id')
    trip_info = trips.\
        set_index('trip_id')[['route_id', 'direction_id']].\
        to_dict(orient='index')
    trip_info = pt.SuperDict.from_dict(trip_info)

    stop_times = tables['stop_times']
    # TODO: fix this so we do not need to chop the end of the day
    stop_times_info = \
        stop_times\
            [stop_times.arrival_time.str.slice(stop=2) < '24'].\
            merge(trips, on='trip_id')
    stop_times_info = \
        stop_times_info[
            stop_times_info.arrival_time.
            between(min_hour, max_hour)].\
            copy()
    stop_times_info.arrival_time = pd.to_datetime(stop_times_info.arrival_time, format='%H:%M:%S')
    stop_times_info.stop_sequence = stop_times_info.stop_sequence.astype(int)
    stop_times_info_1 = \
        stop_times_info.\
        set_index(['trip_id', 'stop_sequence'])\
        [['arrival_time', 'stop_id']].\
        to_dict(orient='index')
    stop_times_info_1 = pt.SuperDict.from_dict(stop_times_info_1).to_dictdict()

    stop_times_2_info = \
        stop_times_info. \
        set_index('stop_id')[['arrival_time', 'trip_id', 'route_id', 'stop_sequence']]

    # we want the backup in the table. This is becuase R has problems with no-unique indeces.
    stop_times_2_info['stop_id_backup'] = stop_times_2_info.index

    route_info = tables['routes'].set_index('route_id').to_dict(orient='index')
    route_info = pt.SuperDict.from_dict(route_info)

    stops_neighbors = get_positions_table(tables['stops'], stop_times_2_info)

    complete_graph = \
        stops_neighbors.\
        merge(stops_neighbors, on=['stop_lon_g', 'stop_lat_g'])

    stops_neighbors = get_distance_dict(complete_graph, max_dist_km_walk)

    stops_info = tables['stops'].set_index('stop_id').to_dict(orient='index')
    stops_info = pt.SuperDict.from_dict(stops_info)

    return pt.SuperDict(trips=trip_info,  # trip: {info}
                        stop_times=stop_times_info_1,  # (route, sequence): time and stop
                        stop_times_2=stop_times_2_info,  # indexed table
                        routes=route_info,  # route: {info}
                        stops=stops_info,  # stop: {info}
                        stops_neigh=stops_neighbors  # stop: {stop: dist}
                        )

def get_positions_table(stop_table, stop_times_2_info):
    stops_neighbors = \
        stop_table.\
        set_index('stop_id').\
        loc[stop_times_2_info.index.unique()].\
        reset_index().\
        filter(['stop_id', 'stop_lat', 'stop_lon'])

    stops_neighbors.stop_lat = stops_neighbors.stop_lat.astype(float)
    stops_neighbors.stop_lon = stops_neighbors.stop_lon.astype(float)
    stops_neighbors['stop_lat_g'] = stops_neighbors.stop_lat.round(2)
    stops_neighbors['stop_lon_g'] = stops_neighbors.stop_lon.round(2)
    return stops_neighbors

def get_distance_dict(complete_graph, max_dist_km_walk):
    complete_graph['distance'] = \
        haversine_np(complete_graph.stop_lon_x, complete_graph.stop_lat_x,
                    complete_graph.stop_lon_y, complete_graph.stop_lat_y)
    complete_graph['distance'] = complete_graph['distance'].round(4)
    complete_graph = complete_graph[complete_graph.distance < max_dist_km_walk]

    data_neighbors = \
        complete_graph.\
        filter(['stop_id_x', 'stop_id_y', 'distance']).\
        to_records(index=False)

    return \
        pt.TupList(data_neighbors). \
        to_dict(result_col=2, is_list=False).\
        to_dictdict()

def create_no_stop_node(lat, lon, info, min_hour, max_dist_km_walk):
    # node_table => stop_id
    trip_id = 'FAKE'
    stop_seq = -1
    stop_id = 'FAKE'
    route_id = 'FAKE'
    route_short_name = 'FAKE'
    stop_name = 'FAKE'
    # we update the info object with this fake node

    # stop_ids and arrival_times
    _tup = ('stop_times', trip_id, stop_seq, 'stop_id')
    info.set_m(*_tup, value=stop_id)
    _tup = ('stop_times', trip_id, stop_seq, 'arrival_time')
    value = datetime.datetime.strptime(min_hour, "%H:%M:%S")
    info.set_m(*_tup, value=value)

    # route_id:
    _tup = ('trips', trip_id, 'route_id')
    info.set_m(*_tup, value=route_id)

    # names for representation:
    _tup = ('routes', route_id, 'route_short_name')
    info.set_m(*_tup, value=route_short_name)
    _tup = ('stops', stop_id, 'stop_name')
    info.set_m(*_tup, value=stop_name)

    # we get the distances to those nodes to update the neighbors info
    data = dict(stop_id=[stop_id],
                stop_lat=[lat],
                stop_lon=[lon],
                stop_lat_g= [round(lat, 2)],
                stop_lon_g= [round(lon, 2)])
    stop_position = pd.DataFrame(data)
    stop_table = info['stops'].to_df(orient='index').rename_axis('stop_id').reset_index()
    neighbors_positions = get_positions_table(stop_table, info['stop_times_2'])

    complete_graph = \
        stop_position.\
        merge(neighbors_positions, on=['stop_lon_g', 'stop_lat_g'])

    neighbors = get_distance_dict(complete_graph, max_dist_km_walk).get(stop_id)
    _tup = ('stops_neigh', stop_id)
    info.set_m(*_tup, value=neighbors)

    # finally, we create the node and return the graph
    # since this artificial node is not a real line, we reduce the default hop number
    return Node(trip_id=trip_id, stop_sequence=stop_seq, info=info, hops=-1)

def graph_from_nodes(lat, lon, info, min_hour, max_dist_km_walk, **kwargs):
    current = create_no_stop_node(lat, lon, info, min_hour, max_dist_km_walk)
    return graph_from_node(current, **kwargs)

def graph_from_node(current, max_hour, max_hops=1):
    arcs = pt.SuperDict()
    max_time = pd.to_datetime(max_hour, format="%H:%M:%S")
    # nodes that I have not yet seen neighbors
    remaining = [current]
    iter = 0
    while len(remaining) > 0 and iter < 10000:
        iter += 1
        current = remaining.pop()
        if current in arcs:
            # if I've seen this node before:
            # it means I already added all arcs
            continue
        print('iter={}, current={}'.format(iter, current))
        neighbors  = current.get_neighbors_in_trip(max_time)
        if current.hops < max_hops:
            # if we have not yet reached the max number of trips,
            # we can search for a change of trip
            neighbors += current.get_neighbors_in_stop(max_time)
        for node in neighbors:
            arcs.set_m(current, node, value=1)
            remaining.append(node)
    return arcs

def get_lats_longs_from_node(directory, trip, sequence, min_hour, max_hour):
    tables = get_tables(directory)
    info = get_info_object(tables, min_hour=min_hour, max_hour=max_hour)
    current = Node(trip, sequence, info)
    arcs = graph_from_node(current, max_hour=max_hour)
    return get_lats_longs(arcs, info)

def get_lats_longs(arcs, info):
    nodes = set()
    for node, neighbors in arcs.items():
        nodes.add(node)
        for node2 in neighbors:
            nodes.add(node2)
    get_lat = lambda v: float(info['stops'][v.stop]['stop_lat'])
    get_lon = lambda v: float(info['stops'][v.stop]['stop_lon'])
    get_route = lambda v: info['routes'][v.route]['route_short_name']
    get_trip = lambda v: v.trip
    get_seq = lambda v: v.seq
    get_time = lambda v: v.time.strftime('%H:%M')
    get_name = lambda v: info['stops'][v.stop]['stop_name']
    get_all = lambda v: dict(lat=get_lat(v),
                             long=get_lon(v),
                             time=get_time(v),
                             route=get_route(v),
                             name=get_name(v),
                             trip=get_trip(v),
                             seq=get_seq(v))
    return pt.TupList(nodes).to_dict(None).vapply(get_all).to_df(orient='index').reset_index(drop=True)

def haversine_np(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points
    on the earth (specified in decimal degrees)

    All args must be of equal length.

    """
    lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])

    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2

    c = 2 * np.arcsin(np.sqrt(a))
    km = 6367 * c
    return km

if __name__ == '__main__':

    tables = get_tables()
    routes_r = tables['routes'][['route_id', 'route_short_name']]
    trip_r = tables['trips'][['route_id', 'trip_id']].merge(routes_r, on='route_id')

    min_hour = '08:00:00'
    max_hour = '09:00:00'
    max_hops = 1
    info = get_info_object(tables, min_hour=min_hour, max_hour=max_hour)
    filtered_data = info['stop_times_2'].reset_index()[['trip_id', 'stop_sequence', 'stop_id', 'arrival_time']]
    max_hour_dt = pd.to_datetime(max_hour, format='%H:%M:%S')
    min_hour_dt = pd.to_datetime(min_hour, format='%H:%M:%S')
    stoptimes_L1 = \
        trip_r[trip_r.route_short_name == 'L1']. \
        merge(filtered_data, on='trip_id').\
        merge(tables['stops'], on='stop_id').\
        query('"{}"<=arrival_time<="{}"'.format(min_hour_dt, max_hour_dt)).\
        query('stop_name=="Cité de l\'Hers"').sort_values('arrival_time')

    # stoptimes_L1[:5][['trip_id', 'stop_sequence', 'arrival_time']]
    candidates = table_to_candidates(stoptimes_L1[:5], info=info)
    current = candidates[0]
    arcs = graph_from_node(current, max_hour=max_hour, max_hops=max_hops)
    table = get_lats_longs(arcs, info)

    # route: ruta (linea de bus)
    # trip: viaje concreto dentro de una ruta
    # service: ligado a un calendario.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Aug 25 11:38:19 2020

@author: aklimasewski

openquake base gmpes
"""

filename = '/Users/aklimasewski/Documents/data/NGAWest2region.csv'

# nga_data1, nga_targets1, feature_names = readindataNGA(filename,n=12)
# ztest = nga_data1

def gmpe_avg(ztest):
    '''
    transforms cybershake dips and Rx

    Parameters
    ----------
    ztest: 2d numpy array of 12 feature data

    Returns
    -------
    model_avg: average of base model predictions in ln m/s2
    '''
    import numpy as np
    import openquake
    from openquake.hazardlib.gsim.abrahamson_2014 import AbrahamsonEtAl2014   #ASK
    from openquake.hazardlib.gsim.campbell_bozorgnia_2014 import CampbellBozorgnia2014  #CB
    from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014   #CY
    from openquake.hazardlib.gsim.boore_2014 import BooreEtAl2014   #BSSA
    import openquake.hazardlib.imt as imt
    from openquake.hazardlib.const import StdDev
    import openquake.hazardlib.gsim.base as base

    stddev_types = [StdDev.TOTAL]

    period=[10,7.5,5,4,3,2,1,0.5,0.2,0.1]

    gmpeBSSAdata=np.zeros((ztest.shape[0], len(period)))
    gmpeASKdata=np.zeros((ztest.shape[0], len(period)))
    gmpeCBdata=np.zeros((ztest.shape[0], len(period)))
    gmpeCYdata=np.zeros((ztest.shape[0], len(period)))

    gmpeBSSAstd=np.zeros((ztest.shape[0],len(period)))
    gmpeASKstd=np.zeros((ztest.shape[0],len(period)))
    gmpeCBstd=np.zeros((ztest.shape[0],len(period)))
    gmpeCYstd=np.zeros((ztest.shape[0],len(period)))

    gmpeASK = AbrahamsonEtAl2014()
    gmpeCB = CampbellBozorgnia2014()
    gmpeCY = ChiouYoungs2014()
    gmpeBSSA = BooreEtAl2014()

    for i in range(ztest.shape[0]):
        dx = base.DistancesContext()
        dx.rjb=np.array([ztest[i,9]])

        #dx.rjb = np.logspace(-1, 2, 10)
        # Magnitude and rake
        rx = base.RuptureContext()
        rx.mag = np.array([ztest[i,0]])
        rx.rake = np.array([ztest[i,5]])
        rx.hypo_depth = np.array([ztest[i,7]])
        # Vs30
        sx = base.SitesContext()
        sx.vs30 = np.array([ztest[i,2]])
        sx.vs30measured = 0

        dx.rrup=np.array([ztest[i,1]])
        rx.ztor=np.array([ztest[i,11]])
        rx.dip=np.array([ztest[i,6]])
        rx.width=np.array([ztest[i,8]])
        # dx.rx=np.array([rxkeep[i]])
        dx.rx=np.array([ztest[i,10]])

        dx.ry0=np.array([0])
        sx.z1pt0= np.array([ztest[i,3]])
        sx.z2pt5=np.array([ztest[i,4]])

        # Evaluate GMPE
        #Unit of measure for Z1.0 is [m] (ASK)

        #for period1 in period:
        for ii in range(len(period)):
            sx.vs30measured = 0
            period1=period[ii]
            gmpeBSSAdata[i,ii], g = gmpeBSSA.get_mean_and_stddevs(sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeBSSAstd[i,ii]=g[0][0]

            gmpeCBdata[i,ii], g = gmpeCB.get_mean_and_stddevs(sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeCBstd[i,ii]=g[0][0]

            gmpeCYdata[i,ii], g = gmpeCY.get_mean_and_stddevs(sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeCYstd[i,ii]=g[0][0]

            sx.vs30measured = [0]
            gmpeASKdata[i,ii], g = gmpeASK.get_mean_and_stddevs(sx, rx, dx, imt.SA(period1), stddev_types)
            gmpeASKstd[i,ii]=g[0][0]

    model_avg = np.log(9.81*np.exp(np.mean([gmpeBSSAdata,gmpeCBdata,gmpeCYdata,gmpeASKdata],axis=0)))

    #outputs ln m/s2
    return model_avg


###Main module for OCR API application###
from __future__ import print_function
import os
import sys
import subprocess
import json
from PIL import Image
import logging

from flask import jsonify
from fuzzywuzzy import fuzz
from fuzzywuzzy import process

#configure pyhton logging module for log creation
logging.basicConfig(filename="/app/ocr.log",format='%(levelname)s:%(asctime)s:%(message)s', level=logging.DEBUG)

def notallowedfile():
    ocrreply = {
        "response":{
        "ocrtext":"Not allowed file type"
        },
    }
    with open('./ocr/casesdb.json', 'r') as f:
        cases = json.load(f)
    # return jsonify(ocr.file_not_found)
    return (cases["Not_Allowed_File_Ext"], ocrreply["response"])
#this function is used to run tesseract on the image file. Recieve the image file name
def ocr(image):
    print("ocr started", file=sys.stderr)
    logging.info(json.dumps({"action": "ocr started"}))
    command = ['tesseract', image, 'stdout']
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         )

    out, err = p.communicate()
    print("ocr ended", file=sys.stderr)
    logging.info(json.dumps({"action": "ocr finished"}))
    return out, err
#
# #Spcial cases for OCR
# #case a file was not found
file_not_found = {
    "query" : "default"
}
# #case of ocr failure
# ocr_dir_not_work  = {
#     "query": "temp_profile_ocrfail"
# }
# #case of no text was found in the image
# no_text_found = {
#     "query": "ocr_notextfound"
# }

#Function to resize the image file by x3. This increase OCR accuracy
def resizeimage(filename):
    if os.path.getsize(filename) < 999999:
        img = Image.open(filename)
        size = (((img.size[0] * 3), (img.size[1] * 3)))
        img_resized = img.resize(size, Image.ANTIALIAS)
        img_resized.save(filename, "PNG")
        print("image resized", file=sys.stderr)
        logging.info(json.dumps({"action": "image resized"}))

#Function to send the file for OCR function and ruturn the results
def process_file(filename):
    print("start process file", file=sys.stderr)
    logging.info(json.dumps({"action": "file processing started"}))
    #validate that the file exist
    if not os.path.exists(filename):
        print("file not found true", file=sys.stderr)
        logging.warn(json.dumps({"error": "file not found"}))
        return 1, file_not_found

    #send the file for resize if needed
    resizeimage(filename)
    print("start ocr", file=sys.stderr)
    logging.info(json.dumps({"action": "file sent for ocr"}))

#Run OCR on the file using tesseract
    out, err = ocr(filename)
    print("finish ocr", file=sys.stderr)
    logging.info(json.dumps({"action": "returned from ocr"}))
    print(err, file=sys.stderr)
    print(out, file=sys.stderr)

#OCR API Output cases - search for the text from the OCR in the errors DB. Return the OCR text and query
    #prepare the OCR text to be returned by OCR API
    ocrreply = out.decode('utf-8')
    ocrdata = {
        "response":{
        "ocrtext":ocrreply
        },
    }
    #open the cases DB for search
    with open('./ocr/casesdb.json', 'r') as f:
        data = json.load(f)

    #Case of image file withou text in it
    if out == b' \n\x0c':
         return 2, (data["No_Text_Found"], ocrdata["response"])

    #Compare the OCR text with error from the cases DB
    best_fuz =0
    for key in data.keys():
        # Perform fuzzynes comparision between OCR text and casesDB
        fuzzyness = fuzz.partial_ratio(str(key).lower(), str(out).lower())
        logging.info(json.dumps([str(key).lower(), fuzzyness]))
        if fuzzyness > 70:
            if fuzzyness > best_fuz:
                best_key = key
                best_fuz = fuzzyness
            logging.info(json.dumps({"ocr status": "known issue", "ocr text": ocrreply}))
            #return 0, (data[key], ocrdata["response"])
            logging.info(json.dumps([str(key).lower(),fuzzyness]))
        # if str(key).lower() in str(out).lower():
        #      logging.info(json.dumps({"ocr status": "known issue", "ocr text":ocrreply}))
        #      return 0,(data[key],ocrdata["response"])
    if best_fuz > 0:
        return 0, (data[best_key], ocrdata["response"])

    #case that the OCR data was not found in the errors DB
    logging.info(json.dumps({"ocr status": "issue not recognized", "ocr text": ocrreply}))
    return 1, (data["topic_not_recognized"], ocrdata["response"])


import streamlit as st
import datetime as DT
import pandas as pd

def gsc_data_work(df, site_url, days_selector, days_ago):
    try:
        #df = webproperty.query.search_type(search_type).range('today',days=days_ago).dimension('date', 'page').get().to_dataframe()
        df['date'] = pd.to_datetime(df['date']) # Convert date format
        df['clicks'] = pd.to_numeric(df['clicks'], downcast="integer")
        df['ctr'] = pd.to_numeric(df['ctr'], downcast="float")

        ########## INTRO MESSAGE BEGIN ############
        today = DT.date.today()

        start_date = today - DT.timedelta(days=days_selector)
        st.caption(f'You selected Google Discover Data for {site_url} from {start_date} to {today}.')

        ########## INTRO MESSAGE END ############

        return df

    except AttributeError:
        st.error("Check please your property URL, don't forget https://, www, the trailing slash if necessary.")

    if not site_url and refresh_button:
        st.error('Please enter the correct property URL exactly as in your Search Console.')


#JTMS-14
#a5_p1.py
#Muskan Shah
#musshah@jacobs-university.de

#initializing variables
cup = float(input("Enter the volume of cups: "))
gallon = float(input("Enter the volume of gallon: "))

#defining the function for converting gallon and cup to liters and summing them up.
def to_liter(gallon, cup):
    cup = cup * 0.2366
    gallon = gallon * 3.7854
    sum = cup + gallon
    return sum

#printing the result.
print("The sum of cups and gallons in liters is: ", to_liter(gallon, cup))


#! usr/bin/env python

from sys import argv
from os.path import exists
import simplejson as json

script, in_file, out_file = argv

data = json.load(open(in_file))

usable = data["data"]["list"]

geojson = {
    "type": "FeatureCollection",
    "features": [
    {
        "type": "Feature",
        "geometry" : {
            "type": "Point",
            "coordinates": [d["lng"], d["lat"]],
            },
            "properties" : {"price": float(d["price"].replace("M","").replace("K","")),"id_listing": d["id_listing"],"house_type": d["house_type"]}
    }    for d in usable]
}

output = open(out_file, 'w')
json.dump(geojson, output)

print(geojson)