import tensorflow as tf

def scaled_dot_product_attention(q, k, v, mask):

  matmul_qk = tf.matmul(q, k, transpose_b=True)

  # scale matmul_qk
  dk = tf.cast(tf.shape(k)[-1], tf.float32)
  scaled_attention_logits = matmul_qk / tf.math.sqrt(dk)

  # add the mask to the scaled tensor.
  if mask is not None:
    scaled_attention_logits += (mask * -1e9)

  attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1)

  output = tf.matmul(attention_weights, v)

  return output, attention_weights

class Attention(tf.keras.layers.Layer):
  def __init__(self, d_model):
    super(Attention, self).__init__()

    self.wq = tf.keras.layers.Dense(d_model)
    self.wk = tf.keras.layers.Dense(d_model)
    self.wv = tf.keras.layers.Dense(d_model)

  def call(self, v, k, q, mask):
    batch_size = tf.shape(q)[0]

    q = self.wq(q)
    k = self.wk(k)
    v = self.wv(v)

    scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask)

    output = scaled_attention

    return output, attention_weights

class Multi_headed_attention(tf.keras.layers.Layer):
  def __init__(self, d_model, num_heads):
    super(Multi_headed_attention, self).__init__()

    self.num_heads = num_heads
    self.d_model = d_model

    assert d_model % self.num_heads == 0

    self.depth = d_model // self.num_heads

    self.wq = tf.keras.layers.Dense(d_model)
    self.wk = tf.keras.layers.Dense(d_model)
    self.wv = tf.keras.layers.Dense(d_model)

  def split_heads(self, x):
    x = tf.reshape(x,[-1,self.num_heads, self.depth])
    return tf.transpose(x, perm=[1,0,2])

  def call(self, v, k, q, mask):
    batch_size = tf.shape(q)[0]

    q = self.wq(q)
    k = self.wk(k)
    v = self.wv(v)

    q = self.split_heads(q)
    k = self.split_heads(k)
    v = self.split_heads(v)

    scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask)

    concat_attention = tf.reshape(scaled_attention,[-1,self.d_model])

    output = concat_attention

    # output = self.dense(concat_attention)

    return output, attention_weights


#!/usr/bin/env python
#
# ROS service to manage docker containers that implement ROS functionality.
#

'''
Docker naming convention

Let NAME be the container identifier, for example 'hello'

* The container is started by running /opt/bdbd_docker/docker/NAME/run.sh
* The container name and hostname is NAME
* Containers are auto-remove, ie docker run --rm
* Containers are stopped using 'docker stop NAME'

'''
import rospy
import subprocess
import traceback
from bdbd_common.srv import DockerCommand
from queue import Queue
import docker
#import platform

ROS_IP = '192.168.0.59'
ROS_MASTER_URI =' http://nano.dryrain.org:11311/'

class DockerManagement():
    def __init__(self):
        rospy.init_node('dockers')
        self.client = {}
        self.client = docker.from_env()
        self.containers = set()
        #hostname = platform.node().split('.')[0]
        self.dockersService = rospy.Service('/bdbd_docker/containers', DockerCommand, self.handle_containers)
        rate = rospy.Rate(100)
        self.mainQueue = Queue()
        rospy.loginfo('Ready to process commands')
        while not rospy.is_shutdown():
            if not self.mainQueue.empty():
                req_type, name, command, responseQueue = self.mainQueue.get()
                response = None

                try:
                    if req_type == 'containers':
                        response = self.process_containers(name, command)

                    else:
                        rospy.logerr('Invalid dockerManagement req_type {}'.format(req_type))
                        response = 'error'

                except KeyboardInterrupt:
                    break
                except:
                    rospy.logerr(traceback.format_exc())
                finally:
                    if responseQueue:
                        responseQueue.put(response)
                        responseQueue = None
            else:
                rate.sleep()

        # shutdown
        names = list(self.containers)
        for name in names:
            self.process_containers(name, 'stop')

    def handle_containers(self, req):
        rospy.loginfo('Got docker launch request: name:{} command:{}'.format(req.name, req.command))
        responseQueue = Queue()
        self.mainQueue.put(['containers', req.name, req.command, responseQueue])
        response = responseQueue.get()
        rospy.loginfo('Docker launch response: {} {} {}'.format(response, req.name, req.command))
        return response

    def process_containers(self, name, command):
        rospy.loginfo('process container name:{} command:{}'.format(name, command))
        result = 'unexpected'

        container = None
        try:
            container = self.client.containers.get(name)
        except docker.errors.NotFound:
            pass

        if command == 'start':
            if container and container.status == 'running':
                rospy.logwarn('Container {} already active'.format(name))
                result = 'active'
            else:
                try:
                    if container:
                        container.remove()
                    subprocess.run(['/opt/bdbd_docker/docker/' + name + '/run.sh'], check=True)
                    result = 'started'
                    self.containers.add(name)
                except:
                    rospy.logerr(traceback.format_exc())
                    result = 'error'
        elif command == 'stop':
            if container and container.status == 'running':
                container.stop()
                result = 'stopped'
            elif container:
                result = 'inactive'
            else:
                result = 'notfound'
        elif command == 'kill':
            if container and container.status == 'running':
                container.kill()
                result = 'killed'
            elif container:
                result = 'inactive'
            else:
                result = 'notfound'
        else:
            rospy.logerr('Unexpected command: {}'.format(command))
        return result

def main():
    DockerManagement()

if __name__ == '__main__':
    main()


from random import choice

nouns = ['fossil', 'horse', 'aardvark', 'judge', 'chef', 'mango', 'extrovert', 'gorilla']
verbs = ['kicks', 'jingles', 'bounces', 'slurps', 'meows', 'explodes', 'curdles']
adjectives = ['furry', 'balding', 'incredulous', 'fragrant', 'exuberant', 'glistening']
prepositions = ['against', 'after', 'into', 'beneath', 'upon', 'for', 'in', 'like', 'over', 'within']
adverbs = ['curiously', 'extravagantly', 'tantalizingly', 'furiously', 'sensuously']

def make_poem():
    """Create a randomly generated poem, returned as a multi-line string.
    While loops keep looping until first noun is not second noun, as well for noun 3.
    """
    # Pull three nouns randomly
    n1 = choice(nouns)
    n2 = choice(nouns)
    n3 = choice(nouns)
    #Make sure that all are different
    while n1 == n2:
        n2 = choice(nouns)
    while n1 == n3 or n2 == n3:
        n3 = choice(nouns)

    # Pull three random verbs
    v1 = choice(verbs)
    v2 = choice(verbs)
    v3 = choice(verbs)
    while v1 == v2:
        v2 = choice(nouns)
    while v1 == v3 or v2 == v3:
        n3 = choice(verbs)

    # Pull three adjectives
    adj1 = choice(adjectives)
    adj2 = choice(adjectives)
    adj3 = choice(adjectives)
    while adj1 == adj2:
        adj2 = choice(nouns)
    while adj1 == adj3 or adj2 == adj3:
        adj3 = choice(adjectives)

    #Pull one adverb
    adv1 = choice(adverbs)

    #Pull two prepositions
    pre1 = choice(prepositions)
    pre2 = choice(prepositions)
    while pre1 == pre2:
        pre2 = choice(prepositions)

    if 'aeiou'.find(adj1[0]) != -1:  # first letter is a vowel
        article = "An"
    else:
        article = "A"

    # add line to poem
    poem = f'{article} {adj1} {n1}\n\n'  # title of poem
    poem = poem + f'{article} {adj1} {n1} {v1} {pre1} the {adj2} {n2}\n'
    poem = poem + f'{adv1} the {n2} {v2}\n'
    poem = poem + f'the {n2} {v3} {pre2} a {adj3} {n3}'

    return poem

print(make_poem())


import argparse
import sys
import config
import os
import s3operation

s3tdir = os.path.dirname(os.path.realpath(__file__))
with open(s3tdir + "/VERSION", "r") as f:
    VERSION = f.readline()

def parse_args():

    conf = config.get()

    parser = argparse.ArgumentParser(description="Python s3 tools")

    parser.add_argument("-d", "--download", type=str, help="Download a file from a bucket")
    parser.add_argument("-u", "--upload", type=str, help="Upload a file to a bucket")
    parser.add_argument("-c", "--copy", type=str, help="Copy a file from one bucket to another")
    parser.add_argument("-r", "--remove", type=str, help="Remove a file from a bucket")
    parser.add_argument("-t", "--target", type=str, help="Target bucket (for use with --copy)")
    parser.add_argument("-k", "--key", type=str, help="Name to save a file as (for --upload, --copy, --download)")
    parser.add_argument("-l", "--list", type=str, nargs="?", const="*", help="List files on a bucket")
    parser.add_argument("-a", "--all", action="store_true", default=False, help="List all files (no pagination)")
    parser.add_argument("-s", "--settings", action="store_true", default=False, help="Define default settings")
    parser.add_argument("-v", "--version", action="version", version=VERSION)
    parser.add_argument("-b", "--bucket", default=conf["default_bucket"], help="Use specified bucket")
    parser.add_argument("--creds", type=str, nargs="?", const="?", help="Run the tool with credentials")
    parser.add_argument("-n", "--nosize", action="store_true", default=False, help="Don't show size of files")

    args = parser.parse_args()

    args.access_key_id = conf["access_key_id"]
    args.access_key = conf["access_key"]

    if not args.settings:

        if args.creds:
            split = args.creds.split(":")
            if len(split) == 2:
                args.access_key_id = split[0]
                args.access_key = split[1]
            elif args.access_key_id == "" or args.access_key == "":
                parser.error("Please provide credentials in format <access_key_id>:<access_key>")

        if args.bucket == "":
            parser.error("No bucket found. Provide it with -b <bucket> or save a default in the settings by running s3t -s")

        op = args.download != None
        if args.upload != None and op:
            parser.error("Can't combine operations. Choose one of -l, -d, -c, -r or -u")
        else:
            op = op or args.upload != None

        if args.copy != None and op:
            parser.error("Can't combine operations. Choose one of -l, -d, -c, -r or -u")
        else:
            op = op or args.copy != None

        if args.list != None and op:
            parser.error("Can't combine operations. Choose one of -l, -d, -c, -r or -u")
        else:
            op = op or args.list != None

        if args.remove != None and op:
            parser.error("Can't combine operations. Choose one of -l, -d, -c, -r or -u")
        else:
            op = op or args.remove != None

        if op is False:
            parser.error("Please specify an operation (-l, -d, -c, -u, -r)")

        if args.copy and args.target is None:
            parser.error("Please specify a target bucket (-t)")

        if args.upload and args.key is None:
            parser.error("Please specify a target key (-k)")

    return args

def main():
    args = parse_args()
    if args.settings:
        config.settings()
        exit(0)

    if args.list:
        s3operation.list_keys(args.bucket, args.list, all=args.all, access_key_id=args.access_key_id, access_key=args.access_key, showSize=(not args.nosize))
    elif args.download:
        s3operation.download(args.bucket, args.download, filename=args.key, showProgress=(not args.nosize))
    elif args.copy:
        s3operation.copy(args.bucket, args.copy, args.target, target_key=args.key)
    elif args.upload:
        s3operation.upload(args.bucket, args.upload, args.key)
    elif args.remove:
        s3operation.remove(args.bucket, args.remove)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit(0)


gifts = input().split()
line = input()

while line != "No Money":
    command_args = line.split()
    command = command_args[0]
    gift = command_args[1]

    if command == "OutOfStock":
        for idx in range(len(gifts)):
            if gifts[idx] == gift:
                gifts[idx] = "None"
    if command == "Required":
        idx = int(command_args[2])
        if 0 <= idx < len(gifts):
            gifts[idx] = gift
    if command == "JustInCase":
        gifts[-1] = gift
    line = input()

for gift in gifts:
    if gift == "None":
        continue
    print(gift, end=' ')


import random
from PIL import Image
from torch.utils.data import Dataset
import glob
import os
from augmentations import AugmentationTransform
from PIL import ImageFile
from imageio import mimread
from random import choice, randint
import numpy as np
import cv2
import ffmpeg

ImageFile.LOAD_TRUNCATED_IMAGES = True

def color_norm(color, depth=None):
    if depth is not None:
        content = (depth > 0)
        bkg = (depth == 0)
        m, s = np.mean(color[content], axis=0), np.std(color[content], axis=0)
        color[content] = (color[content] - m) / (s*2)
        color[content] = np.clip(color[content], -1., 1.) # [-1, 1]
        color[bkg] = -1.
        depth = np.array(depth, dtype='float32') / np.max(depth) # [0, 1]
        depth = depth * 2. - 1. # [-1, 1]
        color = np.concatenate([color, depth[:, :, None]], axis=2)
    else:
        color = np.array(color, dtype='float32') / 255.
        color = color * 2. - 1. # [-1, 1]
    return color

class AvatarDataset(Dataset):
    def __init__(self, dataset_path, in_channels=3, resample=1, is_train=True) -> None:
        super().__init__()
        self.dataset_path = dataset_path
        self.in_channels = in_channels
        self.resample = resample
        self.is_train = is_train
        self.source = self.read_photo('static.png')
        self.size_of_total = (len(os.listdir(os.path.join(self.dataset_path, 'color'))) - 1) // self.resample
        self.size_of_trainset = self.size_of_total * 8 // 10
        # print(self.dataset_path, self.size_of_total, self.size_of_trainset)

    def read_photo(self, photo_name):
        color = np.array(cv2.imread(os.path.join(self.dataset_path, 'color', photo_name)), dtype='float32')[:, :, [2, 1, 0]]
        if self.in_channels == 4:
            depth = cv2.imread(os.path.join(self.dataset_path, 'depth', photo_name), -1)
            photo = color_norm(color, depth)
        else:
            photo = color_norm(color)
        photo = photo.transpose((2, 0, 1))
        return photo

    def __len__(self):
        if self.is_train:
            return self.size_of_trainset
        else:
            return self.size_of_total - self.size_of_trainset

    def __getitem__(self, index):
        if self.is_train:
            driving = self.read_photo(str(index * self.resample)+'.png')
        else:
            driving = self.read_photo(str((self.size_of_trainset+index) * self.resample)+'.png')
        return self.source, driving

class VideoDataset(Dataset):
    def __init__(self, dataset_path, in_channels=3, is_train=True) -> None:
        super().__init__()
        self.dataset_path = dataset_path
        self.in_channels = in_channels
        self.is_train = is_train
        self.video_list = os.listdir(os.path.join(self.dataset_path, 'color'))
        self.size_of_total = (len(self.video_list))
        self.size_of_trainset = self.size_of_total * 8 // 10

    def load_data_from_video(self, video_name):
        depth_video_path = os.path.join(self.dataset_path, 'depth', video_name[:-4]+'.nut')
        color_video_path = os.path.join(self.dataset_path, 'color', video_name)
        # print(color_video_path, depth_video_path)
        try:
            out_depth_byte, _ = (
                ffmpeg
                    .input(depth_video_path)
                    .output('pipe:', format='rawvideo', pix_fmt='gray16le', loglevel="quiet")
                    .run(capture_stdout=True)
                )
            out_color_bytes, _ = (
                ffmpeg
                    .input(color_video_path)
                    .output('pipe:', format='rawvideo', pix_fmt='rgb24', loglevel="quiet")
                    .run(capture_stdout=True)
                )
        except Exception:
            print('Error in loading video %s %s' % (color_video_path, depth_video_path))
            return None, None
        width, height = 256, 256
        video_depth = np.frombuffer(out_depth_byte, np.uint16).reshape([-1, height, width])
        video_color = np.frombuffer(out_color_bytes, np.uint8).reshape([-1, height, width, 3])
        return video_color, video_depth

    def load_data(self, video_name, index=None):
        video_color, video_depth = self.load_data_from_video(video_name)
        if index is None:
            index = np.random.choice(len(video_color), size=1)
        color = video_color[index].squeeze(0).astype('float32')
        if self.in_channels == 4:
            depth = video_depth[index].squeeze(0)
            # print(index, color.shape, depth.shape, video_color.shape, video_depth.shape)
            color = color_norm(color, depth)
        else:
            color = color_norm(color)
        color = color.transpose((2, 0, 1))
        return color

    def __len__(self):
        if self.is_train:
            return self.size_of_trainset
        else:
            return self.size_of_total - self.size_of_trainset

    def __getitem__(self, index):
        if self.is_train:
            video_name = self.video_list[index]
        elif self.size_of_trainset+index < self.size_of_total:
            video_name = self.video_list[self.size_of_trainset+index]
        else:
            video_name = self.video_list[-1]
        source = self.load_data(video_name, index=[0])
        driving = self.load_data(video_name)
        return source, driving

class MMFace4D(Dataset):
    def __init__(self, split, transform=None, augmentation=False, in_channels=3) -> None:
        super().__init__()
        self.split = split
        self.augmentation = augmentation

        if self.augmentation:
            self.aug = AugmentationTransform(False, True, True)

        self.transform = transform
        self.in_channels = in_channels
        self.real_rgbd_path = os.listdir('./datasets/MMFace4D')
        if self.split == 'test':
            self.real_rgbd_path = os.listdir('./datasets/MMFace4D_test')
        self.img_path = [ os.path.join('./datasets', 'kinect_data')]
        self.avatar_dataset = []
        self.end_of_dataset = []
        sum = 0
        if self.split != 'test':
            for k, v in enumerate(self.img_path):
                if k == 0 and self.split == 'train':
                    self.avatar_dataset.append(AvatarDataset(dataset_path=v, in_channels=in_channels, resample=4))
                else:
                    self.avatar_dataset.append(AvatarDataset(dataset_path=v, in_channels=in_channels, resample=1, is_train=(self.split == 'train')))
                sum += len(self.avatar_dataset[k])
                self.end_of_dataset.append(sum)

            for v in self.real_rgbd_path:
                if not os.path.exists(os.path.join('./datasets/MMFace4D', v, 'color')):
                    continue
                self.avatar_dataset.append(VideoDataset(dataset_path=os.path.join('./datasets/MMFace4D', v), in_channels=in_channels, is_train=(self.split == 'train')))
                sum += len(self.avatar_dataset[-1])
                self.end_of_dataset.append(sum)
        else:
            for v in self.real_rgbd_path:
                if not os.path.exists(os.path.join('./datasets/MMFace4D_test', v, 'color')):
                    continue
                self.avatar_dataset.append(VideoDataset(dataset_path=os.path.join('./datasets/MMFace4D_test', v), in_channels=in_channels, is_train=(self.split == 'train')))
                sum += len(self.avatar_dataset[-1])
                self.end_of_dataset.append(sum)

    def __len__(self):
        if self.split == 'train':
            return sum([len(v) for v in self.avatar_dataset])
        elif self.split == 'test':
            return sum([len(v) for v in self.avatar_dataset])
        elif self.split == 'raw':
            return len(self.avatar_dataset[0])
        else:
            raise NotImplementedError

    def __getitem__(self, idx):
        if self.split == 'raw':
            return self.avatar_dataset[0][idx]
        else:
            for k in range(len(self.avatar_dataset)):
                if idx < self.end_of_dataset[k]:
                    if k == 0:
                        return self.avatar_dataset[k][idx]
                    else:
                        return self.avatar_dataset[k][idx-self.end_of_dataset[k-1]]

class Vox256(Dataset):
    def __init__(self, split, transform=None, augmentation=False):

        if split == 'train':
            self.ds_path = './datasets/vox/train'
        elif split == 'test':
            self.ds_path = './datasets/vox/test'
        else:
            raise NotImplementedError

        self.videos = os.listdir(self.ds_path)
        self.augmentation = augmentation

        if self.augmentation:
            self.aug = AugmentationTransform(False, True, True)
        else:
            self.aug = None

        self.transform = transform

    def __getitem__(self, idx):
        video_path = os.path.join(self.ds_path, self.videos[idx])
        frames_paths = sorted(glob.glob(video_path + '/*.png'))
        nframes = len(frames_paths)

        items = random.sample(list(range(nframes)), 2)

        img_source = Image.open(frames_paths[items[0]]).convert('RGB')
        img_target = Image.open(frames_paths[items[1]]).convert('RGB')

        if self.augmentation:
            img_source, img_target = self.aug(img_source, img_target)

        if self.transform is not None:
            img_source = self.transform(img_source)
            img_target = self.transform(img_target)

            return img_source, img_target

    def __len__(self):
        return len(self.videos)

class Vox256_vox2german(Dataset):
    def __init__(self, transform=None):
        self.source_root = './datasets/german/'
        self.driving_root = './datasets/vox/test/'

        self.anno = pd.read_csv('pairs_annotations/german_vox.csv')

        self.source_imgs = os.listdir(self.source_root)
        self.transform = transform

    def __getitem__(self, idx):
        source_name = str('%03d' % self.anno['source'][idx])
        driving_name = self.anno['driving'][idx]

        source_vid_path = self.source_root + source_name
        driving_vid_path = self.driving_root + driving_name

        source_frame_path = sorted(glob.glob(source_vid_path + '/*.png'))[0]
        driving_frames_path = sorted(glob.glob(driving_vid_path + '/*.png'))[:100]

        source_img = self.transform(Image.open(source_frame_path).convert('RGB'))
        driving_vid = [self.transform(Image.open(p).convert('RGB')) for p in driving_frames_path]

        return source_img, driving_vid, source_name, driving_name

    def __len__(self):
        return len(self.source_imgs)

class Taichi(Dataset):
    def __init__(self, split, transform=None, augmentation=False):

        if split == 'train':
            self.ds_path = './datasets/taichi/train/'
        else:
            self.ds_path = './datasets/taichi/test/'

        self.videos = os.listdir(self.ds_path)
        self.augmentation = augmentation

        if self.augmentation:
            self.aug = AugmentationTransform(True, True, True)
        else:
            self.aug = None

        self.transform = transform

    def __getitem__(self, idx):

        video_path = self.ds_path + self.videos[idx]
        frames_paths = sorted(glob.glob(video_path + '/*.png'))
        nframes = len(frames_paths)

        items = random.sample(list(range(nframes)), 2)

        img_source = Image.open(frames_paths[items[0]]).convert('RGB')
        img_target = Image.open(frames_paths[items[1]]).convert('RGB')

        if self.augmentation:
            img_source, img_target = self.aug(img_source, img_target)

        if self.transform is not None:
            img_source = self.transform(img_source)
            img_target = self.transform(img_target)

        return img_source, img_target

    def __len__(self):
        return len(self.videos)

class Taichi_eval(Dataset):
    def __init__(self, transform=None):
        self.ds_path = './datasets/taichi/test/'
        self.videos = os.listdir(self.ds_path)
        self.transform = transform

    def __getitem__(self, idx):
        vid_name = self.videos[idx]
        video_path = os.path.join(self.ds_path, vid_name)

        frames_paths = sorted(glob.glob(video_path + '/*.png'))
        vid_target = [self.transform(Image.open(p).convert('RGB')) for p in frames_paths]

        return vid_name, vid_target

    def __len__(self):
        return len(self.videos)

class TED(Dataset):
    def __init__(self, split, transform=None, augmentation=False):

        if split == 'train':
            self.ds_path = './datasets/ted/train/'
        else:
            self.ds_path = './datasets/ted/test/'

        self.videos = os.listdir(self.ds_path)
        self.augmentation = augmentation

        if self.augmentation:
            self.aug = AugmentationTransform(False, True, True)
        else:
            self.aug = None

        self.transform = transform

    def __getitem__(self, idx):
        video_path = os.path.join(self.ds_path, self.videos[idx])
        frames_paths = sorted(glob.glob(video_path + '/*.png'))
        nframes = len(frames_paths)

        items = random.sample(list(range(nframes)), 2)

        img_source = Image.open(frames_paths[items[0]]).convert('RGB')
        img_target = Image.open(frames_paths[items[1]]).convert('RGB')

        if self.augmentation:
            img_source, img_target = self.aug(img_source, img_target)

        if self.transform is not None:
            img_source = self.transform(img_source)
            img_target = self.transform(img_target)

        return img_source, img_target

    def __len__(self):
        return len(self.videos)

class TED_eval(Dataset):
    def __init__(self, transform=None):
        self.ds_path = './datasets/ted/test/'
        self.videos = os.listdir(self.ds_path)
        self.transform = transform

    def __getitem__(self, idx):
        vid_name = self.videos[idx]
        video_path = os.path.join(self.ds_path, vid_name)

        frames_paths = sorted(glob.glob(video_path + '/*.png'))
        vid_target = [self.transform(Image.open(p).convert('RGB')) for p in frames_paths]

        return vid_name, vid_target

    def __len__(self):
        return len(self.videos)

if __name__ == '__main__':
    test = Vox256_eval()
    # print(len(test))
    # print(len(test[0]))
    # _, vid = test[0]
    # print(vid[0])
    # print(vid[0].shape)


##Write another program that prompts for a list of numbers
##as above and at the end prints out both the maximum and minimum of
##the numbers instead of the average.

total = 0
count = 0
numbersTuple = []
while True:
    inp = input('Enter a number: ')
    if inp == 'done':
        break
    try:
        number = float(inp)
    except:
        print('Invalid input')
        continue
    numbersTuple.append(number)
    total = total + number
    count = count + 1

print(total, count, max(numbersTuple), min(numbersTuple))


# File: hw1_part8.py
# Author: Nana Owusu
# Date: 9/15/17
# Section: 29
# E-mail: onana1@umbc.edu
# Description: This program ask the user how many items of food they want to bu#y based on a fixed price and calculates and prints the total cost.

def main():

    costApp = 9.5
    costMainDish = 15.8
    costDesserts = 6.55

    print("Appetizers cost" ,costApp,)
    numApp = int(input("How many appetizers would you like to order?:"))
    print("Main dishes cost" ,costMainDish,)
    numMainDish = int(input("How many main dishes would you like to order?:"))
    print("Desserts cost" ,costDesserts,)
    numDesserts = int(input("How many desserts would you like to order?:"))

    totalApp = costApp * numApp
    totalMainDish = costMainDish * numMainDish
    totalDesserts = costDesserts * numDesserts

    totalCost = totalApp + totalMainDish + totalDesserts

    print("The total cost of your meal will be" ,totalCost,)

main()


from ManejadorMedicamentos import ManejadorMedicamentos
from ManejadorCamas import ManejadorCamas
import os

if __name__ == "__main__":

    Camas = ManejadorCamas()
    Medicamentos = ManejadorMedicamentos()

    print("ITEM 1 Y 2")
    print(" SE CARGA EL ARREGLO DE CAMAS")
    Camas.CargarCamas()
    input("Presione ENTER para continuar")
    os.system("cls")
    print("SE CARGA LA LISTA DE MEDICAMENTOS")
    Medicamentos.cargarMedicamentos()
    input("Presione ENTER para continuar")
    os.system("cls")
    print("ITEM 3")
    print("DAR PACIENTE DE ALTA")
    Camas.DarAlta(Medicamentos.Lista())
    input("Presione ENTER para continuar")
    os.system("cls")
    print("ITEM 4")
    print("LISTAR PACIENTES CON DIAGNOSTICO INGRESADO POR TECLADO")
    Camas.Listar()


"""first version of the tables

Revision ID: ec04e32ed985
Revises:
Create Date: 2021-03-09 01:44:52.242038

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'ec04e32ed985'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('entrances',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.Text(), nullable=True),
    sa.Column('driving_time', sa.Integer(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('trails',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.Text(), nullable=True),
    sa.Column('entrance_id', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['entrance_id'], ['entrances.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('trails')
    op.drop_table('entrances')
    # ### end Alembic commands ###


# 16638 괄호 추가하기 2 (G1)
# https://www.acmicpc.net/problem/16638
# 정답

n = int(input())
lst = input()
ans = -1e11

def recur(start, flag, buf):
    global ans

    tmp = lst
    for i in buf: tmp = tmp[:i-1] + '(' + tmp[i-1:i+2] + ')' + tmp[i+2:]
    ans = max(ans, eval(tmp))

    for i in range(start, n//2):
        if (flag & 1<<i) or (flag & 1<<i+1) or (i and flag & 1<<i-1): continue
        recur(i+1, flag | 1<<i, [2*i+1]+buf)

recur(0,0,[])
print(ans)

# 접근 1
# 연산자들을 기준으로 해서 순서를 지정해주자
# 그다음에 그 연산자들의 순서에 맞게 괄호를 쳐주면 되겠다
# 괄호는 어떻게 치지?
# 계산에 사용할 연산자의 인덱스를 찾는다
# 그 인덱스를 기준으로 새로운 연산자가 나타날 때까지 양옆으로 인덱스를 탐색하며 좌우 괄호칠 인덱스를 찾는다
# -> 중첩 괄호 케이스 발생

# 접근 2
# 순서를 지정할 게 아니라 괄호 칠 녀석들을 정확하게 고르는 게 맞다
# 순열이 아니라 조건에 맞는 부분집합을 찾는 문제다
# 그 조건은 괄호를 치기로 한(선택한) 바로 옆의 연산자는 괄호를 치면 안 된다는 것.
# 플래그를 잘 사용하면 되겠다.
# -> 성공

# 접근 3
# 인덱스 찾는 로직 너무 귀찮다;
# 다른 사람 풀이 보니까 괄호를 뒤에서부터 치면 접근하고자하는 인덱스가 변동되는 일이 발생하지 않는다!
# 코드 대폭 줄일 수 있겠다!
# -> 성공


"""RecycleApp sensor."""
from homeassistant.components.sensor import SensorDeviceClass
from typing import Any, Dict, Tuple
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.helpers.entity import Entity
from datetime import datetime, timedelta
import logging
from custom_components.recycle_app.api import FostPlusApi
from .const import DOMAIN, get_icon
from homeassistant import config_entries
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.event import async_track_time_change

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass: HomeAssistant, config_entry: config_entries.ConfigEntry, async_add_entities):
    config: Dict = hass.data[DOMAIN][config_entry.entry_id]
    options = config_entry.options
    api = FostPlusApi()

    zip_code_id: str = config["zipCodeId"]
    street_id: str = config["streetId"]
    house_number: int = config["houseNumber"]
    fractions: Dict[str, Tuple[str, str]] = options.get("fractions")
    language: str = options.get("language", "fr")
    _LOGGER.debug(f'zip_code_id: {zip_code_id}')
    _LOGGER.debug(f'street_id: {street_id}')
    _LOGGER.debug(f'house_number: {house_number}')
    _LOGGER.debug(f'fractions: {fractions}')
    _LOGGER.debug(f'language: {language}')

    async def async_update_collections():
        _LOGGER.debug("Update collections")
        """Fetch data"""
        return await hass.async_add_executor_job(api.get_collections, zip_code_id, street_id, house_number)

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name='RecycleAppGetCollections',
        update_method=async_update_collections
    )

    last_refresh = datetime.utcnow()

    @callback
    async def async_refresh(now):
        nonlocal last_refresh
        if (datetime.utcnow() - last_refresh).total_seconds() > 120:
            last_refresh=datetime.utcnow()
            _LOGGER.debug(f"async_refresh {unique_id}")
            await coordinator.async_refresh()

    # Fetch initial data so we have data when entities subscribe
    await coordinator.async_refresh()
    # Refresh every day at midnight
    async_track_time_change(hass, async_refresh, hour=0, minute=0, second=0);

    unique_id = f"RecycleApp-{zip_code_id}-{street_id}-{house_number}"
    device_info = DeviceInfo(
        entry_type=DeviceEntryType.SERVICE,
        identifiers={(DOMAIN, unique_id)},
        name=config.get("name", "Collecte des poubelles"),
        manufacturer='Fost Plus',
        model='Recycle!'
    )

    if isinstance(fractions, dict):
        async_add_entities([RecycleAppEntity(
            coordinator, f"{unique_id}-{fraction}", fraction, color, name, device_info) for (fraction, (color, name)) in fractions.items()])
    else:
        _LOGGER.error('Your fractions are in the v1 format... Please delete this address and restart.')

class RecycleAppEntity(CoordinatorEntity, Entity):
    """Base class for all RecycleApp entities."""

    def __init__(
            self,
            coordinator: DataUpdateCoordinator,
            unique_id: str,
            fraction: str,
            color: str,
            name: str,
            device_info: Dict[str, Any] = None
    ):
        """Initialize the entity"""
        super().__init__(coordinator)
        self._unique_id = unique_id
        self._fraction = fraction
        self._image = get_icon(fraction, color)
        self._name = name
        self._device_info = device_info
        self._attr_extra_state_attributes = {"days": None}

    @property
    def device_class(self):
        return SensorDeviceClass.DATE

    @property
    def unique_id(self) -> str:
        return self._unique_id

    @property
    def name(self):
        return self._name

    @property
    def icon(self) -> str:
        return "mdi:trash-can"

    @property
    def entity_picture(self):
        return self._image

    @property
    def state(self):
        return self.coordinator.data[self._fraction] if self._fraction in self.coordinator.data else None

    @property
    def available(self) -> bool:
        return self._fraction in self.coordinator.data

    @property
    def device_info(self) -> dict:
        return self._device_info

    @callback
    def async_write_ha_state(self) -> None:
        if (self.state):
            delta: timedelta = self.state - datetime.now().date()
            self._attr_extra_state_attributes["days"] = delta.days
        else:
            self._attr_extra_state_attributes["days"] = None

        super().async_write_ha_state()


from sys import stdin

n, start, end, m = map(int, stdin.readline().split())
graph = [[] for _ in range(n)]

for _ in range(m):
    s, e, v = map(int, stdin.readline().split())
    graph[s].append([e, v])

plus_value = list(map(int, stdin.readline().split()))

visit_graph = [-1e9] * n
visit_graph[start] = plus_value[start]
result = False
for i in range(n):
    for j in range(len(graph[i])):
        for k in range(n):
            if graph[i][j][0] == k:
                graph[i][j][1] = plus_value[k] - graph[i][j][1]

for i in range(n + 1):
    current = visit_graph[end]
    if current == -1e9 and i == n:
        print('gg')
        quit()
    for j in range(n):
        if visit_graph[j] == -1e9:
            continue
        for node, value in graph[j]:
            if visit_graph[j] != -1e9 and visit_graph[node] < visit_graph[j] + value + plus_value[node]:
                visit_graph[node] = visit_graph[j] + value + plus_value[node]
                if i == n:
                    check = [0] * n
                    queue = [node]
                    while queue:
                        current_node = queue.pop()
                        if current_node == end:
                            print('Gee')
                            quit()
                        check[current_node] = 1
                        for next_node, value in graph[current_node]:
                            if check[next_node] == 0:
                                queue.append(next_node)

print(visit_graph[end])


#in Anaconda, use Tkinter, otherwise tkinter
from tkinter import *
import time
import random

###################################

class Frog(object):
    global lily_pad_array

    def __init__(self, canvas, color, score, car, log):
        self.canvas = canvas
        self.color = color
        self.score = score
        self.car = car
        self.log = log
        #width of the frog
        self.rectWidth = 20

        #initializes the speed
        self.x = 0
        self.y = 0

        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

        #setting the initial conditions.
        self.hit_object = False
        self.frog_on_log = False
        self.log_speed = 0
        self.started = False
        self.condition = True
        self.win = False
        self.initial_position = []

        #used by frog.cheat() to check end of game functions
        self.cheat_count = 0

        #binds the movement of the frog to the arrows.
        self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
        self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
        self.canvas.bind_all('<KeyPress-Up>', self.turn_up)
        self.canvas.bind_all('<KeyPress-Down>', self.turn_down)
        self.canvas.bind_all('<KeyPress-C>', self.cheat)

        #the game will start once the left-mouse button is pushed.
        self.canvas.bind_all('<Button-1>', self.start_game)

        #calls the create_frog function to create the initial frog
        self.create_frog()

        #arrays for the coordinates of the cars in rows 1 through 5
        self.car_row_1_coord = []
        self.car_row_2_coord = []
        self.car_row_3_coord = []
        self.car_row_4_coord = []
        self.car_row_5_coord = []
        self.get_car_coordinates()

        #arrays for the coordinates of the logs in rows 1 through 5
        self.car_log_1_coord = []
        self.car_log_2_coord = []
        self.car_log_3_coord = []
        self.car_log_4_coord = []
        self.car_log_5_coord = []
        self.get_log_coordinates()

        #has the frog hit the lily pads?
        self.lily_pad_pos_array = []
        self.hit_lily_pad_array = [False, False, False, False, False]
        self.unwrap_lily_pad_array()

    #function starts the game
    def start_game(self, evt):
        self.started = True

    #creates the initial frog on the canvas
    def create_frog(self):
        #we will eventually want this to be a jpg file
        self.id = canvas.create_rectangle(0,0,self.rectWidth,
                            self.rectWidth, fill = self.color)

        #move frog to this location.
        self.canvas.move(self.id, self.canvas_width/2 - 10, self.canvas_height-1.5*self.rectWidth)
        self.initial_position = self.canvas.coords(self.id)

    # draw the frog in the window/canvas
    def draw(self):
        current_pos = self.canvas.coords(self.id)
        move_frog = False

        #To get the animation of the frog, the frog.draw() checks the current position
        #to the new position defined by the turn_...() functions.

        self.canvas.move(self.id, 1.5*self.rectWidth*self.x, 1.5*self.rectWidth*self.y)
        self.canvas.move(self.id, self.log_speed, 0)

        #returns all speeds back to zero.
        self.x = 0
        self.y = 0
        self.log_speed = 0

    #left and right functions
    def turn_left(self, evt):
        self.x = -1
        self.y = 0

    def turn_right(self, evt):
        self.x = 1
        self.y = 0

    def turn_up(self, evt):
        self.x = 0
        self.y = -1

    def turn_down(self, evt):
        self.x = 0
        self.y = 1

    #check to see if the frog goes off the edge of the canvas
    def check_hit_object(self):
        position = self.canvas.coords(self.id)

        x1 = position[0]
        y1 = position[1]
        x2 = position[2]
        y2 = position[3]

        #check the hit functions depending on where the frog is on the screen
        self.check_hit_edge(x1, y1, x2, y2)

        #Check to see if the from hits a car
        if y1>= self.car_row_5_coord[1]:
            self.log_speed = 0
            self.check_hit_car(x1, y1, x2, y2)

        #check to see if the frog hits the water
        if y2<= self.car_row_5_coord[3] and y1 >= self.log_row_5_coord[1]:
            self.check_hit_water(x1, y1, x2, y2)

        #check to see if the frog lands on a lily pad
        if y2 <= self.log_row_5_coord[1]:
            self.log_speed = 0
            self.check_hit_lily_pad(x1, y1, x2, y2)

        #lose a life if the frog dies
        if self.hit_object == True:
            self.score.lose_life()

    def check_hit_edge (self, x1, y1, x2, y2):
        if x1 < 0 or x2 > self.canvas_width:
            self.hit_object = True

        if y1 <0 or y2 > self.canvas_height:
            self.hit_object = True

    #Get the coordinates of the rows for the cars and pull them into the frog object
    def get_car_coordinates (self):
        self.car_row_1_coord = self.canvas.coords(self.car.car_row_1[1])
        self.car_row_2_coord = self.canvas.coords(self.car.car_row_2[1])
        self.car_row_3_coord = self.canvas.coords(self.car.car_row_3[1])
        self.car_row_4_coord = self.canvas.coords(self.car.car_row_4[1])
        self.car_row_5_coord = self.canvas.coords(self.car.car_row_5[1])
        #print(self.car_row_5_coord)

    #check to see if the frog hits a car
    def check_hit_car(self, x1, y1, x2, y2):
        #check the y-values for row 1
        if y1>= self.car_row_1_coord[1] and y2 <= self.car_row_1_coord[3]:
            #check the x-values
            self.check_hit_row(x1, y1, x2, y2, 1)

        #check the y-values for row 2
        if y1>= self.car_row_2_coord[1] and y2 <= self.car_row_2_coord[3]:
            #check the x-values
            self.check_hit_row(x1, y1, x2, y2, 2)

        #check the y-values for row 3
        if y1>= self.car_row_3_coord[1] and y2 <= self.car_row_3_coord[3]:
            #check the x-values
            self.check_hit_row(x1, y1, x2, y2, 3)

        #check the y-values for row 4
        if y1>= self.car_row_4_coord[1] and y2 <= self.car_row_4_coord[3]:
            #check the x-values
            self.check_hit_row(x1, y1, x2, y2, 4)

        #check the y-values for row 5
        if y1>= self.car_row_5_coord[1] and y2 <= self.car_row_5_coord[3]:
            #check the x-values
            self.check_hit_row(x1, y1, x2, y2, 5)

    #used by the check_hit_car function to cut down on repeated code
    def check_hit_row (self, x1, y1, x2, y2, row_num):
        if row_num == 1:
            row_array = self.car.car_row_1
        elif row_num == 2:
            row_array = self.car.car_row_2
        elif row_num == 3:
            row_array = self.car.car_row_3
        elif row_num == 4:
            row_array = self.car.car_row_4
        elif row_num == 5:
            row_array = self.car.car_row_5

        for i in range(len(row_array)):
            self.car.id = row_array[i]
            car_pos = self.canvas.coords(self.car.id)

            if x1 <= car_pos[2] and x2 >= car_pos[0]:
                print("you hit a car!")
                self.hit_object = True

    #pull log coordinates into the frog object.
    def get_log_coordinates (self):
        self.log_row_1_coord = self.canvas.coords(self.log.log_row_1[1])
        print("Log Row 1: ", self.log_row_1_coord)
        self.log_row_2_coord = self.canvas.coords(self.log.log_row_2[1])
        print("Log Row 2: ", self.log_row_2_coord)
        self.log_row_3_coord = self.canvas.coords(self.log.log_row_3[1])
        print("Log Row 3: ", self.log_row_3_coord)
        self.log_row_4_coord = self.canvas.coords(self.log.log_row_4[1])
        print("Log Row 4: ", self.log_row_4_coord)
        self.log_row_5_coord = self.canvas.coords(self.log.log_row_5[1])
        print("Log Row 5: ", self.log_row_5_coord)

    #check to see if the frog hits the water
    def check_hit_water(self, x1, y1, x2, y2):
        #check the y-values for row 1
        if y1>= self.log_row_1_coord[1] and y2 <= self.log_row_1_coord[3]:
            #print("checking row 1")
            #check the x-values
            self.check_hit_water_row(x1, y1, x2, y2, 1)

        #check the y-values for row 2
        if y1>= self.log_row_2_coord[1] and y2 <= self.log_row_2_coord[3]:
            #check the x-values
            #print("checking row 2")
            self.check_hit_water_row(x1, y1, x2, y2, 2)

        #check the y-values for row 3
        if y1>= self.log_row_3_coord[1] and y2 <= self.log_row_3_coord[3]:
            #check the x-values
            #print("checking row 3")
            self.check_hit_water_row(x1, y1, x2, y2, 3)

        #check the y-values for row 4
        if y1>= self.log_row_4_coord[1] and y2 <= self.log_row_4_coord[3]:
            #check the x-values
            #print("checking row 4")
            self.check_hit_water_row(x1, y1, x2, y2, 4)

        #check the y-values for row 5
        if y1>= self.log_row_5_coord[1] and y2 <= self.log_row_5_coord[3]:
            #print("checking row 5")
            self.check_hit_water_row(x1, y1, x2, y2, 5)

    #used by the check_hit_water function to cut down on repeated code.
    def check_hit_water_row(self, x1, y1, x2, y2, row_num):
        self.frog_on_log = False

        if row_num == 1:
            row_array = self.log.log_row_1

        elif row_num == 2:
            row_array = self.log.log_row_2
        elif row_num == 3:
            row_array = self.log.log_row_3
        elif row_num == 4:
            row_array = self.log.log_row_4
        elif row_num == 5:
            row_array = self.log.log_row_5

        #cycle through all logs in row to see if the frog is on any of them.
        for i in range(len(row_array)):
            self.log.id = row_array[i]
            log_pos = self.canvas.coords(self.log.id)

            #check to see if the frog is on a log.
            if x1 <= log_pos[2] and x2 >= log_pos[0]:
                self.frog_on_log = True

                if row_num ==1:
                    self.log_speed =  3
                elif row_num == 2:
                    self.log_speed = -2
                elif row_num == 3:
                    self.log_speed = 5
                elif row_num == 4:
                    self.log_speed = -2.5
                elif row_num == 5:
                    self.log_speed = 4

        #If the frog is not on a log, it dies.
        if self.frog_on_log == False:
            print("you fell in the water!")
            self.hit_object = True

    #pull information in from the lily pad set up.
    def unwrap_lily_pad_array(self):
        global lily_pad_array

        for i in range(len(lily_pad_array)):
            self.lily_pad_id = lily_pad_array[i]
            #print(self.lily_pad_id)
            lily_pad_pos = self.canvas.coords(self.lily_pad_id)
            #print(lily_pad_pos)
            self.lily_pad_pos_array.append(lily_pad_pos)

    def check_hit_lily_pad(self, x1, y1, x2, y2):
        global lily_pad_array
        #check to see if the frog makes it into the top spots.
        print("Checking the lily pad function")
        #check to see if the the frog makes it between the x-values.

        for i in range(len(self.lily_pad_pos_array)):
            lily_pad_pos = self.lily_pad_pos_array[i]
            #print(lily_pad_pos)
            #print("self.hit_lily_pad_array[i]: ", self.hit_lily_pad_array[i])
            #check to see if the frog is on a lilypad.
            if x1 <= lily_pad_pos[2] and x2 >= lily_pad_pos[0]:
                #has the frog already been on that lilypad?
                if self.hit_lily_pad_array[i] == True:
                    print("You've already jumped on this lily pad!")
                    self.hit_object = True
                    #print("Inside the 'True': ", self.hit_lily_pad_array[i])
                elif self.hit_lily_pad_array[i] == False:
                    #print("Inside the 'False': ", self.hit_lily_pad_array[i])
                    print("The frog is on lily pad: ", [i])
                    self.hit_lily_pad_array[i] = True
                    #print(lily_pad_array[i])
                    self.canvas.itemconfig(lily_pad_array[i], fill="green")
                    self.move_frog_back()
                    self.score.increase()

                #Controls the values of the self.cheat()
                self.cheat_count +=1

        #check to see if all 5 lily pads have been landed on
        self.check_win()

    def move_frog_back(self):
        frog_position = self.canvas.coords(self.id)
        self.canvas.move(self.id, -frog_position[0], -frog_position[1])
        self.canvas.move(self.id, self.initial_position[0], self.initial_position[1])

    #once the frog has filled in all the lily pads, the game is won
    def check_win(self):
        lily_pad_count = 0
        for i in range(len(self.hit_lily_pad_array)):
            if self.hit_lily_pad_array[i] == True:
                lily_pad_count +=1
                print("lily pad count: ", lily_pad_count)
            elif self.hit_lily_pad_array[i] == False:
                pass

        if lily_pad_count == 5:
            self.win == True
            print("You win!!!")

    #Pressing Shift+C will move the frog directly to the lily pad
    #Use this function to test end-of-game functions.
    def cheat(self, evt):
        global lily_pad_array
        print("Running the cheat function")
        i = self.cheat_count
        frog_position = self.canvas.coords(self.id)
        lily_pad_pos = self.lily_pad_pos_array[i]
        self.canvas.move(self.id, -frog_position[0], -frog_position[1])
        self.canvas.move(self.id, lily_pad_pos[0]+2, lily_pad_pos[1]+2)

######################################
class Car(object):

    def __init__(self, canvas):
        self.canvas = canvas
        self.color = ""
        self.car_type = ""
        self.row = 1
        self.column = 1

        #setting up the car arrays
        #this one is for animation
        self.car_object_wrapper = []

        #these are for checking to see if the frog gets hit
        self.car_row_1 = []
        self.car_row_2 = []
        self.car_row_3 = []
        self.car_row_4 = []
        self.car_row_5 = []

        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

        #width of car
        self.rectWidth = 20
        self.carLength = 2*self.rectWidth

        #the x-value and y-value placement of the car
        self.col_placement = self.rectWidth
        self.row_placement = self.rectWidth

        #initializes the speed
        self.x = 4
        self.set_up_cars(canvas)

    def set_up_cars(self, canvas):
        #self.set_up_cars_row(canvas, color, row #, car type, x speed)
        self.set_up_cars_row(canvas, "purple", 1, "car", 5)
        self.set_up_cars_row(canvas, "blue", 2, "truck", -4)
        self.set_up_cars_row(canvas, "red", 3, "car", 3, )
        self.set_up_cars_row(canvas, "yellow", 4, "truck", -5)
        self.set_up_cars_row(canvas, "orange", 5, "car", 6)

    def set_up_cars_row(self, canvas, color, row, car_type, x_speed):
        self.color = color
        self.row = row
        self.car_type = car_type
        self.x = x_speed

        for i in range(1, 6):
            self.choose_col(i)
            self.create_car()

    def choose_car_type(self):
        if self.car_type == "car":
            self.carLength = 2*self.rectWidth
        if self.car_type == "truck":
            self.carLength = 3*self.rectWidth

    def choose_row(self):
        #choosing the y-value placement
        self.row_placement = self.canvas_height-self.row*1.5*self.rectWidth-(1.5*self.rectWidth)

    def choose_col(self, column):
        self.column = column
        #choosing the x-value placement
        self.col_placement = -self.carLength + (self.column-1)*self.canvas_width/5

    #creates the initial car on the canvas
    def create_car(self):
        self.choose_car_type()
        self.choose_row()

        #we will eventually want this to be a jpg file
        self.id = canvas.create_rectangle(0,0,self.carLength,
                            self.rectWidth, fill = self.color)

        #move car to this location:
        self.canvas.move(self.id, self.col_placement, self.row_placement)
        self.car_object_wrapper.append([self.id, self.row, self.x])

        #add the newly created cars to their respective lists for the check_hit functions
        if self.row == 1:
            self.car_row_1.append(self.id)
        elif self.row == 2:
            self.car_row_2.append(self.id)
        elif self.row == 3:
            self.car_row_3.append(self.id)
        elif self.row == 4:
            self.car_row_4.append(self.id)
        elif self.row == 5:
            self.car_row_5.append(self.id)

    #animate the car in the window/canvas
    def draw(self):
        for i in range(0, len(self.car_object_wrapper)):
            car_id = self.car_object_wrapper[i][0]
            row_id= self.car_object_wrapper[i][1]
            speed_id = self.car_object_wrapper[i][2]
            self.canvas.move(car_id, speed_id, 0)
            self.reset_car(car_id, row_id, speed_id)

    #move the car back to the beginning
    def reset_car(self, car_id, row_id, speed_id):
        self.id = car_id
        self.row = row_id
        self.x = speed_id
        position = self.canvas.coords(self.id)
        if self.x > 0:
            if position[0] > self.canvas_width:
                self.canvas.move(self.id, -self.canvas_width-20, 0)
        if self.x < 0:
            if position[2] < 0:
                self.canvas.move(self.id, self.canvas_width+20, 0)

######################################
class Log(object):
    def __init__(self, canvas):
        self.canvas = canvas
        self.color = ""
        self.log_type = ""
        self.row = 1
        self.column = 1

        #setting up the log arrays
        #this one is for animation
        self.log_object_wrapper = []

        #these are for checking to see if the frog gets hit
        self.log_row_1 = []
        self.log_row_2 = []
        self.log_row_3 = []
        self.log_row_4 = []
        self.log_row_5 = []

        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

        #width of log
        self.rectWidth = 20
        self.logLength = 2*self.rectWidth

        #the x-value and y-value placement of the log
        self.col_placement = self.rectWidth
        self.row_placement = self.rectWidth

        #initializes the speed
        self.x = 4
        self.set_up_logs(canvas)

    def set_up_logs(self, canvas):
        #self.set_up_logs_row(canvas, color, row #, log type, x speed)
        self.set_up_logs_row(canvas, "brown", 1, "log", 3)
        self.set_up_logs_row(canvas, "dark green", 2, "turtle", -2)
        self.set_up_logs_row(canvas, "brown", 3, "log", 5, )
        self.set_up_logs_row(canvas, "dark green", 4, "turtle", -2.5)
        self.set_up_logs_row(canvas, "brown", 5, "log", 4)

    def set_up_logs_row(self, canvas, color, row, log_type, x_speed):
        self.color = color
        self.row = row
        self.log_type = log_type
        self.x = x_speed

        for i in range(1, 6):
            self.choose_col(i)
            self.create_log()

    def choose_log_type(self):
        if self.log_type == "log":
            self.logLength = 3*self.rectWidth
        if self.log_type == "turtle":
            self.logLength = 2*self.rectWidth

    def choose_row(self):
        #choosing the y-value placement
        self.row_placement = self.canvas_height-self.row*1.5*self.rectWidth-(7*30)
        #canvas_height-(35+ 2*1.5*5*20+30+30)
    def choose_col(self, column):
        self.column = column
        #choosing the x-value placement
        self.col_placement = -self.logLength + (self.column-1)*self.canvas_width/5

    #creates the initial log on the canvas
    def create_log(self):
        self.choose_log_type()
        self.choose_row()

        #we will eventually want this to be a jpg file
        self.id = canvas.create_rectangle(0,0,self.logLength,
                            self.rectWidth, fill = self.color)

        #move log to this location:
        self.canvas.move(self.id, self.col_placement, self.row_placement)
        self.log_object_wrapper.append([self.id, self.row, self.x])

        #add the newly created logs to their respective lists for the check_hit functions
        if self.row == 1:
            self.log_row_1.append(self.id)
        elif self.row == 2:
            self.log_row_2.append(self.id)
        elif self.row == 3:
            self.log_row_3.append(self.id)
        elif self.row == 4:
            self.log_row_4.append(self.id)
        elif self.row == 5:
            self.log_row_5.append(self.id)

    #animate the log in the window/canvas
    def draw(self):
        for i in range(0, len(self.log_object_wrapper)):
            log_id = self.log_object_wrapper[i][0]
            row_id= self.log_object_wrapper[i][1]
            speed_id = self.log_object_wrapper[i][2]
            self.canvas.move(log_id, speed_id, 0)
            self.reset_log(log_id, row_id, speed_id)

    #move the log back to the beginning
    def reset_log(self, log_id, row_id, speed_id):
        self.id = log_id
        self.row = row_id
        self.x = speed_id
        position = self.canvas.coords(self.id)
        if self.x > 0:
            if position[0] > self.canvas_width:
                self.canvas.move(self.id, -self.canvas_width-50, 0)
        if self.x < 0:
            if position[2] < 0:
                self.canvas.move(self.id, self.canvas_width+40, 0)

######################################
class Score(object):
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.color = color
        self.score = 0
        self.lives = 3
        self.lose = False
        self.canvas_width = self.canvas.winfo_width()
        self.id = canvas.create_text(self.canvas_width-60, 10, text = "Score: ", \
                                     fill = color)
        self.score_id = canvas.create_text(self.canvas_width-30, 10, text=self.score, \
                                     fill=color)

        self.id = canvas.create_text(30, 10, text = "Lives: ", \
                                     fill = color)
        self.lives_id = canvas.create_text(60, 10, text = self.lives, \
                                     fill = color)

    #increase the score by 1
    def increase(self):
        self.score += 1
        self.canvas.itemconfig(self.score_id, text=self.score)

    #lose a life
    def lose_life(self):
        self.lives -=1
        self.canvas.itemconfig(self.lives_id, text=self.lives)
        self.check_life()

    #check to see if the player has any lives left
    def check_life(self):
        if self.lives == 0:
            self.lose = True

######################################
class Game(object):
    def __init__(self, canvas, frog, car, log, score):
        self.canvas = canvas
        self.frog = frog
        self.car = car
        self.log = log
        self.score = score
        self.speed = 0.05
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()

    def restart(self):

        self.frog.condition = False
        self.hit_text = canvas.create_text(self.canvas_width/2,200,text="You Died!",
                                    fill="black",font="TimesNewRoman 36")
        tk.update_idletasks()
        tk.update()

        if self.score.lose == False:
            self.frame = Frame(tk)
            self.frame.pack()

            self.button_quit = Button(self.frame, text="QUIT", bg="green", command = quit)
            self.button_quit.pack(side=LEFT)
            self.button_again = Button(self.frame,text="PLAY AGAIN", bg = 'green', command = self.play_again)
            self.button_again.pack(side=LEFT)

        if self.score.lose == True:
            if frog.hit_object == True:
                self.canvas.delete(self.hit_text)
                self.gameOverText = canvas.create_text(self.canvas_width/2,200,text="Game Over",
                                    fill="black",font="TimesNewRoman 15")
                time.sleep(2)
                self.frog.condition = False

    def win_the_game(self):
        self.frog.condition = False
        self.hit_text = canvas.create_text(self.canvas_width/2,200,text="You Win!",
                                    fill="black",font="TimesNewRoman 36")
        tk.update_idletasks()
        tk.update()

    def play_again(self):
        #removes the buttons and the extra row off the canvas
        self.button_quit.destroy()
        self.button_again.destroy()
        self.frame.destroy()

        #resets the score
        self.score.score = 0
        self.canvas.itemconfig(self.score.score_id, text=self.score.score)
        self.canvas.delete(self.hit_text)

        #resets the frog
        self.canvas.delete(self.frog.id)
        frog = Frog(canvas, "green", score, car, log)
        self.frog = frog

        #starts the mainloop again
        self.mainloop()

    #This is our animation loop
    def mainloop(self):
        while self.frog.condition:
            if self.frog.started == True:
                if self.frog.hit_object==False:
                    self.frog.check_hit_object()
                    self.frog.draw()
                    self.car.draw()
                    self.log.draw()
                elif self.frog.hit_object==True:
                    self.restart()
                if self.score.score >= 5:
                    self.win_the_game()

            tk.update_idletasks()
            tk.update()
            time.sleep(self.speed)

def window_setup(canvas):
    global lily_pad_array

    canvas_height = canvas.winfo_height()
    canvas_width = canvas.winfo_width()

    #create the grass areas
    grass1 = canvas.create_rectangle (0,0,canvas_width, 35, fill="dark green")
    canvas.move(grass1, 0, canvas_height-35)
    grass2 = canvas.create_rectangle(0,0, canvas_width, 30, fill = "dark green")
    canvas.move(grass2, 0, canvas_height-(35+1.5*6*20))
    grass3 = canvas.create_rectangle (0,0,canvas_width, 35, fill="dark green")
    canvas.move(grass3, 0, canvas_height-(35+ 2*1.5*5*20+30+35))

    #create the spaces for the frog to go in (lily pads)
    lily_pad_1 = canvas.create_rectangle (0,0, 30, 30, fill = "dark gray")
    canvas.move(lily_pad_1, canvas_width/6-15,canvas_height-(35+ 2*1.5*5*20+30+30))

    lily_pad_2 = canvas.create_rectangle (0,0, 30, 30, fill = "dark gray")
    canvas.move(lily_pad_2, 2*canvas_width/6-15,canvas_height-(35+ 2*1.5*5*20+30+30))

    lily_pad_3 = canvas.create_rectangle (0,0, 30, 30, fill = "dark gray")
    canvas.move(lily_pad_3, 3*canvas_width/6-15, canvas_height-(35+ 2*1.5*5*20+30+30))

    lily_pad_4 = canvas.create_rectangle (0,0, 30, 30, fill = "dark gray")
    canvas.move(lily_pad_4, 4*canvas_width/6-15,canvas_height-(35+ 2*1.5*5*20+30+30))

    lily_pad_5 = canvas.create_rectangle (0,0, 30, 30, fill = "dark gray")
    canvas.move(lily_pad_5, 5*canvas_width/6-15,canvas_height-(35+ 2*1.5*5*20+30+30))

    lily_pad_array.append(lily_pad_1)
    lily_pad_array.append(lily_pad_2)
    lily_pad_array.append(lily_pad_3)
    lily_pad_array.append(lily_pad_4)
    lily_pad_array.append(lily_pad_5)

    #create the road area
    road = canvas.create_rectangle(0,0, canvas_width, 1.5*5*20, fill = "dark gray")
    canvas.move(road, 0, canvas_height-(35 + 1.5*5*20))

    #create the water area
    water = canvas.create_rectangle(0,0, canvas_width, 1.5*5*20, fill = "light blue")
    canvas.move(water, 0, canvas_height-(35 + 2*1.5*5*20 + 30))

#Normal tkinter intro.
tk = Tk()
#Title of the game
tk.title("Frogger")
tk.resizable(0, 0)
#window appears on top
tk.wm_attributes("-topmost", 1)
#dimensions of the canvas
canvas = Canvas(tk, width=900, height=420, bd=0, highlightthickness=0)
canvas.pack()

#tkinter redraws the canvas
tk.update()

#this array contains the coordinates for the winning spaces at the top of the game board
lily_pad_array = []
#runs the function which sets up the game window
window_setup(canvas)

#defines all the objects on the screen
car = Car(canvas)
log = Log(canvas)
score = Score(canvas, "blue")
frog = Frog(canvas, "green", score, car, log)
game = Game(canvas, frog, car, log, score)

#run the main loop
game.mainloop()


from math import inf, nan

def inverse_quadratic_interpolation(f, a, b, tol):
    """
    Using the inverse quadratic interpolation,
    find a zero of the function f to accuracy tol with starting points (a,b).

    (a, b) need not bracket a zero.

    Each iteration of the algorithm requires three points, (a, b, c);
    on the first iteration, the third point, c, is chosen as the arithmetic mean of (a,b).

    Fails whenever any two of f(a), f(b), f(c) are equal (no inverse).

    :param callable f: the function whose zeros are to be found
    :param float a: the first starting point
    :param float b: the second starting point
    :param float tol: tightness of convergence
    :return float: d, the coordinate of the zero if found, otherwise nan
    """
    dx = inf
    c = (a + b) / 2
    d = nan
    fa, fc, fb = f(a), f(c), f(b)
    while abs(dx) > tol:
        if not fa == fb or fb == fc or fc == fa:
            return nan
        d = (a * fc * fb / (fa - fc) / (fa - fb) +
             c * fa * fb / (fc - fa) / (fc - fb) +
             b * fa * fc / (fb - fa) / (fb - fc))
        a, c, b = c, b, d
        fa, fc, fb = fc, fb, f(d)
        dx = b - a
    return d


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

#Based on sXML-master projet on gitHub

__author__= "Luis C. Pérez Tato (LCPT)"
__copyright__= "Copyright 2015 LCPT"
__license__= "GPL"
__version__= "3.0"
__email__= "l.pereztato@gmail.com"

from import_export.sciaXML.xml_basics import scxml_properties_container as ctr
from import_export.sciaXML import node_container as nc
from import_export.sciaXML.xml_basics import scxml_property as prop
from import_export.sciaXML.xml_basics import scxml_properties_table as propTable
import xml.etree.cElementTree as ET

idName= '{4364BC01-AAB7-11D4-B3D9-00104BC3B531}'
idXCoord= '{C1DD759A-4291-481B-B819-92E3AA9E04B7}'
idYCoord= '{A84A15AC-FEC2-4C27-84B4-CFA676615934}'
idZCoord= '{1017EA1E-F76B-4D4B-8A4C-7E58FDED1B02}'
idNodeTable= 'F67B790F-88D4-41ED-A3B9-3D9F9744B5AF' #sin llavecitas

class NodeProperties(ctr.SCXMLPropertiesContainer):
  tableDef= None
  def __init__(self):
    super(NodeProperties,self).__init__(nc.idNodeContainer,nc.idNodeContainer,nc.progIdNodes)
    self.tableDef= propTable.SCXMLPropertiesTable(idNodeTable,"XML\default","vertical",nc.idNodeContainer,nc.progIdNodes)
    self.tableDef.properties.append(prop.SCXMLProperty("0","Name","string",idName))
    self.tableDef.properties.append(prop.SCXMLProperty("1","XCoord","param",idXCoord,"33619968"))
    self.tableDef.properties.append(prop.SCXMLProperty("2","YCoord","param",idYCoord,"33619968"))
    self.tableDef.properties.append(prop.SCXMLProperty("3","ZCoord","param",idZCoord,"33619968"))

  def getXMLElement(self,parent):
    '''Returns the corresponding XML element for the node properties.
       Parameters:
       parent: owner of this object in the XML structure.'''
    container= ET.SubElement(parent,"def_container")
    self.populateXMLElement(container)
    self.tableDef.getXMLElement(container)
    return container


#import sokcet
import socket

host = "127.0.0.1"
#inisialisasi socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#kirim permintaan koneksi
#sock.bind(("0.0.0.0", 7774))
sock.connect((host, 7774))
t = input("queue : ")
sock.send(t.encode("ascii"))
data = sock.recv(100)
print(data)
while True :
    #q = input("queue : ")
    #sock.send(q.encode("ascii"))
    data = sock.recv(100)
    print(data)
    #data = input ("Masukkan kata : ")
    #sock.send(data.encode("ascii"))


import os
import redis
from rq import Worker, Queue, Connection

listen = ['high', 'default', 'low']

ON_HEROKU = 'ON_HEROKU' in os.environ
if ON_HEROKU:
    conn = redis.from_url(os.environ.get('REDIS_URL'))
else:
    conn = redis.Redis()

if __name__ == '__main__':
    with Connection(conn):
        if not ON_HEROKU and os.name == 'nt':
            from rq_win import WindowsWorker
            worker = WindowsWorker(map(Queue, listen))
        else:
            worker = Worker(map(Queue, listen))
        worker.work()


#!/usr/bin/env python
from typing import Tuple, Dict, Union, NoReturn
import numpy as np

from PlaxisRectangleGrid import utils
from PlaxisRectangleGrid.calc_func import distance_euc

class Point(object):
    def __init__(self, pt):
        self._coords = pt

    @property
    def x(self):
        return self._coords[0]

    @x.setter
    def x(self, x):
        self._coords[0] = x

    @property
    def z(self):
        return self._coords[1]

    @z.setter
    def z(self, z):
        self._coords[0] = z

    @property
    def u_y(self) -> float:
        return self._coords[2]

    @u_y.setter
    def u_y(self, u_y: Union[int, float]) -> NoReturn:
        self._coords[2] = u_y

    @property
    def coords(self):
        return self._coords

    @coords.setter
    def coords(self, new_coords):
        self._coords = np.ndarray(new_coords, dtype='float')

    @property
    def xz(self):
        return self._coords[:2]

    def nearby_points(self,
                      points: np.ndarray,
                      eps_x=1,
                      eps_z=1
                      ) -> Tuple[np.ndarray, list]:
        """
        Функция поиска ближайщих точек массива для данной точки. Ищет в
        заданной окрестности (eps_x, eps_z). Поиск происходит делением
        точек на 4 части (верх-право, верх-лево, низ-право, низ-лево)
        относительно самой точки(центр) и последующим нахождением минимального
        расстояния(евклидова метрика) из расстояний каждой точки до центра в
        каждой четверти.

        :param points: массив точек [[x1, z1, u_y1], [x2, z2, u_y2] ...]
        :param eps_x: окрестность поиска по горизонтальной оси
        (имеет смысл задавать как шаг сетки)
        :param eps_z: окрестность поиска по вертикальной оси
        (имеет смысл задавать как шаг сетки)
        :return: возвращает массив ближайщих точек(максимум 4) и
        массив расстояний от этих точек до данной точки
        """

        right_limit = self.x + eps_x  # правая граница поиска
        left_limit = self.x - eps_x  # левая граница поиска
        upper_limit = self.z + eps_z  # верхняя граница поиска
        lower_limit = self.z - eps_z  # нижняя граница поиска

        # Ищем точки в заданной окрестности (eps_x, eps_z)
        eps_area = points[np.where(
            (points[:, 0] <= right_limit) &
            (points[:, 0] >= left_limit) &
            (points[:, 1] <= upper_limit) &
            (points[:, 1] >= lower_limit))]

        # создаем маску для точек лежащие левее(и на вертикальной линии
        # проходящей через данную точку) и правее от данной точки
        mask_vertical = eps_area[:, 0] <= self.x

        # в случае если все точки окажутся левее пробуем более строгое условие,
        # т.к. некоторые точки могут оказаться на вертикальной линии проходящей
        # через данную точку
        if np.sum(mask_vertical == True) == len(eps_area):
            mask_vertical = eps_area[:, 0] < self.x

        # по маске создаем массивы точек лежащих слева и справа
        right = eps_area[mask_vertical]
        left = eps_area[~mask_vertical]

        # для левых и правых точек создаем маски для точек лежащие выше(и на
        # горизонтальной линии проходящей через данную точку) и ниже от
        # данной точки
        right_mask = right[:, 1] >= self.z
        left_mask = left[:, 1] >= self.z

        # в случае если все точки окажутся выше пробуем более строгое условие,
        # т.к. некоторые точки могут оказаться на горизонтальной
        # линии проходящей через данную точку
        if np.sum(right_mask == True) == len(right):
            right_mask = right[:, 1] > self.z

        if np.sum(left_mask == True) == len(left):
            left_mask = left[:, 1] > self.z

        # по маскам создаем массивы точек лежащих в четвертях
        nearby_points = [right[right_mask],
                         right[~right_mask],
                         left[left_mask],
                         left[~left_mask]]

        nearby = []
        nearby_dist = []

        # для каждой четверти выбираем точку с наименьшим расстоянием
        for pts in nearby_points:
            if len(pts):
                dist = distance_euc(self.xz, pts[:, :-1])
                min_idx = dist.argmin()
                nearby.append(pts[min_idx])
                nearby_dist.append(dist[min_idx])
        return np.array(nearby), nearby_dist

    def point4vectors2d(self, points: np.ndarray) -> np.ndarray:
        """
        Определяет положение точки относительно векторов образованных из
        массива точек на плоскости. с помощью векторного произведения векторов.
        0 - принадлежит вектору,
        1 - лежит правее,
        -1 - лежит левее.

        :param points: массив точек
        :return: результат векторных произведений.
        """

        start_point = points[0, :-1]  # точка начала векторов
        end_points = points[1:, :-1]  # точки конца векторов

        vec_1 = self.xz - start_point  # вектор до данной точки
        vec_2 = end_points - start_point  # векторы до остальных точек

        # массив знаков векторных произведений
        return np.sign(np.cross(vec_2, vec_1))

    def __repr__(self):
        x, z, u_z = self._coords
        return f"x: {x}, z: {z} u_z: {u_z}"

def write_log(method):
    """
    Декоратор для записи лога операции над точками
    :param method: метод возвращающий команду и массив точек
    :return: возвращающая команду и массив точек
    """
    def wrapper(self, *args, **kwargs):
        command, points = method(self, *args, **kwargs)
        self.logs.append([command, points])
        return command, points
    return wrapper

class GridPoint(Point):
    """
    Класс узла сетки.
    """
    def __init__(self, pt):
        super().__init__(pt)
        self.logs = []

    @write_log
    def point4point2d(self,
                      points: np.ndarray,
                      dist: np.ndarray,
                      eps_match=0
                      ) -> Tuple[str, np.ndarray]:
        """
        Определяет взаимное положение точки относительно точки на плоскости.
        Возвращает кортеж из: командa ('point' - совпадают,
        'no_point' - не совпадают), ближайшая точка [x1, y1, z1].

        :param points: массив точек ([[x1, y1, z1], [x2, y2, z2], ...])
        :param dist: массив расстояний ([dist1, dist2, ....])
        :param eps_match: окрестность в которой точки можно считать совпадающим
        :return: (команда: 'point'/'no_point', ближайщая точка: [[x1, y1, z1]])
        """
        idx = np.argmin(dist)
        command = 'point' if dist[idx] <= eps_match else 'no_point'
        return command, points[idx].reshape(1, 3)

    @write_log
    def point4lines2d(self, points: np.ndarray) -> Tuple[str, np.ndarray]:
        """
        Определяет взаимное положение точки относительно прямой, заданной двумя
        точками на плоскости.
        Возвращает кортеж из: командa ('line' - принадлежит,
        'outside' - не принадлежит), points.
        :param points: массив из двух точек ([[x1, y1, z1], [x2, y2, z2]])
        :return: (команда: 'line'/'outside', [[x1, y1, z1], [x2, y2, z2]])
        """
        sign = self.point4vectors2d(points)

        if sign == 0:
            return 'line', points
        else:
            return 'outside', points

    @write_log
    def point4triangle2d(self, points: np.ndarray) -> Tuple[str, np.ndarray]:
        """
        Определяет положение точки относительно треугольника образованного
        тремя точками. Из 1ой точки проводим вектора V1,V2 до остальных двух и
        V3 до данной точки.
        Берем знаки векторных произведений (V1, V3), (V2, V3). Если знаки
        различны - данная точка лежит между этими векторами(внутри) и повторяем
        данные операции для следующей точки. Если знаки также различны - точка
        точка лежит внутри треугольника.
        Если знаки одинаковы - вне данных векторов и следовательно вне
        треугольника.
        Если произведение равно 0, то точка принадлежит данному вектору,
        следовательно можно применить методы и функции для точки и линии.

        Возвращает кортеж из: командa ('line' - принадлежит линии,
        'inside' - принадлежит области, 'outside' - не принадлежит области),
        points.

        :param points: массив из двух точек ([[x1, y1, z1], [x2, y2, z2], ,
        [x3, y3, z3]])
        :return: ('line', [[x, y, z], [x*, y*, z*]]) \\ ('outside'/'inside',
        [[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]])
        """
        # создаем 2 набора точек.
        # Для второго набора делаем смещение элементов вправо на 1 шаг.
        sets_points = np.array([points, np.roll(points, 1, axis=0)])
        for set_ in sets_points:
            sign = self.point4vectors2d(set_)  # знаки векторного произведения

            if np.any(sign == 0):
                # возвращаем пару точек при которых векторное произведение
                # равно 0
                end_point = set_[1:][sign == 0].reshape(-1)
                return 'line', np.array([set_[0], end_point])

            elif np.all(sign == sign[0]):
                return 'outside', np.array(points)

        return 'inside', np.array(points)

class RectangleGrid(object):
    """
    Класс создает массив точек(узлов) прямоугольной сетки.
    """

    def __init__(self,
                 length: Union[int, float],
                 depth: Union[int, float],
                 step_z: Dict[int, Union[int, float]]):
        self.length = length
        self.depth = depth
        self._step_x = self.set_step_x()
        self._step_z = self.set_step_z(step_z)
        self._grid_x = None
        self._grid_z = None
        self.journal_pts = self.create_grid()
        self.main_info = {'Points': len(self.journal_pts),
                          'Success': 0,
                          'Errors': 0
                          }

    def set_step_z(self, step: Dict[int, Union[int, float]]) -> float:
        """
        Устанавливает шаг сетки по Z.
        """
        return float(step[self.depth])

    def set_step_x(self) -> float:
        """
        Устанавливает шаг сетки по X.
        """
        return 1. if self.length < 60 else 5.

    @property
    def grid_x(self) -> np.ndarray:
        return self._grid_x

    @grid_x.setter
    def grid_x(self, array: np.ndarray) -> NoReturn:
        self._grid_x = array

    @property
    def grid_z(self) -> np.ndarray:
        return self._grid_z

    @grid_z.setter
    def grid_z(self, array: np.ndarray) -> NoReturn:
        self._grid_z = array

    @property
    def step_x(self) -> float:
        return self._step_x

    @property
    def step_z(self) -> float:
        return self._step_z

    def create_grid(self) -> Dict[Tuple[int, int], GridPoint]:
        """
        Создает узлы сетки как класс GridPoint для каждого узла,
        на длине и глубине равной self.length, self.depth и шагом
        self._step_x, self._step_z. Узел имеет координаты [x, z, 0.].
        Связывает эти узлы с координатами ячейки на листе в excel.
        :return: Возвращает словарь, где ключ - координатами ячейки на
        листе в excel; значение - объект GridPoint([x, z, 0.])
        """

        length = self.length
        depth = self.depth
        step_x = self._step_x
        step_z = self._step_z

        self._grid_x = np.arange(-length / 2, length / 2 + 1, step_x)
        grid_z = np.arange(0, depth + step_z, step_z)
        grid_z[-1] = self.depth
        self._grid_z = grid_z

        journal_pts = {(row, col): GridPoint([x, z, 0.])
                       for col, x in enumerate(self._grid_x, 2)
                       for row, z in enumerate(self._grid_z, 2)}
        return journal_pts

class SheetInfo:
    """
    Класс для создания журнала операций на листе excel.
    Производит оформление листа.
    Производит запись операции по узлу GridPoint(Point).
    Вид операции для записи имеет вид:
    GridPoint[x, z, u_y] [('команда', массив_точек), ........ ]
    Использует стили оформления таблицы из класса SheetInfoStyles.
    """

    TITLE_HEADER = {'grid_X': 1,
                    'grid_Z': 2,
                    'grid_u_Y': 3,
                    'command': 4,
                    'X': 5,
                    'Z': 6,
                    'u_Y': 7
                    }

    def __init__(self, sheet, main_info: dict) -> None:
        """
        Инициализация атрибутов экземпляра класса. Создает строки с основной
        информацией содержащейся в переданном словаре main_info.
        Создает атрибут с экземпляром класса SheetInfoStyles являющийся набором
        шаблонов стилей оформления ячеек.

        :param sheet: лист в excel файле
        :param main_info: {'Points': 12345,'Success': 12340, 'Errors': 5}
        """

        self.sheet = sheet
        self.row = 1  # используем как указатель для строки
        self.col = 1
        self.styles = utils.SheetInfoStyles()  # стили оформления
        self.__main_info(main_info)
        self.__header()

    def __main_info(self, main_info: dict) -> NoReturn:
        """
        Создает строки с основной информацией по узлам сетки.
        :param main_info: {'Points': 12345,'Success': 12340, 'Errors': 5}
        :return: NoReturn
        """
        field_col = self.col  # номер столбца полей
        value_col = self.col + 1  # номер столбца для значений полей

        for row, (field, value) in enumerate(main_info.items(), self.row):
            # устанавливаем высоту строк
            self.sheet.row_dimensions[row].height = 20

            # Записываем название поля и оформляем ячейку
            cell = self.sheet.cell(row=row, column=field_col, value=field)
            cell.style = self.styles.main_cell
            cell.number_format = '@'

            # Записываем значение поля и оформляем ячейку
            cell = self.sheet.cell(row=row, column=value_col, value=value)
            cell.style = self.styles.main_cell
            cell.number_format = '0'

            self.row += 1  # перемещаем на следующую строку
        self.row += 2  # пустые строки до таблицы

    def __header(self) -> NoReturn:
        """
        Оформление шапки таблицы операций. Записываем названия столбцов из
        атрибута класса TITLE_HEADER.
        :return: NoReturn
        """
        # устанавливаем высоту строки шапки
        self.sheet.row_dimensions[self.row].height = 25

        # заполняем шапку таблицы
        for field, col in self.TITLE_HEADER.items():
            cell = self.sheet.cell(row=self.row, column=col, value=field)
            cell.style = self.styles.header
            cell.number_format = '@'

            # устанавливаем ширину столбца
            col_letter = cell.column_letter  # получаем букву столбца
            self.sheet.column_dimensions[col_letter].width = 13
        self.row += 1  # перемещаем указатель на новую строку

    def write_journal(self, point: GridPoint) -> NoReturn:
        """
        Запись журнала операций для узла GridPoint.
        Вид операции для записи имеет вид:
        GridPoint[x, z, u_y] [('команда', [массив_точек]), ........ ]
        Использует стили оформления таблицы из класса SheetInfoStyles.
        :param point: экземпляр класса GridPoint
        :return: NoReturn
        """

        # устанавливаем высоту первой стоки строки
        self.sheet.row_dimensions[self.row].height = 20
        column = self.col  # локальный счетчик для столбцов

        """
        используем 2 стиля оформления для визуальной индикации успеха/не_успеха
        найденного перемещения в узле:
              self.styles.success - если значение перемещения не равно None;
              self.styles.errors - если значение перемещения равно None;
        """
        style = self.styles.errors if point.u_y is None else self.styles.success

        # записываем координаты узла
        for col, value in enumerate(point.coords, column):
            cell = self.sheet.cell(row=self.row, column=col, value=value)
            cell.style = style
            cell.font = self.styles.grid_pt_font

            # это условие требуется тк. для координаты u_y требуется повышенное
            # отображение десятичных знаков
            if col == 3:
                cell.number_format = '0.000000'
            else:
                cell.number_format = '0.00'
            column += 1

        # записываем произведенные операции над ближайшими точками узла
        for logs in point.logs:
            # лог имеет вид ('команда', [массив_точек])
            command, points = logs

            # записываем команду
            cell = self.sheet.cell(row=self.row, column=column, value=command)
            cell.style = style

            # в цикле записываем все точки над которыми производилась операция
            for point in points:
                # покоординатно записываем все координаты точки в свой столбец
                for col, value in enumerate(point, column + 1):

                    cell = self.sheet.cell(row=self.row,
                                           column=col,
                                           value=value)
                    cell.style = style
                    cell.number_format = '0.000000'
                self.row += 1  # перемещаем указатель на новую строку
            # перемещаем указатель на новую строку
            # (для визуального разделения операций и узлов)
            self.row += 1


import gevent
from urllib.request import urlopen
from decimal import Decimal, getcontext
from collections import Counter
from time import time
# If we were to speed up the download as much as possible I will probably not
# delay the requests - that would be the best optimization :)

# assuming we want the size of the response and not the size of
# the output saved on disk which might be different
class Exercise(object):

    calls = []

    def download_from_url(self):
        gevent.sleep(0)
        from hashlib import sha256
        url = "http://slowwly.robertomurray.co.uk/delay/3000/url/https://www.python.org/"
        response = urlopen(url)
        return (sha256(response.read()).hexdigest(),
                response.info()['Content-Length'])

    def call_download(self):
        beg = time()
        self.calls = [self.download_from_url() for i in range(0, 10)]
        gevent.sleep(0)
        ms = time() - beg
        assert len(self.calls) == 10
        count = Counter([hash for (hash,y) in self.calls])

        if list(count.values())[0] is not 10:
            print("Something is wrong, all data should be the same")
        else:
            print("All data downloaded is the same and the lenght is:",
                  " {}.It took {}s to complete".format(self.calls[0][1], ms))

    def pi(self):
        # code taken from https://docs.python.org/3/library/decimal.html#recipes
        """Compute Pi to the current precision.

        >>> print(pi())
        3.141592653589793238462643383

        """
        getcontext().prec += 1000000  # extra digits for intermediate steps
        three = Decimal(3)      # substitute "three=3.0" for regular floats
        lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
        while s != lasts:
            lasts = s
            n, na = n+na, na+8
            d, da = d+da, da+32
            t = (t * n) / d
            s += t
            if len(self.calls) is 10:
                break
            gevent.sleep(0)
        getcontext().prec -= 2

        # since it will be difficult to view I also added it on a text file
        with open('result_of_pi.txt', 'w') as f:
            f.write('{}'.format(+s))
        f.close()
        print('Displaying truncated pi to 20 decimal places: {}',
              'Full output can be seen on result_of_pi.txt'.format(
               round(+s, 20)))

if __name__ == '__main__':
    ex = Exercise()

    first = gevent.spawn(ex.pi)
    second = gevent.spawn(ex.call_download)
    gevent.joinall([
        second,
        first,
    ])


"""
file name: naive_trading.py
author: Sheng Yang
Date Created: 2021/04/12

set up a naive high-freqency trading strategy.
Rules:
long when a signal 2 is given, short when 0 is given, and clear when 1 is given.
Once an action is dealt, ignore signal for lag many mintues

TODO: what should be the benchmark?
"""

import json
from preprocess import *
from train_test import *

# load parameters
with open('parameters/parameters.json', 'r') as f:
    param_dict = json.load(f)
    window, lag, th, train_days, test_days = param_dict.values()

def label_data_and_transform(data, window=window, lag=lag, th=th, split_at=train_days * 241):
    """
    split the partitioned dataset further into training the testing periods,
    assign labels to the window, lag, and threshold

    :param split_at: the index position of the start of the testing period
    """
    # split train and test temporally
    train_dataset, test_dataset = np.split(data, [split_at])
    # standardize separately
    scaler = StandardScaler().fit(train_dataset)
    train_standardized = scaler.transform(train_dataset)
    test_standardized = scaler.transform(test_dataset)
    # merge together
    standardized_data = np.append(train_standardized, test_standardized, axis=0)

    # give labels to training
    num_data = standardized_data.shape[0]
    X_train, X_test, Y_train = [], [], []
    for t in range(window, split_at):
        X_train.append(dwt(standardized_data[t - window:t]))
        # assign labels by close price movements
        curr_close = standardized_data[t, 0]
        price_movement = (
            standardized_data[t: t + lag, 0].mean() - curr_close
        ) / curr_close
        if price_movement > th:
            Y_train.append(2)
        elif price_movement < -th:
            Y_train.append(0)
        else:
            Y_train.append(1)

    # obtain testing features
    # add Y_test to plot confusion matrix
    Y_test = []
    for t in range(split_at, num_data):
        X_test.append(dwt(standardized_data[t - window:t]))

        # adding Y_test for making confusion matrix plot
        # note that the last lag number of labels are incorrect
        curr_close = standardized_data[t, 0]
        price_movement = (
            standardized_data[t: t + lag, 0].mean() - curr_close
        ) / curr_close
        if price_movement > th:
            Y_test.append(2)
        elif price_movement < -th:
            Y_test.append(0)
        else:
            Y_test.append(1)

    # assign indices (TO BE REMOVED LATER ON)
    test_idx = test_dataset.index
    Y_train = np.array(Y_train, dtype=int)
    Y_test = np.array(Y_test, dtype=int)
    X_test = pd.DataFrame(X_test, index=test_idx)
    return X_train, Y_train, X_test, Y_test

def train_assign_direction_by_period(X_train, Y_train, X_test):
    """
    in each training/testing period, use XGBoost trained with X_train and Y_train to give
    directions on X_test.

    :param X_train: the flattened wavelet features at each timestamp
    :param Y_train: the training labels (0, 1, and 2) for the training period
    :param X_test: the flattened wavelet features at each timestamp for testing
    """
    # pca
    pca_transformer = PCA(n_components=20).fit(X_train)
    X_train = pca_transformer.transform(X_train)
    test_idx = X_test.index
    X_test = pca_transformer.transform(X_test)

    # train model
    xgb_clf = XGBClassifier(
        objective='multi:softmax',
        use_label_encoder=False,
        random_state=0
    ).fit(X_train, Y_train, eval_metric='merror')

    # prediction
    Y_test_prediction = xgb_clf.predict(X_test)
    return pd.Series(Y_test_prediction, index=test_idx)

def pipeline_each_period(data_chunk):
    """
    pipelining the process for each period to facilitate multiprocessing
    """
    # standardize and transform
    # print('Start Training')
    X_train, Y_train, X_test, _ = label_data_and_transform(data_chunk)
    # give directions
    direction_curr_period = train_assign_direction_by_period(
        X_train, Y_train, X_test)
    # print('Finish Training')
    return direction_curr_period

def train_assign_direction(raw_data,
                           train_days=train_days, test_days=test_days
                          ):
    """
    Given the raw data, on a rolling basis, train on train_days many days
    and trade for the next test_day many days. The trading signals are given
    by XGBoost trained on the train_days many days of data.

    :param raw_data: the data of the original csv
    :return the decision after each minute
    """
    data_to_use = raw_data[['c', 'h', 'l', 'v']]
    train_period, test_period = train_days * 241, test_days * 241
    num_chunk = (data_to_use.shape[0] - train_period) // test_period

    # obtain directions
    data_chunks = []
    for i in range(num_chunk + 1):
        # obtain train and test dataset
        train_start_idx = i * test_period
        train_end_idx = train_start_idx + train_period  # also the test start idx
        test_end_idx = train_end_idx + test_period
        data_chunk = data_to_use.loc[train_start_idx:test_end_idx - 1]
        data_chunks.append(data_chunk)

    # multiprocessing to process each chunk
    with mp.Pool() as pool:
        directions = pool.map(pipeline_each_period, data_chunks)

    direction = pd.concat(directions)
    return direction

def trade(raw_data, direction):
    """
    given the raw_data and computed direction predicted by XGBoost,
    how does the strategy perform in reality?

    :param raw_data: the raw_data read from the preprocess folder
    :param direction: the direction (0, 1, or 2) computed by XGBoost
    :return a series of net values guided by the XGBoost predictions
    """
    trade_data = raw_data.loc[direction.index]

    min_ret = trade_data.c.pct_change()
    guided_min_ret = min_ret * (direction - 1).shift(1)

    cum_ret = (min_ret + 1).cumprod()
    guided_cum_ret = (guided_min_ret + 1).cumprod()

    # make a plot
    plt.plot(cum_ret)
    plt.plot(guided_cum_ret)
    plt.legend(['asset return', 'wavelet guided return'])
    plt.title(f'Wavelet returns vs asset return: {train_days}, {test_days}')
    plt.savefig(f'report/naive_trading_{train_days}_{test_days}.png')
    return cum_ret, guided_cum_ret

if __name__ == '__main__':
    raw_data = load_data()  # from preprocess
    direction = train_assign_direction(raw_data)  # obtain directions
    cum_ret, guided_cum_ret = trade(raw_data, direction)  # trade


class TuringMachine(object):
	def __init__(self):
		self.fita = None
		self.instrucoes = None
		self.leitura_cabeca = None
		self.estado_atual = ''
		self.posicao_cabeca = 0

	def entrada_info(self, fita, instrucoes, instrucao_inicial):
		self.limpar_maquina()
		self.instrucoes = instrucoes
		self.fita = fita
		self.estado_atual = instrucao_inicial
		self.leitura_cabeca = self.fita[0]

	def start(self):
		self.leitura_cabeca = self.fita[0]
		while self.estado_atual.upper() != 'END':
			self.operacao()
		while self.fita[0] == ' ':
			self.fita.pop(0)
		return ''.join(self.fita)

	def operacao(self):
		if self.estado_atual.upper() == 'END':
			return self.fita, self.posicao_cabeca, self.estado_atual
		chave = (self.estado_atual, self.leitura_cabeca)
		if chave in self.instrucoes:
			instrucao = self.instrucoes[chave]
			self.estado_atual = instrucao[0]
			self.fita[self.posicao_cabeca] = instrucao[1]
			if instrucao[2].upper() == 'D':
				self.posicao_cabeca += 1
			elif instrucao[2].upper() == 'E' and self.posicao_cabeca > 0:
				self.posicao_cabeca -= 1
			else:
				raise Exception('Direção indicada na instrução {0},{1} não foi reconhecida'.format(chave[0], chave[1]))
			if self.posicao_cabeca == len(self.fita):
				self.fita.append(' ')
			elif self.posicao_cabeca == 0:
				self.fita.insert(0, ' ')
				self.posicao_cabeca += 1
			self.leitura_cabeca = self.fita[self.posicao_cabeca]
		else:
			raise Exception('A operação {0} não foi encontrada na lista de instruções'.format(chave))
		return self.fita, self.posicao_cabeca, self.estado_atual

	def limpar_maquina(self):
		self.fita = None
		self.instrucoes = None
		self.estado_atual = ''
		self.posicao_cabeca = 0
		self.leitura_cabeca = 0