#!/usr/bin/env python

import logging
import os
import pygit2
import sys

AUDIT_OK = 0
AUDIT_FAILED = 1
ERROR = 2

issues = {}

def record_issue(issue, more_data):
    if issue in issues:
        if more_data not in issues[issue]:
            issues[issue].append(more_data)
    else:
        issues[issue] = [more_data]

def check_can_merge_to_this_branch(email):
    pass

def track_back_to_parents(this_commit, excluded_author,
                          all_baselines, depth=1):
    logging.debug("Checking feature branch %s by %s" % (
        this_commit.id,
        this_commit.author.email))
    if depth > 20:
        logging.info("Max depth exceeded while looking for the parents of %r" %
                     this_commit)
        sys.exit(ERROR)
    logging.debug("Looking for parents of %r" % this_commit.message)
    if this_commit.id in all_baselines:
        logging.debug("Tracked back to base; nothing futher to do")
        return None
    if this_commit.author.email == excluded_author:
        logging.info(("This feature branch contains commit %s, authored by " +
                      " %s, who performed the merge.") %
                     (this_commit.id, this_commit.author.email))
        record_issue("Feature branch merged by one of its contributors",
                     this_commit.id)
        return None
    for p in this_commit.parents:
        return track_back_to_parents(p, excluded_author, all_baselines,
                                     depth + 1)

def print_commit(commit):
    return "%s %s" % (commit.id, commit.message)

def find_baselines(commit):
    """ Finds all the previous revisions of the branch this
    commit is now the head of. """
    baselines = []
    while True:
        if len(commit.parents) > 1:
            baselines.append(commit.id)
            commit = commit.parents[0]
        elif len(commit.parents) == 0:
            logging.debug("Reached the end of the branch")
            return baselines
        else:
            record_issue("Non-merge commit on trunk", commit.id)
            baselines.append(commit.id)
            commit = commit.parents[0]

def check_merges_by_branch_authors(repo):
    head = repo.head

    # Is it a merge commit? Can we get the parents?
    commit = head.peel(pygit2.Commit)

    all_baselines = find_baselines(commit)

    while True:
        merge_author = commit.author.email
        parents = commit.parents

        if len(parents) == 0:
            # We've reached the end of the repository
            break

        if len(parents) < 2:
            record_issue("Non-merge commit on trunk", commit.id)
            commit = parents[0]
            continue

        check_can_merge_to_this_branch(merge_author)

        # ASSUME (!) the first parent was the previous
        # position of the branch...
        feature_branches = parents[1:]
        logging.debug("Base of this merge is %s" % (parents[0].id))
        for p in feature_branches:
            ident = track_back_to_parents(p, merge_author, all_baselines)
        commit = parents[0]

def get_mergers_for_commit(repo, commit_id):
    """ This reads the ROLES file at the time of a given commit and returns a
        list of the people allowed to merge each branch. The return value is a
        dictionary whose keys are branch names and values are lists of email
        addresses. """
    commit = repo[commit_id]
    try:
        permissions_file_id = commit.tree['ROLES'].id
    except KeyError:
        record_issue("Repository has no ROLES file", None)
        return {}
    permissions_file = repo[permissions_file_id]
    perms = permissions_file.data.split("\n")
    mergers = {}
    for l in perms:
        if l == "":
            continue
        fields = l.strip().split(":")
        branch = fields[0]
        users = fields[1].split(",")
        if users is not None:
            mergers[branch] = users
        logging.info("Users %s are allowed to merge to %s" % (users, branch))
    return mergers

def check_merge_permissions(repo):
    """ Checks the ROLES file for each baseline - at the time of the previous
        baseline - allows that merge. """

    head_commit = repo.head.peel(pygit2.Commit)
    all_baselines = find_baselines(head_commit)
    checked_branch = "master"

    # This requires that baselines are in order (most recent to oldest)
    for baseline_no in range(0, len(all_baselines)-1):
        b = all_baselines[baseline_no]
        rules_baseline = all_baselines[baseline_no+1]
        mergers = get_mergers_for_commit(repo, rules_baseline)
        if checked_branch not in mergers:
            # If there are no rules for a branch, that's considered
            # OK, so there's nothing to check at this point (although
            # this might warrant a low-level warning)
            continue
        commit = repo.get(b)
        mergers_for_branch = mergers[checked_branch]
        if commit.author.email not in mergers_for_branch:
            record_issue("Unauthorised user committed to branch",
                         "%s committed to %s at %s" %
                         (commit.author.email, checked_branch, b))
        else:
            logging.info("Commit by %s to %s" %
                         (checked_branch, commit.author.email))

def plural(n):
    return 's' if len(n) != 1 else ''

def main():
    if len(sys.argv) < 2:
        print("Usage: check.py <git directory>")
        sys.exit(ERROR)
    gitdir = sys.argv[1]
    if not os.path.isdir(gitdir):
        logging.error("%s is not a directory" % gitdir)
        sys.exit(ERROR)

    try:
        repo = pygit2.Repository(gitdir)
    except Exception as e:
        logging.error("Failed to open git repository %s: %r" % (gitdir, e))
        sys.exit(ERROR)

    check_merges_by_branch_authors(repo)
    check_merge_permissions(repo)

    print("Analysis complete.")
    if len(issues.items()) == 0:
        print ("No issues found in repository.")
        sys.exit(AUDIT_OK)
    else:
        print ("Issues found in git repository: ")
        for (k, v) in issues.items():
            if len(v) <= 5:
                print("  %s (%d count%s)" % (k, len(v), plural(v)))
                for note in v:
                    if note is not None:
                        print("    %s" % note)
            else:
                print("  %s (%d counts, not listed)" % (k, len(v)))
        sys.exit(AUDIT_FAILED)

if __name__ == "__main__":
    main()


import pandas as pd
import numpy as np
import sys,os

def aggregation(train_df, test_df, target, features_list, agg_list=['mean', 'std', 'median']) -> pd.DataFrame:
    """集計特徴量を生成する関数
    :train_df:tranデータ
    :test_df:testデータ
    :target:集計元の特徴量
    :features_list:集計対象の特徴量のリスト
    :agg_list:計算する統計量のリスト
    """
    tmp_df = pd.concat([train_df, test_df], axis=0, sort=False).reset_index(drop=True)
    tmp_df = tmp_df.groupby(target)[features_list].agg(agg_list).reset_index()
    return tmp_df

def binning(train_df, test_df, target, bin_edges) -> pd.Series:
    """連続変数などをbin分割する関数
    デフォルトでは左側（小さい方）のエッジの値は含まれない。
    :train_df:tranデータ
    :test_df:testデータ
    :target:bin分割対象の特徴量
    :bin_edges:ビン分割の範囲のリスト
    """
    train_binned = pd.cut(train_df[target], bin_edges, labels=False)
    test_binned = pd.cut(test_df[target], bin_edges, labels=False)
    return train_binned, test_binned

def division(df, targets_list) -> pd.DataFrame:
    """リストの特徴量を除算する関数
    :df:dfデータ
    :targets_list:除算対象の特徴量2次元リスト[[a, b], [b, c]]と指定した場合はa/bとb/cが計算される
    """
    df_division = pd.DataFrame()
    for i in range(len(targets_list)):
        column_name = ''
        value = 0
        feature1 = targets_list[i][0]
        feature2 = targets_list[i][1]
        value = round(df[feature1] / df[feature2], 3)
        value = value.replace([np.inf, -np.inf], np.nan)
        value = value.fillna(0)

        column_name = targets_list[i][0] + '_div_' + targets_list[i][1]
        df_division[column_name] = value

    return df_division


from adapt.intent import IntentBuilder
from mycroft import MycroftSkill, intent_handler, intent_file_handler
from os.path import join, dirname

class ConfuciusQuotesSkill(MycroftSkill):

    def show_confucius(self, caption):
        self.gui.clear()
        self.gui.show_image(join(dirname(__file__), "ui", "confucius.jpg"),
                            caption=caption, fill='PreserveAspectFit')

    @intent_handler(IntentBuilder("ConfuciusQuote")
                    .require('confucius').require('quote'))
    def handle_quote(self, message):
        utterance = self.dialog_renderer.render("quote", {})
        self.show_confucius(utterance)
        self.speak(utterance, wait=True)
        self.gui.clear()

    @intent_handler(IntentBuilder("ConfuciusLive")
                    .require('confucius').require('when').require('live'))
    def handle_live(self, message):
        utterance = self.dialog_renderer.render("live", {})
        self.show_confucius(utterance)
        self.speak(utterance, wait=True)
        self.gui.clear()

    @intent_handler(IntentBuilder("ConfuciusBirth")
                    .require('confucius').require('birth'))
    def handle_birth(self, message):
        utterance = self.dialog_renderer.render("birth", {})
        self.show_confucius(utterance)
        self.speak(utterance, wait=True)
        self.gui.clear()

    @intent_handler(IntentBuilder("ConfuciusDeath")
                    .require('confucius').require('death'))
    def handle_death(self, message):
        utterance = self.dialog_renderer.render("death", {})
        self.show_confucius(utterance)
        self.speak(utterance, wait=True)
        self.gui.clear()

    @intent_file_handler("who.intent")
    def handle_who(self, message):
        utterance = self.dialog_renderer.render("confucius", {})
        self.show_confucius(utterance)
        self.speak(utterance, wait=True)
        self.gui.clear()

def create_skill():
    return ConfuciusQuotesSkill()


import datetime
import fcntl
import time
import logging
import os
import shutil
import tempfile
from collections import OrderedDict

import numpy as np
import torch
import torch.nn as nn

def set_hyperparameter(config):
    """Load/set hyperparameter settings based on predefined config"""

    if config.hp_setting == "in_metanas":  # setting for MetaNAS
        config.task_train_steps = 5
        config.n_train = 15
        config.batch_size = 20
        config.batch_size_test = 5 if config.n == 1 else 15  # reptile paper A1
        config.meta_batch_size = 10
        config.w_lr = 0.001
        config.alpha_lr = 0.001
        config.w_meta_lr = 1.0
        config.a_meta_lr = 0.6
        config.a_meta_anneal = 0
        config.a_task_anneal = 0
        config.w_meta_anneal = 0
        config.w_task_anneal = 0

    elif config.hp_setting == "og_metanas":  # setting for MetaNAS
        config.task_train_steps = 5
        config.n_train = 15
        config.batch_size = 20
        config.batch_size_test = 10
        config.meta_batch_size = 10
        config.w_lr = 0.005
        config.alpha_lr = 0.005
        config.w_meta_lr = 1.0
        config.a_meta_lr = 0.6
        config.a_meta_anneal = 0
        config.a_task_anneal = 0
        config.w_meta_anneal = 0
        config.w_task_anneal = 0

    elif config.hp_setting == "og":  # default setting from REPTILE paper
        print("Using 'og' hp setting")
        config.task_train_steps = 10
        config.n_train = 10
        config.batch_size = 20
        config.batch_size_test = 10
        config.meta_batch_size = 5
        config.w_lr = 0.0005
        config.alpha_lr = 0.0
        config.w_meta_lr = 1.0
        config.a_meta_lr = 0.0
        config.a_meta_anneal = 0
        config.a_task_anneal = 0
        config.w_meta_anneal = 1
        config.w_task_anneal = 0

    elif config.hp_setting == "in":  # default setting from REPTILE paper
        print("Using 'in' hp setting")
        config.task_train_steps = 8
        config.n_train = 15
        config.batch_size = 10
        config.batch_size_test = 5 if config.n == 1 else 15  # reptile paper A1
        config.meta_batch_size = 5
        config.w_lr = 0.001
        config.alpha_lr = 0.0
        config.w_meta_lr = 1.0
        config.a_meta_lr = 0.0
        config.a_meta_anneal = 0
        config.a_task_anneal = 0
        config.w_meta_anneal = 1
        config.w_task_anneal = 0

    else:
        raise RuntimeError(f"Unrecognized hp_setting {config.hp_setting}")

    # compatibility with older versions
    if not hasattr(config, "batch_size_test"):
        config.batch_size_test = config.batch_size
    return config

def get_logger(file_path):
    """ Make python logger """
    logger = logging.getLogger("darts")
    log_format = "%(asctime)s | %(message)s"
    formatter = logging.Formatter(log_format, datefmt="%m/%d %I:%M:%S %p")
    file_handler = logging.FileHandler(file_path)
    file_handler.setFormatter(formatter)
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(formatter)

    logger.addHandler(file_handler)
    logger.addHandler(stream_handler)
    logger.setLevel(logging.INFO)

    return logger

def get_experiment_path(config):
    # Write experiment output (logging, parameters, tensorboardX, ..) to
    # experiments/<EXPERIMENT_GROUP>/<DATE>_<NAME>_<UNIQUE_ID>/
    current_date = datetime.datetime.today().strftime(f"%m-%d")
    current_time = datetime.datetime.now().time()
    experiment_group_dir = os.path.join("experiments", config.experiment_group)
    os.makedirs(experiment_group_dir, exist_ok=True)
    experiment_name = f"{current_date}_{config.name}_"

    if config.job_id:
        experiment_name = f"{experiment_name}{config.job_id}"
        experiment_path = os.path.join(experiment_group_dir, experiment_name)
        if not os.path.exists(experiment_path):
            os.makedirs(experiment_path)
        else:
            print("----------------------------------")
            print("Warning: Dir already exists. Will overwrite.")
            print("----------------------------------")
    else:
        experiment_path = tempfile.mkdtemp(
            prefix=experiment_name, dir=experiment_group_dir
        )
    return experiment_path

def parse_gpus(gpus):
    if gpus == "all":
        return list(range(torch.cuda.device_count()))
    else:
        return [int(s) for s in gpus.split(",")]

def print_config_params(config, prtf=print):
    prtf("")
    prtf("Parameters:")
    for attr, value in sorted(vars(config).items()):
        prtf(f"{attr.upper()}={value}")
    prtf("")

def param_size(model):
    """ Compute parameter size in MB """
    n_params = sum(
        np.prod(v.size())
        for k, v in model.named_parameters()
        if not k.startswith("aux_head")
    )
    return n_params / 1024.0 / 1024.0

class AverageMeter:
    """ Computes and stores the average and current value """

    def __init__(self):
        self.val, self.avg, self.sum, self.count = (0.0, 0.0, 0.0, 0.0)
        self.reset()

    def reset(self):
        """ Reset all statistics """
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def update(self, val, n=1):
        """ Update statistics """
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count

class EMAMeter:
    """Computes and stores an exponential moving average

    Attributes:
        avg: The current EMA
        alpha: The degree of weight decrease (a higher alpha discounts older observations faster)
    """

    def __init__(self, alpha=0.01):
        self.alpha = alpha
        self.avg = 0.0

    def update(self, val, _):
        self.avg = self.alpha * val + (1 - self.alpha) * self.avg

    def reset(self):
        self.avg = 0.0

def accuracy(output, target, topk=(1,)):
    """ Computes the precision@k for the specified values of k """
    maxk = max(topk)
    batch_size = target.size(0)

    _, pred = output.topk(maxk, 1, True, True)
    pred = pred.t()
    # one-hot case
    if target.ndimension() > 1:
        target = target.max(1)[1]

    correct = pred.eq(target.view(1, -1).expand_as(pred))

    res = []
    for k in topk:
        correct_k = correct[:k].view(-1).float().sum(0)
        res.append(correct_k.mul_(1.0 / batch_size))

    return res

def save_checkpoint(state, ckpt_dir, is_best=False):
    filename = os.path.join(ckpt_dir, "checkpoint.pth.tar")
    torch.save(state, filename)
    if is_best:
        best_filename = os.path.join(ckpt_dir, "best.pth.tar")
        shutil.copyfile(filename, best_filename)

def count_params(net):
    return sum(p.numel() for p in net.parameters())

def save_state(
    meta_model,
    meta_optimizer,
    task_optimizer,
    path: str,
    epoch: int = None,
    job_id: str = None,
):
    """Save the model and optimizer states using pytorch

    Args:
        meta_model:
        meta_optimizer:
        task_optimizer:
        path: The path where the model is stored
        epoch: Epoch that is appended to the file name "meta_state".
        job_id: String that is used to save a temporary file with the
            job_id appended to the state file name. This file is rename
            after saving to the regular name.
    """

    epochpath = os.path.join(path, f"e{epoch}_") if epoch is not None else path

    # save the model (to temporary path if job_id is specified then then rename)
    model_file = epochpath + "meta_state"
    model_file_tmp = model_file if job_id is None else model_file + f"_{job_id}"
    torch.save(
        {
            "meta_model": meta_model.state_dict(),
            "w_meta_optim": meta_optimizer.w_meta_optim.state_dict(),
            "a_meta_optim": meta_optimizer.a_meta_optim.state_dict(),
            "w_task_optim": task_optimizer.w_optim.state_dict(),
            "a_task_optim": task_optimizer.a_optim.state_dict(),
        },
        model_file_tmp,
    )
    if model_file_tmp != model_file:
        os.rename(model_file_tmp, model_file)

def load_state(
    meta_model,
    meta_optimizer,
    task_optimizer,
    path,
    filename="meta_state",
):

    meta_state = torch.load(os.path.join(path, filename))
    meta_model.load_state_dict(meta_state["meta_model"])
    if meta_optimizer is not None:
        meta_optimizer.w_meta_optim.load_state_dict(meta_state["w_meta_optim"])
        meta_optimizer.a_meta_optim.load_state_dict(meta_state["a_meta_optim"])
    if task_optimizer is not None:
        task_optimizer.w_optim.load_state_dict(meta_state["w_task_optim"])
        task_optimizer.a_optim.load_state_dict(meta_state["a_task_optim"])

def load_model_from_state(meta_model, path, strict, filename="meta_state"):
    meta_state = torch.load(os.path.join(path, filename))
    meta_model.load_state_dict(meta_state["meta_model"], strict=strict)

def get_genotype_from_model_ckpt(path, model_instance):
    meta_state = torch.load(path)
    model_instance.load_state_dict(meta_state["meta_model"])
    return model_instance.genotype()


import random, datetime
from datetime import datetime

def bulletin_picker():

    text = bulletins()
    month = datetime.now().month

    if month == 1:
        color = 'red'
    if month == 2:
        color = 'purple'
    if month == 3:
        color = 'aqua'
    if month == 4:
        color = 'yellow'
    if month == 5:
        color = 'green'
    if month == 6:
        color = 'navy'
    if month == 7:
        color = 'red'
    if month == 8:
        color = 'orange'
    if month == 9:
        color = 'blue'
    if month == 10:
        color = 'brown'
    if month == 11:
        color = 'violet'
    if month == 12:
        color = 'garnet'

    return (text, color)

def bulletins():
    bulletin_board = ['Sidewalk Film Festival: Aug. 2-6', 'Concert Tonight: Carrie Underwood', 'Hot Dog Eating Contest: Five Points',
                      'Sloss Furnace Music Festival', ' Pepper Place Market: Every Saturday', 'Play: Wonderland Wives', 'Birmingham Restaurant Week',
                      'Barons Game: Tonight', 'Magic City Brewfest', 'Birimingham Innovation Week', 'Rock and Roll Bingo: Tonight',
                      'The Three Musketeers Live Show: Brookwood Village', 'Free Art Friday: July 13th', 'McWayne Science Center Celebration',
                      'Birmingham TACO FEST: Avondale', 'Cooking Class at Railroad Park: Sunday', 'Sloss Furnace: Metal Casting Class']
    bulletin_board.append(_visitor_bulletin())
    bulletin_choice = random.choice(bulletin_board)
    return bulletin_choice

def _read_arduino_visitors():
    with open('smartpark/arduino/output.txt') as f:
        peeps = f.readline().strip()
        doggos = f.readline().strip()
    # leaving as strings. We aren't crunching this!
    num_peeps = peeps.split(':')[1].strip()
    num_doggos = doggos.split(':')[1].strip()
    return (num_peeps, num_doggos)

def _visitor_bulletin():
    visitors = _read_arduino_visitors()
    peeps = visitors[0]
    doggos = visitors[1]
    # This is a terrible way to write strings #sorrynotsorry
    bulletin = "We've had " + peeps + " visitors and " + doggos + " canine visitors today!"
    return bulletin


def zadanie29(T, r):
    def rek(T, r,index=0, tablica=[]):
        if index==len(T):
            return False
        x=y=z=0
        for element in tablica:
            x+=element[0]
            y+=element[1]
            z+=element[2]
        from math import sqrt
        odleglosc =sqrt(x**2+y**2+z**2)
        if len(tablica)>=3 and odleglosc<=r:
            return True
        return rek(T, r, index+1, tablica.append(T[index])) | rek(T, r, index+1, tablica)


# -*- coding: utf-8 -*-
"""
Created on Wed Apr 22 15:35:47 2020

@author: Thomas
"""

"""
So, what does this do ?

Same file as db_maker.py, except that creating a db is now a function.
Why did I do that ? Laziness.
"""

import model
import numpy as np
import cv2
import json
import pickle
from os import listdir

np_load_old = np.load
np.load = lambda *a,**k: np_load_old(*a, allow_pickle=True)

def processAndSave(fileName, data):
    #with open('image.p', 'rb') as infile:
    #    imageArray = pickle.load(infile)
    imageArray = data
    img = cv2.imread("all/bad/"+fileName)
    imgg = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    imgg = cv2.GaussianBlur(imgg,(5,5),cv2.BORDER_DEFAULT)
    imgg = cv2.threshold(imgg, 252, 255, cv2.THRESH_BINARY_INV)[1]
    imageArray[fileName] = imgg
    return imageArray

def createDb():
    allPics = listdir("all/bad")
    data = {}
    for picture in allPics:
        data = processAndSave(picture, data)
    with open('image.p', 'wb') as outfile:
        pickle.dump(data, outfile, protocol=pickle.HIGHEST_PROTOCOL)


__author__ = 'preeti_sah'
import pickle
import csv
import sys
import getopt

from Tree_Model import Tree

def read_file(argv):
       """
       This will read a file and store the data in the list
       :param argv: file name from command line
       :return: input file
       """
       inputfile = ''
       attribute_name=[]
       if not len(argv) > 1:
            print('No user input')
            sys.exit()
       try:
          opts, args = getopt.getopt(argv,"x:",["ifile="])
       except getopt.GetoptError:
            print('build_tree.py -x <inputfile>')
            sys.exit(2)
       for opt, arg in opts:
          if opt in ("-x", "--ifile"):
             inputfile = arg

       return inputfile

if __name__ == '__main__':
    file = read_file(sys.argv[1:])
    tree=Tree(0.80)
    data,column_name = tree.create_list(file)
    tree.train(data)
    with open('ET-Preeti.pkl','wb') as h:
        pickle.dump(tree,h)


#!/usr/bin/env python3
'''
    Solitaire
'''
from GameView import animation, log, draw, init_view, wait, check_touch
from GameView import touch_deck, touch_waste, touch_button, touch_pile, select_box
import Model as model
import pygame
import sys

#
# Controller
#

def move(dest, source, index):
    'move card(s) from source to destination'
    length = len(dest.cards)
    animation.set(dest=dest, cards=model.get_cards_from(source, index))
    log.append(("move", (dest, source, length)))
    # animation loop
    while animation.in_motion():
        draw()
        wait(animation.speed)
        pygame.event.get()
        # while(not pygame.event.get()): pass   # single step through animation
    # place card(s) in final position then update view
    for card in animation.cards:
        animation.dest.cards.append(card)
    draw()
    print(model.get_state())
    model.countSteps += 1

def check_move_to_pile(atouch):
    'verify if a card is compatible with a pile'
    if not atouch:
        return None
    card = atouch.source.cards[touch.index]
    apile = card.match_pile()
    if apile != None:
        move(dest=apile, source=atouch.source, index=atouch.index)
    return apile

def check_move_to_foundation(atouch):
    'verify if a card is compatible with a foundation'
    if not atouch:
        return None
    if len(atouch.source.cards[touch.index:]) > 1:
        return None
    card = atouch.source.cards[touch.index]
    foundation = card.match_foundation()
    if foundation != None:
        move(dest=foundation, source=atouch.source, index=atouch.index)
    return foundation

def undo():
    'undo last operation logged'
    if log.list:
        action, params = log.pop()
        if action == "move":
            dest, source, index = params
            move(source, dest, index)      # animate the reverse of the last move
            log.pop()                       # avoid logging the undo action
        elif action == "turn":
            card = params.top()
            undo()                          # move / animate
            card.face = 'D'                 # turn back down
        elif action == "recycle":
            model.undo_recycle()
        draw()
        print(model.get_state())

def user_input():
    'returns a touch tuple, intercepts QUIT'
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONUP:
            return check_touch(pygame.mouse.get_pos())
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                sys.exit()
            if event.key == pygame.K_m:
                return touch_waste()
            if event.key == pygame.K_SPACE:
                return touch_deck()
            if event.key == pygame.K_COMMA:
                return touch_button(0)

def start_game():
    'set up the intial game configuration'
    model.init()
    # check if a configuration restore is required for debugging
    if len(sys.argv) > 1:
        model.restore_state(sys.argv[1])
        del(sys.argv[1])
    else:
        model.shuffle()
        model.deal()
    model.countSteps = 0
    log.clear()

#----------------------------------------------------------------------

if __name__ == "__main__":
    init_view()
    auto = False
    victory = False
    start_game()
    draw()
    # print state for debugging purposes
    print(model.get_state())

    # main loop
    while True:

        wait(animation.speed)
        touch = user_input()

        if victory:
            choice = select_box(["victory", "Start a new Game", "Quit"])
            if choice == 0:
                auto = False
                victory = False
                start_game()
                continue
            else:
                sys.exit()

        # auto mode activated
        elif auto:
            # try to use the top card from the waste
            if model.WASTE:
                # print ('check Waste')
                # try to move the card automatically to the first matching foundation
                if check_move_to_foundation(touch_waste()):
                    victory = model.check_finished()

            # try with one of the tips
            for pile in model.PILES:
                if pile:
                    # print ('check Pile', pile)
                    if check_move_to_foundation(touch_pile(pile)):
                        victory = model.check_finished()

        # else respond to user input
        elif touch:
            if touch.source.name == "deck":
                if model.DECK.cards:
                    # get the top card down into the waste
                    move(dest=model.WASTE, source=model.DECK, index=-1)
                else: # if deck is empty
                    model.recycle()
                    draw()
                    print(model.get_state())
                    log.append(("recycle", 0))

            elif touch.source.name == "pile":
                if not check_move_to_foundation(touch):
                    check_move_to_pile(touch)

            elif touch.source.name == "tail":
                check_move_to_pile(touch)

            elif touch.source.name == "foundation":
                check_move_to_pile(touch)

            elif touch.source.name == "waste":
                if not check_move_to_foundation(touch):
                    check_move_to_pile(touch)

            elif touch.source.name == "button":
                if touch.index == 0:  # undo
                    undo()

                elif touch.index == 1:  # restart
                    model.restart()
                    model.count_steps = 0
                    log.clear()

                elif touch.index == 2:  # re-shuffle and deal a new one
                    auto = False
                    victory = False
                    start_game()
                draw()
                # print state for debugging purposes
                print(model.get_state())

            # check if auto can be activated
            if not auto:
                auto = (model.count_hidden() < 1)


# https://www.acmicpc.net/problem/1064

ax, ay, bx, by, cx, cy = map(int, input().split())

# 기울기가 같다면
if ((ay-by)*(ax-cx) == (ay-cy)*(ax-bx)):
    print(-1.0)

# 기울기가 다르다면, 평행사변형의 제일 큰 둘레와 제일 작은 둘레의 차이 구하기
else:
    ab_length = ((ax-bx)**2 + (ay-by)**2)**0.5
    ac_length = ((ax-cx)**2 + (ay-cy)**2)**0.5
    bc_length = ((bx-cx)**2 + (by-cy)**2)**0.5

    length = [ab_length, ac_length, bc_length]
    result = max(length) - min(length)
    print(2*result)


from slack_sdk.webhook import WebhookClient
import os
import requests

# Add in from Telegram
CHATID = "CHANGEME"
BOTKEY = "CHANGEME"

TGURL = f"https://api.telegram.org/bot{BOTKEY}/sendMessage"

# Chance to match slack webhook
slackurl = "https://hooks.slack.com/services/VALUE1/VALUE2"
webhook = WebhookClient(slackurl)
HOSTNM = os.popen('hostname').read()
IP = os.popen('curl -s http://whatismyip.akamai.com/').read()
LOGININFO=os.popen('last -1 -i | head -n 1 | cut -d " " -f 1').read()

tgheaders = {
    'Content-Type': 'application/json',
}

tgdata = '{"chat_id": "{}", "text": "Log in to: {}\\n{}\\nfrom: {}", "disable_notification": false}'.format(CHATID,HOSTNM,IP,LOGININFO)

tgresponse = requests.post(f'https://api.telegram.org/bot{BOTKEY}/sendMessage', headers=tgheaders, data=tgdata)

response = webhook.send(text='Log in to: {}\n from {}\n by\n User: {} \n'.format(HOSTNM,IP,LOGININFO))
assert response.status_code == 200
assert response.body == "ok"


class Employee():

    raise_amount = 1.04

    def __init__(self,first,last,pay):
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + "." + last + "@email.com"

    def fullname(self):
        return "{} {}".format(self.first,self.last)

    def raise_pay(self):
        return self.pay * self.raise_amount

dev1 = Employee("Darshan","Mandlecha",50000)

print(dev1.raise_pay())

class Developer(Employee):
    def __init__(self,first,last,pay,program_language):
        super().__init__(first,last,pay)
        self.program_language = program_language

    raise_amount = 1

dev2 = Developer("Darshan2","M",40000,"Python")

print(dev2.raise_pay())
print(dev2.fullname())


from PyQt6 import Qsci, QtGui

# These values are just used for testing, you can delete them:
VALUE_JSON = """{
    "asdf": "123",
    "array": [
        {
            "hello": "world",
            "age": 123
        }
    ]
}"""

VALUE = """<!DOCTYPE html>
<html lang="en-US">
 <head>
  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-38714717-1">
  </script>
  <script>
   window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-38714717-1');
  </script>
  <!-- Google Optimize -->
  <script src="https://www.googleoptimize.com/optimize.js?id=OPT-56H9SXM">
  </script>
  <!-- Google Tag Manager -->
  <script>
   (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
            new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-W82WNBG');
  </script>
  <!-- End Google Tag Manager -->
  <!-- META DATA -->
  <meta charset="utf-8"/>
  <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
  <!--[if IE]><meta http-equiv="cleartype" content="on" /><![endif]-->
  <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" /><![endif]-->
  <link href="http://gmpg.org/xfn/11" rel="profile"/>
  <link href="https://www.synack.com/xmlrpc.php" rel="pingback"/>"""

VALUE_JS = """(function() {
    var didInit = false;
    function initMunchkin() {
        if(didInit === false) {
            didInit = true;
            Munchkin.init('738-OEX-476');
        }
    }
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = '//munchkin.marketo.net/munchkin.js';
    s.onreadystatechange = function() {
        if (this.readyState == 'complete' || this.readyState == 'loaded') {
            initMunchkin();
        }
    };
    s.onload = initMunchkin;
    document.getElementsByTagName('head')[0].appendChild(s);
})();"""

class DarkTheme:
    default_bg = "#1E1E1E"
    default_color = "#EEFFFF"
    darker_color = "#545454"
    key_color = "#C792EA"
    value_color = "#C3E88D"
    number_color = "#FF5370"
    operator_color = "#569CD6"
    invalid_color = "#f14721"
    selected_secondary_color = "#4E5256"
    other_color = "#FFCB6B"

    bg_dark = "#252526"
    bg_input = "#404040"
    bg_input_hover = "#3A3A3A"

    @classmethod
    def new_html_lexer(cls):
        lexer = Qsci.QsciLexerHTML()

        lexer.setDefaultPaper(QtGui.QColor(cls.default_bg))
        lexer.setDefaultColor(QtGui.QColor(cls.default_color))

        tags = [
            Qsci.QsciLexerHTML.SGMLDefault,
            Qsci.QsciLexerHTML.SGMLCommand,
            Qsci.QsciLexerHTML.SGMLParameter,
            Qsci.QsciLexerHTML.SGMLDoubleQuotedString,
            Qsci.QsciLexerHTML.SGMLSingleQuotedString,
            Qsci.QsciLexerHTML.SGMLError,
            Qsci.QsciLexerHTML.SGMLSpecial,
            Qsci.QsciLexerHTML.SGMLEntity,
            Qsci.QsciLexerHTML.SGMLComment,
            Qsci.QsciLexerHTML.SGMLParameterComment,
            Qsci.QsciLexerHTML.SGMLBlockDefault,
        ]
        for tag in tags:
            lexer.setColor(QtGui.QColor(cls.other_color), tag)
            lexer.setPaper(QtGui.QColor(cls.default_bg), tag)

        lexer.setColor(QtGui.QColor(cls.number_color), Qsci.QsciLexerHTML.Tag)
        lexer.setColor(QtGui.QColor(cls.number_color), Qsci.QsciLexerHTML.UnknownTag)
        lexer.setColor(QtGui.QColor(cls.key_color), Qsci.QsciLexerHTML.Attribute)
        lexer.setColor(QtGui.QColor(cls.key_color), Qsci.QsciLexerHTML.UnknownAttribute)

        lexer.setColor(QtGui.QColor(cls.operator_color), Qsci.QsciLexerHTML.XMLStart)
        lexer.setColor(QtGui.QColor(cls.operator_color), Qsci.QsciLexerHTML.XMLEnd)

        lexer.setColor(QtGui.QColor(cls.value_color), Qsci.QsciLexerHTML.OtherInTag)
        lexer.setColor(QtGui.QColor(cls.value_color), Qsci.QsciLexerHTML.HTMLNumber)
        lexer.setColor(QtGui.QColor(cls.value_color), Qsci.QsciLexerHTML.HTMLDoubleQuotedString)
        lexer.setColor(QtGui.QColor(cls.value_color), Qsci.QsciLexerHTML.HTMLSingleQuotedString)

        lexer.setPaper(QtGui.QColor(cls.default_bg), Qsci.QsciLexerHTML.JavaScriptDefault)
        lexer.setColor(QtGui.QColor(cls.default_color), Qsci.QsciLexerHTML.JavaScriptDefault)
        lexer.setPaper(QtGui.QColor(cls.default_bg), Qsci.QsciLexerHTML.Script)
        lexer.setColor(QtGui.QColor(cls.default_color), Qsci.QsciLexerHTML.Script)

        lexer.setColor(QtGui.QColor(cls.darker_color), Qsci.QsciLexerHTML.HTMLComment)
        lexer.setColor(QtGui.QColor(cls.default_color), Qsci.QsciLexerHTML.Default)
        lexer.setPaper(QtGui.QColor(cls.default_bg), Qsci.QsciLexerHTML.Default)

        # Javascript colours
        colours = {
            Qsci.QsciLexerHTML.JavaScriptDefault: cls.default_color,
            Qsci.QsciLexerHTML.JavaScriptSymbol: cls.default_color,
            Qsci.QsciLexerHTML.JavaScriptKeyword: cls.operator_color,

            Qsci.QsciLexerHTML.JavaScriptWord: cls.key_color,
            Qsci.QsciLexerHTML.JavaScriptKeyword: cls.key_color,

            Qsci.QsciLexerHTML.JavaScriptDoubleQuotedString: cls.value_color,
            Qsci.QsciLexerHTML.JavaScriptSingleQuotedString: cls.value_color,
        }
        for key, colour in colours.items():
            lexer.setColor(QtGui.QColor(colour), key)
            lexer.setPaper(QtGui.QColor(cls.default_bg), key)

        lexer.setFont(cls.get_font())
        return lexer

    @classmethod
    def new_json_lexer(cls):
        lexer = Qsci.QsciLexerJSON()

        lexer.setHighlightEscapeSequences(False)

        lexer.setDefaultPaper(QtGui.QColor(cls.default_bg))
        lexer.setDefaultColor(QtGui.QColor(cls.default_color))

        lexer.setPaper(QtGui.QColor(cls.default_bg), Qsci.QsciLexerJSON.Error)
        lexer.setColor(QtGui.QColor(cls.invalid_color), Qsci.QsciLexerJSON.Error)
        lexer.setPaper(QtGui.QColor(cls.default_bg), Qsci.QsciLexerJSON.UnclosedString)
        lexer.setColor(QtGui.QColor(cls.invalid_color), Qsci.QsciLexerJSON.UnclosedString)

        lexer.setColor(QtGui.QColor(cls.key_color), Qsci.QsciLexerJSON.Property)
        lexer.setColor(QtGui.QColor(cls.value_color), Qsci.QsciLexerJSON.String)
        lexer.setColor(QtGui.QColor(cls.number_color), Qsci.QsciLexerJSON.Number)
        lexer.setColor(QtGui.QColor(cls.default_color), Qsci.QsciLexerJSON.Operator)

        lexer.setFont(cls.get_font())
        return lexer

    @classmethod
    def new_js_lexer(cls):
        lexer = Qsci.QsciLexerJavaScript()

        lexer.setHighlightEscapeSequences(False)

        lexer.setDefaultPaper(QtGui.QColor(cls.default_bg))
        lexer.setDefaultColor(QtGui.QColor(cls.default_color))

        colours = {
            Qsci.QsciLexerCPP.Default: cls.default_color,
            Qsci.QsciLexerCPP.Operator: cls.default_color,
            Qsci.QsciLexerCPP.InactiveOperator: cls.operator_color,
            Qsci.QsciLexerCPP.Identifier: cls.operator_color,

            Qsci.QsciLexerCPP.Keyword: cls.key_color,

            Qsci.QsciLexerCPP.DoubleQuotedString: cls.value_color,
            Qsci.QsciLexerCPP.SingleQuotedString: cls.value_color,
            Qsci.QsciLexerCPP.InactiveDoubleQuotedString: cls.value_color,
            Qsci.QsciLexerCPP.InactiveSingleQuotedString: cls.value_color,
        }
        for key, colour in colours.items():
            lexer.setColor(QtGui.QColor(colour), key)

        lexer.setFont(cls.get_font())
        return lexer

    @classmethod
    def get_font(cls) -> QtGui.QFont:
        # fonts = QtGui.QFontDatabase.families()
        # TODO: Search through the fonts and find one that matches
        font = QtGui.QFontDatabase.font('Menlo', 'Regular', 11)
        return font


import time
import sys
import LZ78
import Huffman

def save_text(content, file_name):
    with open(file_name, "w", newline='') as f:
        return f.write(content)

if __name__ == '__main__':
    encoded_name = str(sys.argv[1])
    output_name = str(sys.argv[2])

    # Start of decoding process
    before_decode = time.time()

    ciphertext = Huffman.load_ciphertext(encoded_name)
    text = LZ78.decode(ciphertext)[:-1]

    # End of decoding process
    after_decode = time.time()
    print("Decoding Time: {} seconds".format(
        after_decode - before_decode))

    save_text(text, output_name)


# cube limitations (in cm)
POS_MAX = [80, 80, 180]
POS_MIN = [0, 0, 20]

# websocket for SDK cmd
CMD_IP = '192.168.10.1'
CMD_PORT = 8889
HOST_IP = '0.0.0.0'
RESP_PORT = 9000

# cmd
TAKEOFF_EXEC_TIME = 8
MOVE_EXEC_TIME = 4
ROTATION_EXEC_TIME = 3
MOVE = [40, 60, 80, 100, 120]
MOVE_UP_DOWN = [60, 80, 120]
DEGREES = [90, 180]
CMDS = [#["takeoff", None],
        #["land", None],
       # ["up", MOVE_UP_DOWN, MOVE_EXEC_TIME],
        #["down", MOVE_UP_DOWN, MOVE_EXEC_TIME],
        ["forward", MOVE, MOVE_EXEC_TIME],
        ["back", MOVE, MOVE_EXEC_TIME],
        ["left", MOVE, MOVE_EXEC_TIME],
        ["right", MOVE, MOVE_EXEC_TIME],
        ["cw", DEGREES, ROTATION_EXEC_TIME],    # rotate clockwise
        ["ccw", DEGREES, ROTATION_EXEC_TIME]   # rotate counter-clockwise
        ]

# mission pad detected (not constant)
PAD_DETECTED = False


from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from shutil import which
import chromedriver_binary
from fake_useragent import UserAgent
import time
from scrapy.selector import Selector
from selenium.webdriver.common.action_chains import ActionChains
import csv
from selenium.webdriver.support.ui import Select
import re
from datetime import datetime
import requests
from requests.structures import CaseInsensitiveDict
import sys
class kijihi():

    """
    proxies = [
        ""
        ]

    """
    count = 0
    links =[]

    def start(self):
        options = Options()
        options.add_experimental_option("detach", True)
        # options.add_argument("--headless")
        # options.add_argument("--no-sandbox")
        # options.add_argument('--disable-gpu')
        ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"
        options.add_argument(f'user-agent={ua}')
        options.add_argument("start-maximized")
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        options.add_experimental_option('useAutomationExtension', False)
        options.add_argument("--disable-blink-features=AutomationControlled")
        self.driver = webdriver.Chrome(options=options)
        self.driver.get('https://google.com')
        time.sleep(2)

    def target_url(self,url):
        self.driver.get(url)
        time.sleep(60)
        self.next_page()

    def result_scrap(self):
        html = self.driver.page_source
        resp = Selector(text=html)
        results = resp.xpath("//div[contains(@class,'ProductTile')]")
        for ri in results:
            li = ri.xpath(".//div/h3[@class='product-brand-name']/a/@href").extract_first()
            li = str(li)
            li = li.strip()
            li = f"https://www.liquorland.com.au{li}"
            self.links.append(li)

    def next_page(self):
        try:
            self.result_scrap()
            next_button = self.driver.find_element_by_xpath("//button[contains(@title,'next')]")
            if next_button:
                next_button.click()
                time.sleep(20)
                self.next_page()
        except:
            None

    def header(self,out_name):
        with open(out_name, 'w', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(["scrape_date","website_url","Product_ID","GTIN","Brand","product","price","pack_size","multibuy_deal_quantity","multibuy_deal_price","undiscounted_price","delivery_available","review_rating","review_count","style","type","packaging","standard_drinks","alcohol_content","organic","origin"])

    def scrap(self,scrape_date,out_name):
        self.header(out_name)
        for ulo in self.links:
            self.driver.get(ulo)
            try:
                WebDriverWait(self.driver, 30).until(EC.presence_of_element_located(
                    (By.XPATH, "//span[contains(text(),'Product ID')]/following-sibling::span")))
            except:
                None

            time.sleep(7)
            html = self.driver.page_source
            resp = Selector(text=html)

            website_url = str(ulo)
            Product_ID = resp.xpath("normalize-space(//span[contains(text(),'Product ID')]/following-sibling::span/text())").extract_first()
            GTIN = resp.xpath("normalize-space(//span[contains(text(),'GTIN')]/following-sibling::span/text())").extract_first()

            Brand = resp.xpath("//span[contains(text(),'Brand')]/following-sibling::span/a/text()").extract_first()
            product = resp.xpath("(//div[@class='product-name'])[1]/text()").extract_first()
            price = resp.xpath("normalize-space((//span[@class='PriceTag zero-cents current primary']//span[@class='dollarAmount'])[1]/text())").extract_first()

            pack_size = resp.xpath("normalize-space((//span[@class='unitOfMeasure'])[1]/text())").extract_first()

            multibuy_deal_quantity = resp.xpath("normalize-space(//div[@class='callout callout-text' and contains(text(),' for ')]/text())").extract_first()
            multibuy_deal_quantity = str(multibuy_deal_quantity)
            m_deal_quantity = re.findall(r"^([\w\-]+)",multibuy_deal_quantity)
            m_deal_quantity = str(m_deal_quantity)
            m_deal_quantity = m_deal_quantity.replace("'","")
            m_deal_quantity = m_deal_quantity.replace("[","")
            m_deal_quantity = m_deal_quantity.replace("]","")
            m_deal_quantity = m_deal_quantity.strip()

            multibuy_deal_quantity = multibuy_deal_quantity.replace(m_deal_quantity,'')
            multibuy_deal_quantity = multibuy_deal_quantity.replace('for','')
            multibuy_deal_quantity = multibuy_deal_quantity.replace('$','')
            multibuy_deal_price = multibuy_deal_quantity.strip()

            undiscounted_price = resp.xpath("(//span[contains(text(),'Price reduced from')])[1]/following-sibling::div/span[@class='dollarAmount']/text()").extract_first()

            delivery_available = resp.xpath("(//span[contains(text(),'Delivery')])[last()-3]/text()").extract_first()
            if delivery_available == "Delivery":
                delivery_available = True
            else:
                delivery_available = False

            review_rating = resp.xpath("//div[contains(@class,'bv_avgRating_component_container')]/text()").extract_first()
            review_count = resp.xpath("//div[contains(@class,'bv_numReviews_text')]/text()").extract_first()
            review_count = str(review_count)
            review_count = review_count.replace('-','')
            review_count = review_count.replace('(','')
            review_count = review_count.replace(')','')
            review_count = review_count.strip()
            style = resp.xpath("//span[contains(text(),'Style')]/following-sibling::span/text()").extract_first()
            type = resp.xpath("//span[contains(text(),'Type')]/following-sibling::span/text()").extract_first()
            packaging = resp.xpath("//span[contains(text(),'Packaging')]/following-sibling::span/text()").extract_first()
            standard_drinks = resp.xpath("//span[contains(text(),'Standard Drinks')]/following-sibling::span/text()").extract_first()
            alcohol_content = resp.xpath("//span[contains(text(),'Alcohol Content')]/following-sibling::span/text()").extract_first()
            organic = resp.xpath("//span[contains(text(),'Organic')]/following-sibling::span/text()").extract_first()
            origin = resp.xpath("//span[contains(text(),'Origin')]/following-sibling::span/text()").extract_first()

            print()
            print("scrape_date",scrape_date)
            print("website_url:",website_url)
            print("Product_ID:",Product_ID)
            print("GTIN:",GTIN)
            print("Brand:",Brand)
            print("product:",product)
            print("price:",price)
            print("pack_size:",pack_size)
            print("multibuy_deal_quantity:",m_deal_quantity)
            print("multibuy_deal_price:",multibuy_deal_price)
            print("undiscounted_price:",undiscounted_price)
            print("delivery_available:",delivery_available)
            print("review_rating:",review_rating)
            print("review_count:",review_count)
            print("style:",style)
            print("type:",type)
            print("packaging:",packaging)
            print("standard_drinks:",standard_drinks)
            print("alcohol_content:",alcohol_content)
            print("organic:",organic)
            print("origin:",origin)
            print()

            with open(out_name,'a',newline='',encoding='utf-8') as file:
                writer = csv.writer(file)
                writer.writerow([scrape_date,website_url,Product_ID,GTIN,Brand,product,price,pack_size,m_deal_quantity,multibuy_deal_price,undiscounted_price,delivery_available,review_rating,review_count,style,type,packaging,standard_drinks,alcohol_content,organic,origin])
                self.count = self.count + 1
                print("Data saved in excel: ",self.count)

    def close(self):
        self.driver.close()

if __name__ == '__main__':

    out_name = sys.argv[1]
    scrape_date = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    scraper = kijihi()
    scraper.start()
    url = "https://www.liquorland.com.au/beer"

    scraper.target_url(url)
    scraper.scrap(scrape_date,out_name)
    scraper.close()


import sys
import todo_model, todo_view

class CommandAndExecute:

    def __init__(self):
        self.command_list = {
        '-l': self.lister,
        '-a': self.adder,
        '-r': self.remover,
        '-c': self.checker}

        self.is_running = True
        self.cdr = sys.argv
        self.rw = todo_model.FileModifier()
        self.disp = todo_view.Display()
        self.file = self.rw.file
        self.is_running = True
        self.validator()

    # checking the existence of the file
    def validator(self):
        try:
            self.rw.todo_reader()
        except FileNotFoundError:
            self.rw.todo_file_creator()
        self.command_checker()

    def command_checker(self):
        if len(self.cdr) == 1:
            self.disp.intro()
        elif self.cdr[1] in self.command_list:
            self.command_list[self.cdr[1]]()
        else:
            self.disp.unsupported()

    def lister(self):
        self.disp.listing(self.rw.todo_reader())

    def adder(self):
        if len(self.cdr) == 3:
            self.rw.todo_adder()
        else:
            self.disp.invalid()

    def remover(self):
        if len(self.cdr) == 2:
            self.disp.no_index()
        else:
            try:
                if int(self.cdr[2]) > len(self.rw.todo_reader()):
                    self.disp.out_of()
                else:
                    self.rw.todo_checker()
            except ValueError:
                self.disp.exception()

    def checker(self):
        if len(self.cdr) == 2:
            self.disp.no_index()
        else:
            try:
                if int(self.cdr[2]) > len(self.rw.todo_reader()):
                    self.disp.out_of()
                else:
                    self.rw.todo_checker()
            except ValueError:
                self.disp.exception()

todo = CommandAndExecute()


from project.planet.planet import Planet
from project.planet.planet_repository import PlanetRepository
from project.astronaut.astronaut import Astronaut
from project.astronaut.astronaut_repository import AstronautRepository
from project.astronaut.biologist import Biologist
from project.astronaut.geodesist import Geodesist
from project.astronaut.meteorologist import Meteorologist

class SpaceStation:
    VALID_TYPES = {
        'Biologist': Biologist,
        'Geodesist': Geodesist,
        'Meteorologist': Meteorologist
    }

    SUCCESSFUL = 0
    UNSUCCESSFUL = 0

    def __init__(self):
        self.planet_repository = PlanetRepository()
        self.astronaut_repository = AstronautRepository()

    def add_astronaut(self, astronaut_type: str, name: str):
        for a in self.astronaut_repository.astronauts:
            if a.name == name:
                return f"{name} is already added."

        if astronaut_type not in SpaceStation.VALID_TYPES:
            raise Exception(f"Astronaut type is not valid!")

        curr_astronaut = SpaceStation.VALID_TYPES[astronaut_type](name)
        self.astronaut_repository.add(curr_astronaut)
        return f"Successfully added {astronaut_type}: {name}."

    def add_planet(self, name: str, items: str):
        for p in self.planet_repository.planets:
            if p.name == name:
                return f"{name} is already added."

        curr_planet = Planet(name)
        split_items = items.split(", ")

        for i in split_items:
            curr_planet.items.append(i)

        self.planet_repository.add(curr_planet)
        return f"Successfully added Planet: {name}."

    def retire_astronaut(self, name: str):
        astronaut = [a for a in self.astronaut_repository.astronauts if a.name == name]

        if not astronaut:
            raise Exception(f"Astronaut {name} doesn't exist!")

        curr_astronaut = astronaut[0]
        self.astronaut_repository.remove(curr_astronaut)

        return f"Astronaut {name} was retired!"

    def recharge_oxygen(self):
        for a in self.astronaut_repository.astronauts:
            a.increase_oxygen(10)

    def send_on_mission(self, planet_name: str):
        planet = [p for p in self.planet_repository.planets if p.name == planet_name]

        if not planet:
            raise Exception(f"Invalid planet name!")
        curr_planet = planet[0]

        sorted_astronauts = sorted(self.astronaut_repository.astronauts, key=lambda x: -x.oxygen)

        total = []
        for a in sorted_astronauts:
            if a.oxygen > 30:
                total.append(a)

        if not total:
            raise Exception(f"You need at least one astronaut to explore the planet!")

        participated = 0
        for astronaut in total[0:5]:
            while astronaut.oxygen:
                if curr_planet.items:
                    item = curr_planet.items.pop()
                    astronaut.backpack.append(item)
                    astronaut.breathe()

                else:
                    participated += 1
                    SpaceStation.SUCCESSFUL += 1
                    return f"Planet: {planet_name} was explored. {participated} astronauts participated in collecting items."

            participated += 1

        SpaceStation.UNSUCCESSFUL += 1
        return f"Mission is not completed."

    def report(self):
        final = [f"{SpaceStation.SUCCESSFUL} successful missions!\n"
                 f"{SpaceStation.UNSUCCESSFUL} missions were not completed!\n"
                 f"Astronauts' info:"]

        for a in self.astronaut_repository.astronauts:
            final.append(f"Name: {a.name}\nOxygen: {a.oxygen}")

            if a.backpack:
                final.append(f"Backpack items: {', '.join([item for item in a.backpack])}")
            else:
                final.append(f"Backpack items: none")

        return '\n'.join(final)

3. Python Advanced/Python OOP - Exams/Python OOP Retake Exam - 23 August 2021/01. Structure and 02. Functionality/project/space_station.py


import pandas as pd
import matplotlib.pyplot as plt

#import a subset of the modules
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

#read from the csv file and return a Pandas DataFrame.
# print the column names
# nba is the variable that has the whole data set imported from the Excel
print("\n", original_headers)
nba = pd.read_csv('NBAstats.csv')

##print the first three rows.
#print(nba[0:3])
## "(pos)" is the class attribute we are predicting.
class_column = 'Pos'

##The dataset contains attributes such as player name and team name.
##We know that they are not useful for classification and thus do not
##include them as features.
feature_columns = ['Age', 'G', 'GS', 'MP', 'FG', 'FGA', 'FG%', '3P', '3PA', \
   '3P%', '2P', '2PA', '2P%', 'eFG%', 'FT', 'FTA', 'FT%', 'ORB', 'DRB', \
   'TRB', 'AST', 'STL', 'BLK', 'TOV', 'PF', 'PS/G']
#
##Pandas DataFrame allows you to select columns.
##We use column selection to split the data into features and class.
nba_feature = nba[feature_columns]
nba_class = nba[class_column]

train_feature, test_feature, train_class, test_class = \
    train_test_split(nba_feature, nba_class, stratify=nba_class, \
    train_size=0.75, test_size=0.25)

training_accuracy = []
test_accuracy = []

tree = DecisionTreeClassifier(max_depth=6, random_state=0)
tree.fit(train_feature, train_class)
print("Training set score: {:.3f}".format(tree.score(train_feature, train_class)))
print("Test set score: {:.3f}".format(tree.score(test_feature, test_class)))

prediction = tree.predict(test_feature)
print("Confusion matrix:")
print(pd.crosstab(test_class, prediction, rownames=['True'], colnames=['Predicted'], margins=True))

train_class_df = pd.DataFrame(train_class,columns=[class_column])
train_data_df = pd.merge(train_class_df, train_feature, left_index=True, right_index=True)
train_data_df.to_csv('train_data.csv', index=False)

temp_df = pd.DataFrame(test_class,columns=[class_column])
temp_df['Predicted Pos']=pd.Series(prediction, index=temp_df.index)
test_data_df = pd.merge(temp_df, test_feature, left_index=True, right_index=True)
test_data_df.to_csv('test_data.csv', index=False)


import pystart
pystart.main()
""" Given an array Arr[] of N integers. Find the contiguous sub-array(containing at least one number) which has the minimum sum and return its sum."""
class solution:
    def minjumps(self,arr,n):
        if n == 1:
            return 0
        res = float('inf')
        for i in range(n-1):
            if (i + arr[i] >= n-1):
                sub_res = minJumps(arr, i+1)
                if sub_res != float('inf'):
                    res = min(res, sub_res + 1)
        return res

obj = solution()
obj.minjumps(arr,)
print("-----%s seconds-----"%(time.time()-start_time))
sys.stdin.close()
sys.stdout.close()


import numpy as np
from src.utils import tools

class Environment:
    def __init__(self, config):
        """Initializes the Gobang Environment Manager.

        :param config: configuration dictionary containing game parameters
        :type config: dict
        """
        # Extracting game parameters from the configuration dictionary
        self.config = config
        self.height = config["height"]
        self.width = config["width"]
        self.required_pieces = config["number win pieces"]
        self.pit_number = config["number pits"]
        # Initializing the Gobang environment object
        self.env = Gobang_Env(width=self.width, height=self.height,
                              required_win_pieces=self.required_pieces)
        # List that accumulates all actions taken in the environment
        self.action_acc = []
        # History of string representations of the game board
        self.string_board_hist = [self.get_board_string()]
        # Resetting the environment to its initial state
        self.reset_env()
        # Calculating the size of the action space
        self.action_space_size = self.width * self.height
        # Path to the experience replay directory in the configuration
        self.hist_dir_path = self.config['experience path']

    def execute_step(self, action):
        """Executes a step in the Gobang environment.

        :param action: the action to be taken in the environment
        :type action: int
        :return: True if the step was successfully executed, False otherwise
        :rtype: bool
        """
        # Remember the board state string before taking the step
        # Take a step in the environment
        successful = self.env.step(action)
        # Update attributes with the current state of the environment
        self.board, self.legal_actions, self.terminal, self.reward = self.env.last()
        # Add the action to the action accumulator
        self.action_acc.append(action)
        # Update the history of string representations of the game board
        self.string_board_hist.append(self.get_board_string())
        return successful

    def is_terminal(self):
        """Returns true if game is either truncated or terminated.

        :return: if game is terminated true, else false
        :rtype: boolean
        """
        return self.env.is_terminal()

    def pit(self, new_agent, old_agent, win_treshold):
        """Pits two agents against each other for a specified number of games.

        :param new_agent: The agent representing the new network.
        :type new_agent: function get_action_prob()
        :param old_agent: The agent representing the old network.
        :type old_agent: function get_action_prob()
        :param win_threshold: The threshold for victory, value between 0 and 1.
        :type win_threshold: float
        :return: True if the new agent wins, False otherwise.
        :rtype: bool
        """
        print("Start pitting...")
        # Set up the agents and counters for wins and draws
        self.agents = (new_agent, old_agent)
        self.new_agent_wins, self.old_agent_wins, self.draws = 0, 0, 0
        # Iterate through the specified number of games
        for pit_i in range(self.pit_number):
            print("Pit number:", pit_i + 1, "/", self.pit_number)
            # Determine which player starts the game
            player_i = 0 if pit_i%2 else 1
            print(f"{'old' if player_i else 'new'} player starting the game.. {player_i}")
            # Play a game between the two agents
            experience_replay = self.execute_pit(player_i)
            # Add new examples to the experience replay if a path is specified
            if self.hist_dir_path:
                tools.add_new_examples(self.hist_dir_path, experience_replay)
            # Create a gif to visualize the game
            if pit_i < 10:
                tools.create_gif(f"pit_n{pit_i}", self.action_acc, self.config)
            # Update win counters based on the game outcome
            if player_i == 0:
                if self.reward == 0:
                    self.draws += 1
                elif self.reward == 1:
                    self.new_agent_wins += 1
                    print("black wins!")
                elif self.reward == -1:
                    print("white wins")
                    self.old_agent_wins += 1
            else:
                if self.reward == 0:
                    self.draws += 1
                elif self.reward == 1:
                    self.old_agent_wins += 1
                    print("black wins")
                elif self.reward == -1:
                    self.new_agent_wins += 1
                    print("white wins")
            # Check if the new agent has already lost
            rounds_left = self.pit_number - pit_i - 1
            current_new_win_threshold = (self.old_agent_wins / (1 - win_treshold)) * win_treshold
            print(self.new_agent_wins, self.old_agent_wins, self.draws)
            if self.new_agent_wins + rounds_left < current_new_win_threshold:
                return False
            # Check if the old agent has already lost
            current_old_win_threshold = (self.new_agent_wins / win_treshold) * (1 - win_treshold)
            if self.old_agent_wins + rounds_left <= current_old_win_threshold:
                return True

    def execute_pit(self, player_i):
        """Executes one episode between two different agents/players.

        :param player_i: represents the player that starts (black) with the first
            move, either 0 or 1
        :type player: integer
        :returns: experience replay
        :rtype: list
        """
        experience_replay = []
        self.reset_env()
        self.agents[player_i].reset()
        move_count = 0
        while not self.is_terminal():
            # Compute action probablities by performing tree search
            pi = self.agents[player_i].get_action_probs()
            # Add a "neutralized" board to the experience replay (a board which
            # is player invariant)
            experience_replay.append((self.get_neutral_board(), pi, None))
            # Mask pi so that only legal moves are > 0
            mask = self.legal_actions
            masked_pi = pi
            masked_pi[mask==0] = 0
            # Choose the action with the highest probability
            action = np.argmax(masked_pi)
            # As the previous step is always taking the action the highest
            # probablities we take probablisitc actions for the first three
            # steps.
            if move_count < 3:
                action = np.random.choice(len(self.legal_actions), p=mask/(sum(mask)))
            # Take action
            self.execute_step(action)
            player_i = int(not player_i)
            move_count += 1
        # Assign rewards to each player's move
        for player_i, (observation, pi, _) in list(enumerate(experience_replay))[::-1]:
            r = self.env.reward * (1 if player_i%2 else -1)
            experience_replay[player_i] = (observation, pi, r)
        return experience_replay

    def reset_env(self):
        """Resets environment"""
        self.env.board = np.zeros((self.height, self.width))
        self.env.player = 0
        self.env.reward = 0
        self.env.legal_actions = self.env.get_legal_actions()
        self.env.terminal = False
        self.board, self.legal_actions, self.terminal, self.reward = self.env.last()
        self.action_acc = []
        self.string_board_hist = [self.get_board_string()]

    def create_copy(self):
        """Function that creates a copy of the environment itself."""
        env_copy = Environment(self.config)
        for action in self.action_acc:
            env_copy.execute_step(action)
        return env_copy

    def get_previous_board_string(self):
        """Retrieves the string representation of the board from the
        previous game state.

        :return: String representation of the board from the previous
            game state, or False if not available.
        :rtype: str or False
        """
        if len(self.string_board_hist) > 1:
            return self.string_board_hist[-2]
        return False

    """def copy_values_over(self, other_env):
        self.config = other_env.config
        self.height = self.config["height"]
        self.width = self.config["width"]
        self.required_pieces = self.config["number win pieces"]
        self.pit_number = self.config["number pits"]
        self.action_acc = copy.deepcopy(other_env.action_acc)
        self.string_board_hist = copy.deepcopy(self.string_board_hist)
        self.env.board = np.copy(other_env.env.board)
        self.env.win_pieces = other_env.env.win_pieces
        self.env.player = copy.deepcopy(other_env.env.player)
        self.env.pieces = other_env.env.pieces
        self.env.reward = copy.deepcopy(other_env.env.reward)
        self.env.legal_actions = other_env.env.get_legal_actions()
        self.env.terminal = copy.deepcopy(other_env.env.terminal)
        self.board, self.legal_actions, self.terminal, self.reward = self.env.last()"""

    def get_neutral_board(self):
        player = self.env.player
        player1 = self.env.board == player
        player2 = self.env.board == int(not player)
        empty_space = self.env.board == 0
        board_new = np.copy(self.env.board)
        board_new[player1] = 0
        board_new[player2] = 1
        board_new[empty_space] = 2
        return board_new

    def get_board_string(self):
        """Returns a string representation of the board. However we dont care
        about the player's color - the player currently playing is denoted with
        0, the enemy pieces are denoted with 1 and empty space with 2.
        """
        board_new = self.get_neutral_board()
        flattened_board = str(board_new.flatten())
        # Create a translation table to remove specified characters
        trans_table = str.maketrans("", "", " .\n[]")
        # Apply the translation to the string
        result = flattened_board.translate(trans_table)
        return result

class Gobang_Env:
    def __init__(self, width=19, height=19, required_win_pieces=5):
        """Initializes the Gobang Environment.

        :param width: Width of the game board.
        :type width: int, optional
        :param height: Height of the game board.
        :type height: int, optional
        :param required_win_pieces: Number of pieces in a row/column/diagonal
            required to win.
        :type required_win_pieces: int, optional
        """
        self.width, self.height = width, height
        self.board = np.zeros((height, width))
        self.win_pieces = required_win_pieces
        self.player = 0  # alternates between 0 and 1
        self.pieces = {0: 1, 1: -1}  # key=player, value=piece

        self.reward = 0
        self.legal_actions = self.get_legal_actions()
        self.terminal = False

    def step(self, action: int):
        """Take a step in the Gobang environment.

        :param action: The action to be taken, representing a position on the board.
        :type action: int
        :return: True if the step is successful, False otherwise.
        :rtype: bool
        """
        # Action space is a self.width * self.height large 1-dimensional array
        row = action // self.width
        column = action - (row * self.width)
        # Check if action is legal
        if not self.get_legal_actions()[action]:
            print("! Illegal Action:", action, "!")
            print(np.round(self.board))
            print(self.legal_actions.reshape((self.height, self.width)))
            input()
            return False
        # Place piece on the board
        self.board[row, column] = self.pieces[self.player]
        # Remove enemy pieces if caught (2 pieces in between 2 pieces)
        self.remove_enemy(row, column)
        # Update terminal and reward based on the current state
        self.terminal = self.is_terminal()
        if self.terminal:
            if self.is_draw():
                self.reward = 0
            elif self.player == 0:
                self.reward = 1
            elif self.player == 1:
                self.reward = -1
        # Switch player and update legal actions
        self.player = int(not self.player)
        self.legal_actions = self.get_legal_actions()
        return True

    def last(self):
        """Returns the current state information.

        :return: Tuple containing the board, legal actions,
            terminal state and reward.
        :rtype: tuple
        """
        return (self.board, self.legal_actions, self.terminal, self.reward)

    def get_legal_actions(self):
        """Returns an array representing legal moves, where 0 indicates illegal
        moves and 1 indicates legal moves.

        :return: Array representing legal actions.
        :rtype: numpy.ndarray
        """
        action_mask = np.zeros_like(self.board)
        # the first move of the game has to be on the center crosspoint
        if 1 not in self.board:
            action_mask[self.height//2, self.width//2] = 1
            # flatten action mask
            action_mask = action_mask.ravel()
            return action_mask
        # after first move every move is legal where there is no piece
        action_mask[self.board == 0] = 1
        # flatten action mask
        action_mask = action_mask.ravel()
        return action_mask

    def remove_enemy(self, row, column):
        """Checks in every possible direction if the removal condition is met
        and removes enemy pieces accordingly.

        :param row: Row index of the last placed piece.
        :type row: int
        :param column: Column index of the last placed piece.
        :type column: int
        """
        player_color = self.pieces[self.player]
        directions = [(1, 0), (-1, 0),
                      (0, 1),(0, -1),
                      (1, 1), (1, -1),
                      (-1, 1), (-1, -1)]
        for ydir, xdir in directions:
            y, x = row + ydir * 3, column + xdir * 3
            if 0 <= y < self.height and \
               0 <= x < self.width and \
               self.board[y, x] == player_color:
                pattern = []
                ye1, xe1 = row + ydir * 2, column + xdir * 2
                pattern.append(self.board[ye1, xe1])
                ye2, xe2 = row + ydir * 1, column + xdir * 1
                pattern.append(self.board[ye2, xe2])
                enemy_player_color = self.pieces[int(not self.player)]
                # Check if both inner pieces are from the enemy player
                if np.all(np.array(pattern) == enemy_player_color):
                    # Remove enemy pieces
                    self.board[ye1, xe1] = 0
                    self.board[ye2, xe2] = 0

    def is_draw(self):
        """Checks if a position is draw."""
        return not np.any(self.board == 0)

    def is_terminal(self):
        """Checks if a position is terminal"""
        if self.is_draw(): return True

        def check_lines(arr):
            for y in range(arr.shape[0]):
                for x in range(arr.shape[1]-self.win_pieces+1):
                    if abs(np.sum(arr[y, x:x+self.win_pieces])) == self.win_pieces:
                        return True
            return False

        def check_diagonals(arr):
            for i in range(-arr.shape[0]+1, arr.shape[0]-1):
                diagonal = arr.diagonal(i)
                for x in range(len(diagonal)-self.win_pieces+1):
                    if abs(np.sum(diagonal[x:x+self.win_pieces])) == self.win_pieces:
                        return True
            return False

        return any([
            check_lines(self.board),
            check_lines(self.board.T),
            check_diagonals(self.board),
            check_diagonals(np.flipud(self.board))
        ])

    def copy_env(self):
        """Creates a deep copy of the current game environment.

        :return: New instance of the Gobang_Env class with copied state
        :rtype: Gobang_Env-object
        """
        new_env = Gobang_Env(self.width, self.height, self.win_pieces)
        new_env.board = np.copy(self.board)
        new_env.player = self.player
        new_env.reward = self.reward
        new_env.legal_actions = new_env.get_legal_actions()
        new_env.terminal = new_env.is_terminal()
        return new_env


import numpy as np
from numpy import genfromtxt
import pickle
from fuzzywuzzy import fuzz

with open('./pickles/movie_to_idx.pickle', 'rb') as f:
    # Dump the dictionary into the file using pickle
    movie_to_idx = pickle.load(f)

with open('./pickles/m_dist.pickle', 'rb') as f:
    # Dump the dictionary into the file using pickle
    m_dist = pickle.load(f)

with open('./pickles/movie_dict.pickle', 'rb') as f:
    # Dump the dictionary into the file using pickle
    movie_dict = pickle.load(f)

item_vecs = genfromtxt('csv/item_vecs.csv', delimiter=',')

def fuzzy_matching(fav_movie, verbose=True):
    print('inside of fuzzy matching')
    """
    return the closest match via fuzzy ratio. If no match found, return None

    Parameters
    ----------
    mapper: dict, map movie title name to index of the movie in data

    fav_movie: str, name of user input movie

    verbose: bool, print log if True

    Return
    ------
    index of the closest match
    """
    match_tuple = []
    # get match
    for title, idx in movie_to_idx.items():
        ratio = fuzz.ratio(title.lower(), fav_movie.lower())
        if ratio >= 60:
            match_tuple.append((title, idx, ratio))
    # sort
    match_tuple = sorted(match_tuple, key=lambda x: x[2])[::-1]
    if not match_tuple:
        print('Oops! No match is found')
        return
    if verbose:
        print('Found possible matches in our database: {0}\n'.format([x[0] for x in match_tuple]))
    return match_tuple[0][1]

def make_pred(fav_movie, n_recommandations = 10):
    id_listesi = []
    title_listesi = []
    idx= fuzzy_matching(fav_movie)
    for i in np.argsort(m_dist[idx])[::1][:n_recommandations]:
        movid = int(item_vecs[i,0])
        id_listesi.append(movid)
        title_listesi.append(movie_dict[item_vecs[i,0]]['title'])

    return id_listesi, title_listesi


import numpy as np
from gb_toolbox import gb_current

# Glacier Bay entrance
# stn_list = ['SEA1002', 'SEA1003', 'SEA1004']
# bdate = '20100601'
# edate = '20100701'

# stn_list = ['SEA0845', 'SEA0846', 'SEA0847', 'SEA0848', 'SEA0849', 'SEA0850']
# bdate = '20080810'
# edate = '20080910'

for stn in stn_list:
    info = {'stn' : stn,
            'bdate' : bdate,
            'edate' : edate,
            'filename': '/glade/p/work/chuning/data/NOAA_ADCP/'+stn+'.nc',
            'sl': 'l',
            'Wp_hrs': 2}

    crt = gb_current.get_noaa_current(info)
    crt()


import os
from subprocess import Popen, PIPE, STDOUT
from .latex import LaTeX
from ..protocol import *

class DraTeX(LaTeX):
    def __init__(self, name = "dratex"):
        super(DraTeX, self).__init__()
        self.name = name
        the_plugin_path = get_plugin_path(name)
        self.pre_code = """
\\documentclass{standalone}
\\input "%s/latex/DraTex.sty"
\\input "%s/latex/AlDraTex.sty"
\\pagestyle{empty}
\\begin{document}
""" % (the_plugin_path, the_plugin_path)
        self.post_code = """
\\end{document}
"""
        self.message = "TeXmacs interface to (Al)DraTex (High Level Drawing Facilities)"

    def evaluate(self, code):
        if not (code.lstrip().startswith("\\documentclass")):
            code = self.pre_code + "\n" + code + "\n" + self.post_code

        super(DraTeX, self).evaluate(code)


# https://www.acmicpc.net/problem/1967

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 8)
n = int(input())
graph = [{} for _ in range(n+1)]

for _ in range(n-1):
    p,c,w = map(int, input().split())
    graph[p][c] = w
answer = 0

def dfs(current):
    global answer
    twoSide = []
    oneSide = 0
    for node, weight in graph[current].items():
        val = dfs(node)
        twoSide.append(val + weight)
        oneSide = max(oneSide, val + weight)
    answer = max(answer, sum(sorted(twoSide)[-2:]))
    return oneSide

dfs(1)
print(answer)
# visited = []
# def dfs(current, diameter):
#     for node in graph[current]:
#         if not visited[node]:
#             visited[node] = True
#             dfs(node, diameter + graph[current][node])
#         else:
#             global answer
#             answer = max(answer, diameter)

# for i in range(n-1):
#     visited = [False for _ in range(n+1)]
#     visited[i] = True
#     dfs(i, 0)


import os
import sys
import glob
import ftplib
import syslog
import time
import datetime
import pg
import re

def getList(lines,regex):
    result = []
    for l in lines:
        match = re.match(regex,l)
        if match:
            result.append(l)
    result.sort()
    return result

# Initialization
#  *******************  Modify The Following *********************
local_image_dir  = '/var/www/html/flight_data/images/'
labelfile        = local_image_dir+'time_label.jpg'
local_ge_dir     = '/var/www/html/flight_data/GE/'
font             = '/usr/java/latest/lib/fonts/LucidaTypewriterRegular.ttf'

# **************** End of Modify section ************************

####   KML section #####
# Get the listing and search it for latest images of each type
dirlist = os.listdir(local_ge_dir)
label = ''
# CDPHE Data
CDPHEregx = 'gis.CDPHE_Monitor.*.obs.kml'
cdphelist = getList(dirlist,CDPHEregx)
if len(cdphelist) != 0:
    cdpheFile = cdphelist[len(cdphelist)-1]
    cdpheElmts = []
    cdpheElmts = cdpheFile.split('.')
    label = label + "CDPHE: "+ cdpheElmts[2][:8] + 'T' + cdpheElmts[2][8:-2] + ':' + cdpheElmts[2][10:] + "\\n"
else:
    label = label + 'CDPHE: no file available\\n'

####   Image section #####
# Get the listing and search it for latest images of each type
os.chdir(local_image_dir)

dirlist = os.listdir(local_image_dir)

# NEXRAD Conus - NOTE: might want to do a diff on the last two
#  as it's possible that we get the same image repeatedly
#  (date/time stamped on the plane)
NWSregx = 'NEXRAD.conu*'
conuslist = getList(dirlist,NWSregx)
if len(conuslist) != 0:
    conusFile = conuslist[len(conuslist)-1]
    conusElts = []
    conusElts = conusFile.split('.')
    conusFile = "NWS:     "+ conusElts[2][:8] + 'T' + conusElts[2][8:-2] + ':' + conusElts[2][10:] + "\\n"
else:
    conusFile = "NWS:     no file available\\n"

label = label + conusFile

# Infra-red
IRregx = 'satellite.GOES-13.*thermal-IR.jpg'
irlist = getList(dirlist,IRregx)
if len(irlist) != 0:
    irFile = irlist[len(irlist)-1]
    irElmts = []
    irElmts = irFile.split('.')
    label = label + "IR:          "+ irElmts[2][:8] + 'T' + irElmts[2][8:-2] + ':' + irElmts[2][10:] + "\\n"
else:
    label = label + 'IR:          no file available\\n'

# Visible
VISregx = 'satellite.GOES-13.*ch1_vis.jpg'
vislist = getList(dirlist,VISregx)
if len(vislist) != 0:
    visFile = vislist[len(vislist)-1]
    visElmts = []
    visElmts = visFile.split('.')
    visFile = "VIS:        "+ visElmts[2][:8] + 'T' + visElmts[2][8:-2] + ':' + visElmts[2][10:] + "    "
else:
    visFile = "VIS:          no file available    "

label = label + visFile

####  Done getting listings ####
# Generate the label gif image
command = "convert -background lightblue -fill blue -font " + font + " -pointsize 18 label:'"+label+"' " + labelfile
os.system(command)


"""Commands module for EVENTS UTILITIES.
Access: Role-based"""

import asyncio
from typing import List

import discord

from petal.checks import all_checks, Messages
from petal.commands import core, shared
from petal.exceptions import CommandOperationError
from petal.menu import Menu
from petal.types import Src
from petal.util.embeds import Color
from petal.util.questions import ChatReply

class CommandsEvent(core.Commands):
    auth_fail = "This command requires the `{role}` role."
    role = "xPostRole"

    async def cmd_shiftcategory(
            self, args, src: Src, **_):
        return_channel: discord.TextChannel = src.channel
        event_group_id = self.config.get("eventCategory")
        main_chat_id = self.config.get("mainChatCategory")
        default_position = self.config.get("defaultEventChannelPosition")
        event_group: discord.CategoryChannel = self.client.main_guild.get_channel(event_group_id)
        main_chat: discord.CategoryChannel = self.client.main_guild.get_channel(main_chat_id)
        self.log.info(f"Main Chat position is: {main_chat.position}")
        self.log.info(f"Current event chat position is: {event_group.position}")

        if event_group.position > main_chat.position:
            await event_group.move(before=main_chat)
            await return_channel.send(content=f"{event_group.name} was moved right above {main_chat.name}")
        else:
            await event_group.edit(position=default_position)
            await return_channel.send(content=f"{event_group.name} was moved back to its default position ({default_position})")

    async def cmd_event(
        self, src, _image: str = None, _message: str = None, _nomenu: bool = False, **_
    ):
        """Post a message announcing the start of an event.

        Define a message which will be sent to one or more predefined channels. The message may include mass pings by way of including tags `{{e}}` and `{{h}}` for substitution.
        Destination channels may be selected conversationally or by way of a reaction-based menu.

        Options:
        `--message=<msg>` :: Define the message to send ahead of time. This will skip the step where Petal asks you what you want the message to say.
        `--nomenu` :: Forsake the Reaction UI and determine destination channels conversationally.
        """
        channels_list = []
        channels_dict = {}
        msg = ""
        for chan in self.config.get("xPostList"):
            channel = self.client.get_channel(chan)
            if channel is not None:
                msg += (
                    f"{len(channels_list)}. ({channel.name} [{channel.guild.name}])\n"
                )
                channels_list.append(channel)
                channels_dict[channel.guild.name + "/#" + channel.name] = channel
            else:
                self.log.warn(
                    f"{chan} is not a valid channel. I'd remove it if I were you."
                )

        # Get channels to send to.
        if _nomenu:
            # Do it only conversationally.
            menu = None
            while True:
                await self.client.send_message(
                    src.author,
                    src.channel,
                    "Hi there, "
                    + src.author.name
                    + "! Please select the number of "
                    + "each guild you want to post "
                    + "to. (dont separate the numbers)",
                )

                await self.client.send_message(src.author, src.channel, msg)

                chans = await Messages.waitfor(
                    self.client,
                    all_checks(
                        Messages.by_user(src.author), Messages.in_channel(src.channel)
                    ),
                    timeout=20,
                )

                if chans is None:
                    raise CommandOperationError(
                        "Sorry, the request timed out. Please make sure you"
                        " type a valid sequence of numbers."
                    )
                if self.validate_channel(channels_list, chans.content):
                    break
                else:
                    await self.client.send_message(
                        src.author,
                        src.channel,
                        "Invalid channel choices. You may try again immediately.",
                    )
            post_to = []
            for i in chans.content:
                print(channels_list[int(i)])
                post_to.append(channels_list[int(i)])
        else:
            # Use the Reaction-based GUI.
            menu = Menu(self.client, src.channel, "Event Announcement", user=src.author)
            if _image:
                menu.em.set_thumbnail(url=_image)
            selection = await menu.get_multi(
                list(channels_dict), title="Available Channels"
            )
            post_to = [channels_dict[c] for c in selection if c in channels_dict]
            if not post_to:
                menu.add_section("No Channels selected; Cancelled.", "Target Channels")
                await menu.post()
                return
            menu.add_section("\n".join(c.mention for c in post_to), "Target Channels")
            await menu.post()

        msgstr = yield ChatReply(
            "What do you want to send? (remember: {e} = `@ev` and {h} = `@here`)",
            120,
        )
        if not msgstr:
            # No reply.
            raise CommandOperationError("Text Input timed out.")

        try:
            msgstr = msgstr.format(e="@everyone", h="@here")
        except Exception as e:
            # Given a bad Format tag.
            raise CommandOperationError(
                "Could not perform `format()`. Make sure you did the braces"
                " around any `{e}`s or `{h}`s correctly."
                "\n(Any other braces in the message should be {{doubled}}.)"
            ) from e

        if _nomenu:
            embed = discord.Embed(
                title="Message to post", description=msgstr, colour=Color.info
            )
            embed.add_field(
                name="Channels", value="\n".join(c.mention for c in post_to)
            )
            await self.client.embed(src.channel, embed)

            msg2 = await Messages.waitfor(
                self.client,
                all_checks(
                    Messages.by_user(src.author), Messages.in_channel(src.channel)
                ),
                timeout=20,
                channel=src.channel,
                prompt="If this is correct, type `confirm`.",
            )

            if msg2 is None:
                raise CommandOperationError("Event post timed out.")
            elif msg2.content.lower() != "confirm":
                raise CommandOperationError("Event post cancelled.")
        else:
            menu.add_section(msgstr, "Confirm Message")
            await menu.post()
            proceed = await menu.get_bool()
            if proceed is None:
                menu.add_section("Posting timed out.", "Confirmation")
                await menu.post()
                return
            elif proceed is not True:
                menu.add_section("Posting cancelled.", "Confirmation")
                await menu.post()
                return

        posted: List[discord.Message] = []
        # TODO
        # em = discord.Embed()
        # if _image:
        #     em.set_image(url=_image)
        for i in post_to:
            posted.append(await i.send(msgstr))
            await asyncio.sleep(1)

        if menu:
            menu.add_section("Messages have been posted.", "Confirmation")
            await menu.post()
        else:
            yield "Messages have been posted."

        try:
            subkey, subname = self.get_event_subscription(msgstr)
        except AttributeError:
            pass
        else:
            if subkey is None:
                yield (
                    "I was unable to auto-detect any game titles in your post."
                    " No subscribers will be notified for this event."
                )
            else:
                n = await Messages.waitfor(
                    self.client,
                    all_checks(
                        Messages.by_user(src.author), Messages.in_channel(src.channel)
                    ),
                    timeout=20,
                    channel=src.channel,
                    prompt=f"I auto-detected a possible game in your announcement:"
                    f" **{subname}**. Would you like to notify subscribers? [y/N]",
                )

                if not n:
                    yield "Timed out."
                elif n.content.lower() not in ("y", "yes"):
                    yield "Subscribers will not be notified."
                else:
                    response = await self.notify_subscribers(
                        src.channel, posted[0], subkey
                    )
                    todelete = f"[{subkey}]"
                    for post in posted:
                        content = post.content
                        if todelete in content:
                            content = content.replace(todelete, "")
                            await post.edit(content=content)

                    yield response

    cmd_send = shared.factory_send(
        {
            "events": {"colour": 0x1B6649, "title": "Event Announcement"},
            "staff": {"colour": 0x4CCDDF, "title": "Staff Signal"},
        },
        "events",
    )

# Keep the actual classname unique from this common identifier
# Might make debugging nicer
CommandModule = CommandsEvent


# Problem 6
'''
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

P   A   H   N
A P L S I I G
Y   I   R

And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string s, int numRows);

Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
'''

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows == 1: return s
        res =""
        for r in range(numRows):
            #steps - to calculate the number of steps need to get the next charater in the zig-zag
            steps = (numRows - 1) * 2
            for i in range(r, len(s), steps):
                # step-wise looping to get intermediate characters in zig-zag
                res += s[i]
                if (r > 0 and r < numRows - 1 and i + steps - 2 *r < len(s)):
                    res += s[i + steps - 2 * r]
        return res