"""Example of convolutional neural network classififer."""

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

import tensorflow as tf

FLAGS = tf.flags.FLAGS

def get_params():
    return {
        "drop_rate": 0.5
    }

def modelCNN(features, labels, mode, params):
    images = features["image"]
    labels = labels["label"]
    tf.summary.image("images", images)

    drop_rate = params.drop_rate if mode == tf.estimator.ModeKeys.TRAIN else 0.0

    features = images
    for i, filters in enumerate([32, 64, 128]):
        features = tf.layers.conv2d(
            features, filters=filters, kernel_size=3, padding="same",
            name="conv_%d" % (i + 1))
        features = tf.layers.max_pooling2d(
            inputs=features, pool_size=2, strides=2, padding="same",
            name="pool_%d" % (i + 1))

    features = tf.contrib.layers.flatten(features)
    features = tf.layers.dropout(features, drop_rate)
    features = tf.layers.dense(features, 512, name="dense_1")
    features = tf.layers.dropout(features, drop_rate)
    logits = tf.layers.dense(features, params.num_classes, activation=None, name="dense_2")

    predictions = tf.argmax(lpredictions=1)

    loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
    return {"predictions": predictions}, loss

def eval_metrics(unused_params):
    return {
        "accuracy": tf.contrib.learn.MetricSpec(tf.metrics.accuracy)
    }


#!/usr/bin/python3
"""
Export data
"""
from sys import argv
import json
import requests

if __name__ == "__main__":
    """ export data
    """
    url = 'https://jsonplaceholder.typicode.com'
    user_id = argv[1]
    filename = user_id + ".json"
    value1 = requests.get(url + '/todos')
    value2 = requests.get(url + '/users/{}'.format(user_id))
    username = value2.json()['username']

    with open(filename, 'w', newline='') as csvfile:
        a_dict = {}
        a_list = []
        for todo_dict in value1.json():
            if todo_dict.get('userId') == int(user_id):
                task_dict = {}
                task_dict['task'] = todo_dict.get('title')
                task_dict.update({'username': username})
                task_dict['completed'] = todo_dict.get('completed')
                a_list.append(task_dict)
        a_dict['{}'.format(user_id)] = a_list
        json.dump(a_dict, csvfile)


def longestCommonPrefix(self, strs: [str]) -> str:
    prefix = ""
    if len(strs) == 0:
        return prefix
    for i in range(len(strs[0])):
        for string in strs:
            if i == len(string) or string[i] != strs[0][i]:
                return prefix
        prefix += strs[0][i]

    return prefix


import torch.nn as nn
import torch
import numpy as np
from torch.autograd import Variable
import torch.nn.functional as F

class MLE(nn.Module):
    def __init__(self):
        super(MLE, self).__init__()

    # def arithmetic_mean(self, mu, s):
    #     return np.exp((mu + s.exp()/2.).cpu().data.numpy())

    def forward(self, pred_params, tgts):
        cum_loss = 0
        for pred_param, tgt in zip(pred_params, tgts):
            mu, s = pred_param[0], pred_param[1]
            pred = torch.distributions.LogNormal(mu, s.exp())
            # pred = self.arithmetic_mean(mu, s)
            # print("ARITHMETIC pred is:",pred)
            tte, is_alive = tgt[0], tgt[1]

            # Convert tte in sec to days
            # tte = tte / 86400
            # print("tte", tte)
            # print("log prob", pred.log_prob(tte + 1e-5))
            # print("cdf", pred.cdf(tte))
            if is_alive:
                incr_loss = -((1 - pred.cdf(tte) + 1e-5).log())
            else:
                incr_loss = -(1 - is_alive) * pred.log_prob(tte + 1e-5)
            if torch.isnan(incr_loss) or incr_loss == float('inf'):
                if is_alive:
                    print("nan alive; pred cdf", pred.cdf(tte), "; pred", pred, "; log inner", 1 - pred.cdf(tte) + 1e-5, "; log", (1 - pred.cdf(tte) + 1e-5).log())
                else:
                    print("nan dead; pred log_prob", pred.log_prob(tte + 1e-5), "; tte + eps", tte + 1e-5)
                print("pred params: mu, s", mu, s)
            cum_loss += -((1 - pred.cdf(tte) + 1e-5).log()) if is_alive else -(1 - is_alive) * pred.log_prob(tte + 1e-5)
            print("loss_val per", cum_loss)
        print("loss val in mle.py", cum_loss)

        return cum_loss / tgts.shape[0]


"""NUMBER SPİRAL DIAGNOALS"""

"""3'er 3'er 4 kez, 5'er 5'er 4 kez...
   3 + 2*499 kez artış sağla"""

total = 1
i = 1
for coefficident in range(2,1001,2):
    for num in range(1,5):
        i += coefficident
        total += i

print(total)


from trac.core import *
from trac.web.chrome import ITemplateProvider
from trac.ticket.api import TicketSystem
from trac.util import sorted
from webadmin.web_ui import IAdminPageProvider

from api import HideValsSystem

class HideValsAdminModule(Component):
    """WebAdmin sub-page for configuring the TracHideVals plugins."""

    implements(IAdminPageProvider, ITemplateProvider)

    # IAdminPageProvider methods
    def get_admin_pages(self, req):
        if req.perm.has_permission('TICKET_ADMIN'):
            for field in TicketSystem(self.env).get_ticket_fields():
                if 'options' in field:
                    yield 'hidevals', 'Hide Values', field['name'], field['label']

    def process_admin_request(self, req, cat, page, path_info):
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        field = dict([(field['name'], field) for field in TicketSystem(self.env).get_ticket_fields()])[page]
        cursor.execute('SELECT sid, value FROM hidevals WHERE field = %s', (field['name'],))
        values = cursor.fetchall()
        enabled = field['name'] not in HideValsSystem(self.env).dont_filter

        if req.method == 'POST':
            if req.args.get('add'):
                group = req.args['group']
                value = req.args['value']
                if (group, value) not in values:
                    cursor.execute('INSERT INTO hidevals (sid, field, value) VALUES (%s, %s, %s)', (group, field['name'], value))
                    db.commit()
            elif req.args.get('remove'):
                sel = req.args.getlist('sel')
                for val in sel:
                    group, value = val.split('#', 1)
                    cursor.execute('DELETE FROM hidevals WHERE sid = %s AND field = %s AND value = %s', (group, field['name'], value))
                    db.commit()
            elif req.args.get('toggle'):
                new_val = HideValsSystem(self.env).dont_filter[:]
                if enabled:
                    new_val.append(field['name'])
                else:
                    new_val.remove(field['name'])
                self.config.set('hidevals', 'dont_filter', ', '.join(sorted(new_val)))
                self.config.save()

            req.redirect(req.href.admin(cat, page))

        req.hdf['hidevals.field'] = field
        req.hdf['hidevals.values'] = [{'group': g, 'value': v} for g,v in values]
        req.hdf['hidevals.enabled'] = enabled
        return 'admin_hidevals.cs', None

    # ITemplateProvider methods
    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    def get_htdocs_dirs(self):
        from pkg_resources import resource_filename
        return [('hidevals', resource_filename(__name__, 'htdocs'))]


from unittest import TestCase
from cards.pokemon_card import PokemonCard
from cards.energy_card import EnergyCard
from ability import Ability

class TestPokemonCard(TestCase):
    def test_add_ability(self):
        """
        GIVEN: A Pokémon and an ability object
        WHEN: add_ability is called
        THEN: ability is added to Pokémon
        """
        # arrange
        pokemon = PokemonCard(name='Pikachu', health_points=100, pokemon_type='electric')
        ability = Ability(name='Thundershock', damage=110, energy_reqs={'electric': 1})

        # act
        pokemon.add_ability(ability)

        # assert
        self.assertEqual(pokemon.abilities['Thundershock'], ability)

    def test_attach_energy(self):
        """
        GIVEN: A Pokémon and an energy object
        WHEN: attach_energy is calles
        THEN: energy is attached to Pokémon
        """
        # arrange
        pokemon = PokemonCard(name='Pikachu', health_points=100, pokemon_type='electric')
        energy = EnergyCard(name='thunder', energy_type='electric')

        # act
        pokemon.attach_energy(energy)

        # assert
        self.assertEqual(pokemon.energies[0], energy)

    def test_use_ability(self):
        """
        GIVEN: A pokemon and an ability object
        WHEN: use_ability is calles
        THEN: ability is used on pokemon
        """
        # arrange
        pokemon = PokemonCard(name='Kangaskhan', health_points=100, pokemon_type='normal')
        ability = Ability(name='My Hability', damage=50, energy_reqs={'electric': 2, 'normal': 2})
        energies = [EnergyCard(name='electric energy', energy_type='electric'),
                    EnergyCard(name='electric energy', energy_type='electric'),
                    EnergyCard(name='double normal energy', energy_type='normal', amount=1),
                    EnergyCard(name='double psychic energy', energy_type='psychic', amount=2)]

        pokemon.add_ability(ability)
        for energy in energies:
            pokemon.attach_energy(energy)

        # act
        pokemon.use_ability('My Hability', other_pokemon=pokemon)

        # assert
        self.assertEqual(pokemon.health_points, 50)

    def test_remove_energy(self):
        """
        GIVEN: A Pokémon and an energy object
        WHEN: Remove_energy is called
        THEN: Energy is removed from Pokémon
        """
        # arrange
        pokemon = PokemonCard(name='Pikachu', health_points=100, pokemon_type='electric')
        energies = [EnergyCard(name='thunder', energy_type='electric'),
                    EnergyCard(name='triple energy ', energy_type='electric'),
                    ]

        EnergyCard(name='triple energy ', energy_type='electric'),

        energy = EnergyCard(name='thunder', energy_type='electric')

        # act
        pokemon.attach_energy(energy)
        pokemon.remove_energy(energy)

        # assert
        self.assertEqual(pokemon.energies, [])

    def test_knock_out(self):
        self.fail()


import requests
import json
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter

requestSession = None

def initializeRequestSession():
    global requestSession
    requestSession = requests.Session()
    retries = Retry(total=5,
                    backoff_factor=0.1,
                    status_forcelist=[500, 502, 503, 504])
    requestSession.mount('http://', HTTPAdapter(max_retries=retries))
    requestSession.mount('https://', HTTPAdapter(max_retries=retries))

def getPostRequest(reqUrl,payLoad={}):
    return requestSession.post(reqUrl, data=payLoad)

def getGetRequest(reqUrl,payLoad={}):
    return requestSession.get(reqUrl, data=payLoad)

def getTheUrl(reqUrl,payLoad={}):
    try:
        req = getGetRequest(reqUrl,payLoad)
        return parseRequest(req)
    except Exception as e:
        print(str(e))
        raise e

def postTheUrl(reqUrl,payLoad={}):
    try:
        req = getPostRequest(reqUrl,payLoad)
        return parseRequest(req)
    except Exception as e:
        print(str(e))
        raise e

def parseRequest(req):
    try:
        data = json.loads(req.text)
        return data
    except Exception as e:
        raise e

def getImageContent(imageDownloadUrl):
    return requestSession.get(imageDownloadUrl).content


#!/usr/bin/env python3
"""
Print your header
"""
import argparse
import logging

from rich import box
from rich.console import Console
from rich.logging import RichHandler
from rich.table import Table

from your import Your
from your.utils.misc import YourArgparseFormatter

def nice_print(dic):
    """
    Prints out data files into in a nice to view way

    Inputs:
    dic --  dictionary containing data file meta data to be printed
    """
    for key, item in dic.items():
        print(f"{key}\t{item}")

def table_print(dic):
    """
    Prints out data using rich.Table

    Inputs:
    dic --  dictionary containing data file meta data to be printed
    """

    console = Console()
    table = Table(show_header=True, header_style="bold red", box=box.DOUBLE_EDGE)
    table.add_column("Parameter", justify="right")
    table.add_column("Value")
    for key, item in dic.items():
        table.add_row(key, f"{item}")
    console.print(table)

def read_header(f, no_table):
    """
    Makes your header for given files, hands header off to be nicely printed

    Inputs:
    --
    f -- files to create the your header

    no_table -- bool - if true, don't use rich.table
    """
    y = Your(f)
    dic = vars(y.your_header)
    dic["tsamp"] = y.your_header.tsamp
    dic["nchans"] = y.your_header.nchans
    dic["channel_bandwidth"] = y.your_header.foff
    dic["nspectra"] = y.your_header.nspectra
    if no_table:
        nice_print(dic)
    else:
        table_print(dic)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        prog="your_header.py",
        description="Read header from psrfits/filterbank files and print the unified header",
        formatter_class=YourArgparseFormatter,
    )
    parser.add_argument(
        "-f",
        "--files",
        help="psrfits or filterbank files to read header.",
        required=True,
        nargs="+",
    )
    parser.add_argument(
        "--no_table",
        help="Print plain text, don't use rich.table",
        action="store_true",
    )
    parser.add_argument("-v", "--verbose", help="Be verbose", action="store_true")
    values = parser.parse_args()
    logging_format = (
        "%(asctime)s - %(funcName)s -%(name)s - %(levelname)s - %(message)s"
    )

    if values.verbose:
        logging.basicConfig(
            level=logging.DEBUG,
            format=logging_format,
            handlers=[RichHandler(rich_tracebacks=True)],
        )
    else:
        logging.basicConfig(
            level=logging.INFO,
            format=logging_format,
            handlers=[RichHandler(rich_tracebacks=True)],
        )

    read_header(values.files, values.no_table)


import json
import boto3
from boto3.dynamodb.conditions import Key, Attr
"""
Allen changed Users table to User_new at 2:43AM 5/9/2022
"""
#always start with the lambda_handler
def lambda_handler(event, context):
    print(event)
    user_name = event['user_name']
    # make the connection to dynamodb
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
    # select the table
    table = dynamodb.Table("User_new")
    # get item from database
    item = table.get_item(Key={"user_name": user_name})
    # wishlist = item['Item']['wish_list']
    # print(item['Item']['wish_list'])
    return item


from utils.config import Config
import model
import dataset
import logging
import dataset.NIH_pretrain_dataset as dpd
from model.NIH_model import create_VGG_multioutput_imagenet,create_resnet_multioutput_imagenet,create_densenet_multioutput_imagenet,create_NASnet_multioutupt_imagenet, create_Xception_multioutput_imagenet

from train.pretrain_NIH import pretrain_NIH_chest
from tensorflow.keras.models import load_model

if __name__ == '__main__':

    # set up configuration
    configuration = Config()
    # after this logging.info() will print save to a specific file (global)!
    logging.info("configuration loaded")

    # prepare data
    logging.info("preparing train dataset")

    dataset = dpd.pretrain_dataset_NIH_chest(configuration)
    chest_dataset, chest_dataset_val = dataset.initialize_pipeline(imagenet = True)

    logging.info("datasets prepared")

    # create_VGG_multioutput_imagenet,create_resnet_multioutput_imagenet,create_densenet_multioutput_imagenet,"NIH_resnet_imagenet","NIH_densenet_imagenet",
    # "NIH_VGG_imagenet_max",
    for model_constr,name in zip([create_densenet_multioutput_imagenet],["NIH_densenet_imagenet"]):
        model = model_constr(configuration)

        #create_bigger_kernel_multioutput

        model.summary()
        # check if there is weights to load
        logging.info("model prepared")
        # train
        logging.info("starting training")
        pretrain_NIH_chest(model,chest_dataset,chest_dataset_val,configuration,name,epochs=101)

    # test the different image sizes imagenet
    configuration = Config()

    configuration.img_height = 299
    configuration.img_width = 299
    configuration.batch_size = 32
    dataset = dpd.pretrain_dataset_NIH_chest(configuration)
    chest_dataset, chest_dataset_val = dataset.initialize_pipeline(imagenet = True)

    model = create_Xception_multioutput_imagenet(configuration)

    model.summary()
    # check if there is weights to load
    logging.info("model prepared")
    # train
    logging.info("starting training")
    pretrain_NIH_chest(model,chest_dataset,chest_dataset_val,configuration,"NIH_Xception_imagenet",epochs=101)


import json
import getpass
import os
from datetime import datetime
import requests

today = datetime.today()
NAME = getpass.getuser()

# I would use the line below for macOS.
# with open(f"/Users/{NAME}/.data.json", "r") as data_file:
print('''  ╔╗ ╦╦  ╦  ╔═╗
  ╠╩╗║║  ║  ╚═╗
  ╚═╝╩╩═╝╩═╝╚═╝''')
print("**********************************************************")
print("new = New bill entry.")
print("query = List all the bill entries + bitcoin current price.")
print("delete = Delete a bill entry.")
print("total = List the total amount of all the bills.")
print("due = Displays the date that a bill is due.")
print("quit = Quit the application.")
print("**********************************************************")

def total():
    total = 0
    try:
        with open(f"/home/{NAME}/.data.json", "r") as data_file:
            data = json.load(data_file)

        for i in data:
            amounts = data[i]["amount"]
            amounts = float(amounts)
            total += amounts
        return (f"${format(total,'.2f')}")
    except FileNotFoundError:
        print("There are no bills entered.")

def lets_get_started():
    while True:
        user = input("What would you like to do? ")
        if user == "quit":
            break
        elif user == "new":
            company = input("Company name: ")
            amount = input("Amount Due: ")
            due_date = input("Due date: ")
            new_data = {
                company: {
                    "amount": amount,
                    "due_date": due_date,
                }
            }
            if len(company) == 0:
                print("Please make sure you haven't left any fields empty.")
            else:
                try:
                    with open(f"/home/{NAME}/.data.json", "r") as data_file:
                        # Reading old data
                        data = json.load(data_file)

                except FileNotFoundError:
                    with open(f"/home/{NAME}/.data.json", "w") as data_file:
                        # date_file is the location of where I will dump the new data
                        json.dump(new_data, data_file, indent=4)
                else:
                    # Updating old data with new data
                    data.update(new_data)

                    with open(f"/home/{NAME}/.data.json", "w") as data_file:
                        # Saving updated data
                        json.dump(data, data_file, indent=4)

        if user == "total":

            print(total())

        if user == "due":
            try:
                name = input("Please enter the company name: ")
                if len(name) == 0:
                    print("Please make sure you haven't left any fields empty.")
                else:

                    with open(f"/home/{NAME}/.data.json", "r") as data_file:
                        data = json.load(data_file)

                    due_dates = data[name]["due_date"]

                    print(
                        f"Your {name} payment is due on\n {today.month}/{due_dates}/{today.year}.")
            except FileNotFoundError:
                print("There are no bills entered.")
            except KeyError:
                print("Company name not found.")

        if user == "query":
            try:
                response = requests.get(
                    url="https://api.coindesk.com/v1/bpi/currentprice.json")
                response.raise_for_status()

                data_bitcoin = response.json()
                bitcoin = data_bitcoin['bpi']['USD']['rate_float']
                string = ''

                #name = company_e.get()
                with open(f"/home/{NAME}/.data.json", "r") as data_file:
                    data = json.load(data_file)
                for i in data:
                    string += f"{i} ${data[i]['amount']} on {today.month}/{data[i]['due_date']}/{today.year}\n"

                # \nBitcoin Price: ${round(bitcoin,2)}
                print(
                    f"{string}Total: {total()}\nBitcoin Price: ${round(bitcoin,2)}")
            except FileNotFoundError:
                print("There are no bills entered.")
        if user == "delete":
            wt_delete = input("Enter the company to be deleted: ")
            if len(wt_delete) == 0:
                print("Please make sure you haven't left any fields empty.")
            else:
                try:
                    with open(f"/home/{NAME}/.data.json", "r") as data_file:
                        # Reading old data
                        data = json.load(data_file)

                        data.pop(f"{wt_delete}")
                    with open(f"/home/{NAME}/.data.json", "w") as data_file:
                        # Saving updated data
                        json.dump(data, data_file, indent=4)

                except FileNotFoundError:
                    print("There is nothing to delete.")
                except KeyError:
                    print("Company name not found.")

def main():
    lets_get_started()

if __name__ == '__main__':
    main()


import pandas as pd

# source of dataset:(https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results)

INPUT_CSV = "country_centroids (1).csv"
OUTPUT_JSON = "centroids.json"

# Reading only Date, sex, age, from CSV
df = pd.read_csv(INPUT_CSV, usecols=["country", "latitude", "longitude",
                                     "name"], na_values=[''])

# # Changing data to make it usable
# df_gold = df.loc[df["Medal"].isin(["Gold", "Silver", "Bronze"])]
# df_summer = df_gold.loc[df["Season"] == "Summer"]

# Convert all data to JSON file
df.to_json(OUTPUT_JSON, orient="index")


from pythonds.basic import Stack
from pythonds.trees import BinaryTree

def buildParseTree(fpexp):
    fplist = fpexp.split()
    pStack = Stack()
    eTree = BinaryTree('')
    pStack.push(eTree)
    currentTree = eTree

    for i in fplist:
        if i == '(':
            currentTree.insertLeft('')
            pStack.push(currentTree)
            currentTree = currentTree.getLeftChild()

        elif i in ['+', '-', '*', '/']:
            currentTree.setRootVal(i)
            currentTree.insertRight('')
            pStack.push(currentTree)
            currentTree = currentTree.getRightChild()

        elif i == ')':
            currentTree = pStack.pop()

        elif i not in ['+', '-', '*', '/', ')']:
            try:
                currentTree.setRootVal(int(i))
                parent = pStack.pop()
                currentTree = parent

            except ValueError:
                raise ValueError("token '{}' is not a valid integer".format(i))

    return eTree

def printexp(tree):
    sVal = ""
    if tree:
        left = printexp(tree.getLeftChild())
        sVal = ('(' if left else '') + left
        sVal = sVal + str(tree.getRootVal())
        right = printexp(tree.getRightChild())
        sVal = sVal + right + (')' if right else '')
    return sVal

if __name__ == '__main__':
    pt = buildParseTree("( ( 10 + 5 ) * 3 )")
    # pt.inorder()  # defined and explained in the next section
    print(printexp(pt))


'''
5 5
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
'''
# input
N, M = map(int,input().split())
arr = [list(map(int,input().split())) for _ in range(N)]

# explore nearby

n = len(arr)
m = len(arr[0])

dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]

total = 0
sum_list = []
for x in range(n):
    for y in range(m):
        sum = 0
        for i in range(4):
            newx = x + dx[i]
            newy = y + dy[i]
            #if newx >= 0 and newx < N and newy >= 0 and newy < M:
            if newx <0 or newx >=5:continue
            if newy <0 or newy >=5:continue

            if arr[x][y] - arr[newx][newy] > 0:
                sum += arr[x][y] - arr[newx][newy]
            else:
                sum += arr[newx][newy] - arr[x][y]
        sum_list.append(sum)
        total += sum
print(total,sum_list)


# @Time: 2022/5/10 18:15
# @Author: chang liu
# @Email: chang_liu_tamu@gmail.com
# @File:tree-450-delete-node-in-a-BST.py

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return None
        if root.val == key:
            if not root.left:
                return root.right
            elif not root.right:
                return root.left
            else:
                ans = root.left
                ptr1 = ans.right
                ans.right = root.right
                ptr2 = ans.right
                if not ptr1: return ans
                while ptr2.left:
                    ptr2 = ptr2.left
                ptr2.left = ptr1
                return ans
        ptr = root
        former = None
        while ptr and ptr.val != key:
            former = ptr
            if ptr.val > key:
                ptr = ptr.left
            else:
                ptr = ptr.right

        if not ptr:
            return root
        if not ptr.left:
            if ptr is former.left:
                former.left = ptr.right
            else:
                former.right = ptr.right
        elif not ptr.right:
            if ptr is former.left:
                former.left = ptr.left
            else:
                former.right = ptr.left
        else:
            x = ptr.left
            y = ptr.right
            z = y
            while z.left:
                z = z.left
            if ptr is former.left:
                former.left = x
            else:
                former.right = x
            tem = x.right
            x.right = y
            z.left = tem
        return root


# 이진 힙
# 이진 최소힙 특징
# 1. 항상 완전 이진 트리를 유지하기 위해 마지막 노드 뒤에 새 노드 추가
# 2. 부모 노드의 값 < 자식 노드의 값
# 3. 노드 번호 차례로

for tc in range(int(input())):
    N = int(input())  # 노드의 개수
    tmp = list(map(int, input().split()))
    # 힙초기화
    heap = [-1] * (N+1)

    # 최소힙 순서대로 값 삽입
    last = 0
    for n in tmp:
        last += 1
        heap[last] = n
        position = last
        # 힙 조건 체크
        while position != 1 and heap[position//2] > n:  # 루트이거나 부모 노드가 작을 때까지
            # 바꾼다
            heap[position], heap[position // 2] = heap[position // 2], heap[position]
            position = position // 2

    # print(heap)
    # 마지막 노드의 조상 노드의 합
    sum = 0
    last_node_ances = N//2
    while last_node_ances >= 1:
        sum += heap[last_node_ances]
        last_node_ances //= 2
    print('#{} {}'.format(tc+1, sum))


from os import path

from libparse import Error, Head, Loc, Maybe, Result, Span, Spanned, SpanResult, Stream, Text
from typing import Callable, TypeVar
from sylex_ast import *

Chars = Stream[str]

def chars_of_raw(raw: str) -> Chars:
    text = Text(raw)
    loc = Loc(0, 0)
    chars: Chars = Stream.empty()
    for c in raw:
        chars.append(Span.unit(loc, text).with_data(c))
        if c == "\n":
            loc = loc.newline()
        else:
            loc = loc.newcol()
    return chars

class Blank:
    pass

Token = Symbol | Ident
Tokens = Stream[Token]
HToken = Head[Token]

def next_token(hd: Head[str]) -> Result[Token | Blank | None]:
    # About the return type
    #   Error -> something wrong happened
    #   None -> no more tokens
    #   Blank -> this is whitespace
    start = hd.span()
    read = hd.take()
    if read is None:
        return None

    if read == "<":
        # Left arrow
        # '<' '-'
        hd.bump()
        read = hd.peek()
        if read == "-":
            _ = hd.take()
            return Symbol.LEFT
        return hd.err("Unknown token", "'<' unterminated, expected '-' after", start)

    if read == "#":
        # Line comment
        # '#' [^'\n']* '\n'
        while True:
            hd.bump()
            read = hd.take()
            if read is None:
                return None
            if read == "\n":
                return Blank()

    if read in [" ", "\n", "\t"]:
        # Whitespace
        return Blank()

    if read == ":":
        # ':' ':'
        read1 = hd.peek(1)
        if read1 == ":":
            _ = hd.take(1)
            hd.bump()
            return Symbol.SCOPE
        # Else is a fallthrough: will be handled by 1-char symbols

    if read == "-":
        # '-' '>'
        read1 = hd.peek(1)
        if read1 == ">":
            _ = hd.take(1)
            hd.bump()
            return Symbol.RIGHT
        # Else is a fallthrough so that an identifier can still be caught

    # The following loop takes care of all 1-char symbols
    for sym in Symbol:
        if read == sym.value:
            return sym

    # Identifier contains 'a-z' or 'A-Z' or '-' '.' '_'
    # Can also take the form `'` ... `'` with escaped characters
    if isname(read):
        ident_chars = [read]
        while True:
            read = hd.peek(1)
            if read is None:
                break
            if not isname(read):
                break
            _ = hd.take(1)
            hd.bump()
            ident_chars.append(read)
        return Ident.concat(ident_chars)

    if read != "'":
        return hd.err(
            "Unknown token", "character does not begin any valid token", start
        )

    ident_chars = []
    while True:
        read = hd.peek(1)
        if read is None:
            # premature EOF
            return hd.err(
                "Unterminated literal",
                "`'` opened but unclosed before end of file",
                start,
            )
        if read == "\\":
            # escape next character
            hd.bump()
            read = hd.peek(1)
            if read is None:
                return hd.err("Unterminated escape", "'\\' at end of file", start)
            ident_chars.append(read)
        elif read == "'":
            # end literal
            hd.bump()
            break
        else:
            # default is a single normal character
            hd.bump()
            ident_chars.append(read)

    return Ident.concat(ident_chars)

def tokens_of_chars(chars: Chars) -> Result[Tokens]:
    # Call next_token repeatedly until the whole stream is consumed
    toks: Tokens = Stream.empty()
    hd = Head.start(chars)

    while True:
        fwd = hd.clone()
        print(f"Enter: {fwd.peek()}")
        res = next_token(fwd)
        print(f"Exit: {fwd.peek()}")
        print(f"With: {res}")
        print()

        if isinstance(res, Error):
            inner = res
            if inner.span is None:
                inner.span = hd.until(fwd)
                print(hd.span(), fwd.span(), hd.until(fwd))
            return inner

        if res is None:
            break

        elif isinstance(res, Blank):
            fwd.bump()
            hd.commit(fwd)
            continue

        else:
            spanned = hd.until(fwd).with_data(res)
            toks.append(spanned)
            fwd.bump()
            hd.commit(fwd)

    return toks

U = TypeVar("U")
def ast_of_tokens(tokens: Tokens, target: Callable[[HToken], Result[U]]) -> SpanResult[U]:
    hd = Head.start(tokens)
    start = hd.span()
    res: SpanResult[U] = hd.sub(target)
    read = hd.peek()
    if read is None:
        return res
    else:
        return Error("Extra text", f"expected end of file, found {read}", hd.until(start), None)
    return res

def parse_deflist(hd: HToken) -> Result[DefList]:
    # DefList := Def *
    start = hd.span()
    defs: list[Spanned[Def] | Spanned[Target]] = []
    while True:
        read = hd.peek()
        if read is None:
            break
        elif read == Symbol.DECLARE:
            item_def: SpanResult[Def] = hd.sub(parse_def)
            if isinstance(item_def, Error):
                return item_def
            print(item_def)
            defs.append(item_def)
        elif read == Symbol.OPENBRACK:
            item_target: SpanResult[Target] = hd.sub(parse_target)
            if isinstance(item_target, Error):
                return item_target
            print(item_target)
            defs.append(item_target)
        else:
            return hd.err("Unknown token", "expected '$' or '['", start)
    return DefList(defs)

def parse_def(hd: HToken) -> Result[Def]:
    # Def := '$' Ident '=' ItemList ';'
    start = hd.span()

    # '$'
    read = hd.take()
    if read != Symbol.DECLARE:
        return hd.err("Invalid Def", "expect a Def to start with a '$'", start)
    hd.bump()

    # Ident
    read = hd.take()
    if not isinstance(read, Ident):
        return hd.err("Invalid Def", "'$' should be followed by a name", start)

    # TODO: Waiting mypy 0.940
    name: Spanned[Ident] = hd.span().with_data(read)
    hd.bump()

    # '='
    read = hd.take()
    if read != Symbol.EQUAL:
        return hd.err("Invalid Def", "expected an '=' sign", start)
    hd.bump()

    # ItemList
    val: SpanResult[ItemList] = hd.sub(parse_itemlist)
    if isinstance(val, Error):
        return val
    value = val

    # ';'
    read = hd.take()
    if read != Symbol.SEMI:
        return hd.err("Invalid Def", "expected ';' at the end", start)
    hd.bump()

    return Def(name, value)

def parse_itemlist(hd: HToken) -> Result[ItemList]:
    # ItemList := '{' Item ','* '}'
    #           | Item
    start = hd.span()
    read = hd.peek()
    if read is None:
        return hd.err(
            "Invalid ItemList", "EOF reached while trying to read a list", start
        )

    if read != Symbol.OPENBRACE:
        # did not start with a '{' so it should be a single Item
        obj: SpanResult[Expand | Maybe[Item]] = hd.sub(parse_item)
        if isinstance(obj, Error):
            return obj

        # TODO: Waiting mypy 0.940
        if isinstance(obj.data, Expand):
            return ItemList([obj.span.with_data(obj.data)])
        else:
            return ItemList([obj.span.with_data(obj.data.data)])

    # Case of '{' Item ','* '}'
    _ = hd.take()
    hd.bump()
    # TODO: list[Spanned[Item|Expand]]
    lst: list[Spanned[Item | Expand]] = []
    latest_error = None
    while True:
        read = hd.peek()
        if read is None:
            return hd.err(
                "Invalid ItemList", "EOF reached while trying to read a list", start
            )
        if read == Symbol.CLOSEBRACE:
            # Reached the closing '}'
            _ = hd.take()
            hd.bump()
            return ItemList(lst)
        # otherwise read an Item then maybe a ','
        # if no ',' then it has to stop afterwards
        item: SpanResult[Expand | Maybe[Item]] = hd.sub(parse_item)
        if isinstance(item, Error):
            return item

        # TODO: Waiting mypy 0.940
        if isinstance(item.data, Expand):
            data: Expand | Item = item.data
        else:
            data = item.data.data
        lst.append(item.span.with_data(data))

        read = hd.peek()
        if read is None:
            if latest_error is not None:
                return latest_error
            return hd.err("Invalid ItemList", "unclosed '{' before EOF", start)
        if read == Symbol.COMMA:
            _ = hd.take()
            hd.bump()
        else:
            # No trailing comma, it should be the end
            if read != Symbol.CLOSEBRACE:
                if latest_error is not None:
                    return latest_error
                return hd.err(
                    "Invalid ItemList",
                    "expected '}' after no trailing comma",
                    start,
                )
            # (next iteration will take care of actually returning)

def parse_item(hd: HToken) -> Result[Expand | Maybe[Item]]:
    # Item := '$' Ident
    #       | Entry
    #       | Entry '::' ItemList
    start = hd.span()
    # if it starts with a '$' then it's an expansion
    read = hd.peek()
    if read == Symbol.DECLARE:
        _ = hd.take()
        hd.bump()
        read = hd.take()
        if not isinstance(read, Ident):
            return hd.err("Invalid expansion", "expected identifier after '$'", start)

        # TODO: Waiting mypy 0.940
        ident: Spanned[Ident] = hd.span().with_data(read)
        hd.bump()
        return Expand(ident)

    # otherwise it should be an Entry
    entry: SpanResult[Maybe[Entry]] = hd.sub(parse_entry)
    if isinstance(entry, Error):
        return entry
    # optionally '::' then ItemList
    read = hd.peek()
    if read != Symbol.SCOPE:
        return Maybe(Item(entry.map(lambda x: x.data), None), entry.data.diagnostic)
    _ = hd.take()
    hd.bump()
    tail: SpanResult[ItemList] = hd.sub(parse_itemlist)
    if isinstance(tail, Error):
        return tail
    return Maybe(Item(entry.map(lambda x: x.data), tail), entry.data.diagnostic)

def parse_entry(hd: HToken) -> Result[Maybe[Entry]]:
    # Entry := Ident Tag*
    start = hd.span()
    # Ident
    read = hd.take()
    if not isinstance(read, Ident):
        return hd.err("Invalid Entry", "should start with an Ident", start)

    # TODO: Waiting mypy 0.940
    name: Spanned[Ident] = hd.span().with_data(read)
    hd.bump()

    entry = Entry.from_name(name)
    # list of Tag
    while True:
        print(f"next: {hd.peek()}")
        read = hd.peek()
        if read not in [Symbol.LEFT, Symbol.RIGHT, Symbol.COLON]:
            err = hd.err(
                "Expected tag marker",
                f"tags should begin with '<-' or '->' or ':', not '{hd.peek()}'",
                start,
            )
            return Maybe(entry, err)
        tag: SpanResult[Tag] = hd.sub(parse_tag)
        if isinstance(tag, Error):
            return tag
        entry.push(tag)

def parse_tag(hd: HToken) -> Result[Tag]:
    start = hd.span()
    # '<-' or ':' or '->'
    read = hd.take()
    if read not in [Symbol.LEFT, Symbol.RIGHT, Symbol.COLON]:
        return hd.err(
            "Invalid Tag", "should start with either ':', '<-' or '->'", start
        )
    symbol = read
    hd.bump()

    # Ident
    read = hd.take()
    if not isinstance(read, Ident):
        return hd.err("Invalid Tag", "should have a name", start)

    # TODO: Waiting mypy 0.940
    name: Spanned[Ident] = hd.span().with_data(read)
    hd.bump()

    # If there are params they start with '('
    read = hd.peek()
    if read != Symbol.OPENPAREN:
        params = hd.span().with_data(Params([]))
    else:
        read_params: SpanResult[Params] = hd.sub(parse_params)
        if isinstance(read_params, Error):
            return read_params
        else:
            params = read_params
    # decide type of return value depending on value of symbol
    if symbol == Symbol.COLON:
        return Label(name, params)
    elif symbol == Symbol.LEFT:
        return Induce(name, params)
    else:
        return Depend(name, params)

def parse_params(hd: HToken) -> Result[Params]:
    start = hd.span()
    # Start with '('
    read = hd.take()
    if read != Symbol.OPENPAREN:
        return hd.err("Invalid Params", "should start with '('", start)
    hd.bump()
    inner: list[Spanned[Ident]] = []
    # Comma-separated list of Idents
    while True:
        read = hd.take()
        if read is None:
            return hd.err("Invalid Params", "unclosed '(' at end of file", start)

        if read == Symbol.CLOSEPAREN:
            hd.bump()
            return Params(inner)

        if isinstance(read, Ident):
            # TODO: Waiting mypy 0.940
            inner.append(hd.span().with_data(read))
            hd.bump()

            read = hd.peek()
            if read is None:
                return hd.err("Invalid Params", "unclosed '(' at end of file", start)
            if read == Symbol.COMMA:
                _ = hd.take()
                hd.bump()
            elif read != Symbol.CLOSEPAREN:
                return hd.err("Invalid Params", "expected ',' or ')'", start)

        # (next iteration will return)

def parse_target(hd: HToken) -> Result[Target]:
    # Target := '[' Ident ']' ';'
    start = hd.span()
    # '['
    read = hd.take()
    if read != Symbol.OPENBRACK:
        return hd.err("Invalid Target", "should begin with '['", start)
    hd.bump()

    # Ident
    read = hd.take()
    if not isinstance(read, Ident):
        return hd.err("Invalid Target", "should have a name", start)

    # TODO: Waiting mypy 0.940
    name = hd.span().with_data(read)
    hd.bump()

    # ']'
    read = hd.take()
    if read != Symbol.CLOSEBRACK:
        return hd.err("Invalid Target", "target name should be followed by ']'", start)
    hd.bump()

    # ';'
    read = hd.take()
    if read != Symbol.SEMI:
        return hd.err("Invalid Target", "should be ended by ';'", start)
    hd.bump()

    return Target(name)

def main(raw: str, target: Callable[[HToken], Result[U]]) -> SpanResult[U]:
    chars = chars_of_raw(raw)
    toks = tokens_of_chars(chars)
    if isinstance(toks, Error):
        return toks
    ast = ast_of_tokens(toks, target)
    if isinstance(ast, Error):
        return ast
    return ast

if __name__ == "__main__":
    with open("sylex.conf") as f:
        raw = f.read()
    print(main(raw, parse_deflist))


import gc
import gzip
import os
import platform
import re
import shlex
import shutil
import struct
import subprocess
import time
from datetime import datetime
from functools import partial, wraps
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple, Union
from warnings import warn

import pytz
import zstandard
from loguru import logger

from .disk_usage import DiskUsage
from .config import config

def get_local_time_timezone(timezone="Asia/Riyadh"):
    # Get the current time in UTC
    current_time_utc = datetime.now(pytz.utc)

    # Convert to San Francisco's time zone (PST/PDT)
    sf_time_zone = pytz.timezone(timezone)
    local_time = current_time_utc.astimezone(sf_time_zone)

    # You may format it as you desire, including AM/PM
    formatted_time = local_time.strftime("%Y-%m-%d %I:%M:%S %p %Z%z")

    return formatted_time

def get_local_time(timezone=None):
    if timezone is not None:
        return get_local_time_timezone(timezone)
    else:
        # Get the current time, which will be in the local timezone of the computer
        local_time = datetime.now()

        # You may format it as you desire, including AM/PM
        formatted_time = local_time.strftime("%Y-%m-%d %I:%M:%S %p %Z%z")

        return formatted_time

def force_free_memory():
    """Forces Python's garbage collector to free unused memory.

    Returns:
        int: The number of bytes freed.
    """

    gc.collect()
    return gc.get_stats()[0]

def deprecated(func=None, *, message=None):
    """This is a decorator which can be used to mark functions as deprecated.
    It will result in a warning being emitted when the function is used."""

    if func is None:
        return partial(deprecated, message=message)

    @wraps(func)
    def new_func(*args, **kwargs):
        if message:
            warn(
                message,
                category=DeprecationWarning,
                stacklevel=2,
            )
        else:
            warn(
                f"Call to deprecated function {func.__name__}.",
                category=DeprecationWarning,
                stacklevel=2,
            )
        return func(*args, **kwargs)

    return new_func

def run_command(
        arg: List[Union[str, Path]],
        env: Optional[Dict[str, str]] = None,
        verbose: bool = True,
        capture_output: bool = True,
        **kwargs: Any,
) -> Tuple[str, int]:
    """
    Runs the given command and returns the output.

    Parameters:
        arg (List[Union[str, Path]]): The command represented as a list of strings or Path objects.
        verbose (bool): Whether the commands should be shown. Default True.
        capture_output (bool): Whether to capture the command's output. Default True.
        env (Dict[str, str]): A dictionary of additional environment variables. Default None.
        kwargs (Any): Any additional arguments to be passed to subprocess.run(), such as stdin, etc. stdout and stderr will default to subprocess.PIPE unless the caller specifies any of them.

    Returns:
        Tuple[str, int]: A tuple containing two elements:
            - The output of the command if capture_output is True, else an empty string.
            - The exit code of the command.

    Raises:
        subprocess.CalledProcessError: If the command exits with a non-zero return code.
        KeyboardInterrupt: If the execution is interrupted by Ctrl+C.
        Exception: If any other exception occurs.
    """
    start_time = time.time()

    # Convert all elements in arg to string
    arg = [str(a) for a in arg]

    if env is not None:
        logger.info("Env: {}", env)
        env_copy = os.environ.copy()
        env_copy.update(env)
        kwargs.setdefault("env", env_copy)

    if verbose:
        logger.info(f"Running: {shlex.join(arg)}")

    if capture_output:
        kwargs.setdefault("stdout", subprocess.PIPE)
        kwargs.setdefault("stderr", subprocess.PIPE)
        kwargs.setdefault("universal_newlines", True)

    try:
        proc = subprocess.run(arg, **kwargs, check=True)
        output = proc.stdout if capture_output else ""
    except subprocess.CalledProcessError as exc:
        logger.error(
            f"Failed to run command '{arg}' (exit code {exc.returncode}):\n{exc.output}"
        )
        raise
    except KeyboardInterrupt as exc:
        logger.info("\nTerminating...")
        raise SystemExit(1) from exc
    except Exception as exc:
        logger.exception(f"Failed to run command '{arg}': {exc}")
        raise SystemExit(1) from exc

    runtime = time.time() - start_time
    if verbose:
        logger.info(f"Execution time: {runtime} seconds")

    return output, proc.returncode

def get_environment_variable(name: str) -> Tuple[Optional[str], List[str]]:
    """
    Retrieves the value of the specified environment variable. This function is compatible with both Windows and Unix-based systems.

    Parameters:
        name (str): The name of the environment variable to retrieve.

    Returns:
        Tuple[Optional[str], List[str]]: A tuple containing two elements:
            - The value of the environment variable if it exists, None otherwise.
            - A list of error messages, if any occurred during the retrieval process.

    Raises:
        Exception: If there is a failure in retrieving the environment variable on Windows due to reasons other than the variable not being found.
    """
    error_messages = []

    if platform.system() == "Windows":
        from ctypes import FormatError, wintypes

        value = ""
        req_size = wintypes.DWORD()
        gev_failure = 0
        win32_api_error = 0

        def write_last_error(error_code: int, message: str, name: str) -> None:
            """Prints an error message for a given error code."""
            error_messages.append(f"{message} {name}: {FormatError(error_code)}")

        # Try to get the size of the environment variable value
        if ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0) == gev_failure:
            win32_api_error = ctypes.GetLastError()
            if win32_api_error == 203:  # ERROR_ENVVAR_NOT_FOUND
                error_messages.append(f"No environment variable by the name '{name}'")
                return None, error_messages
            else:
                write_last_error(
                    win32_api_error, "Failed to get size for environment variable", name
                )
                raise Exception(f"Failed to get environment variable: {name}")
        else:
            # Get the value of the environment variable
            req_size = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
            value = ctypes.create_unicode_buffer(req_size)
            if (
                    ctypes.windll.kernel32.GetEnvironmentVariableW(name, value, req_size)
                    == gev_failure
            ):
                write_last_error(
                    ctypes.GetLastError(), "Failed to get environment variable", name
                )
                raise Exception(f"Failed to get environment variable: {name}")
        return value.value, error_messages
    else:
        # Get the value of the environment variable on Unix-based systems
        value = os.environ.get(name)
        if value is None:
            error_messages.append(f"No environment variable by the name '{name}'")
        return value, error_messages

def create_directory(dir_name: Path) -> int:
    """
    Creates a directory and its parent directories if they do not exist.

    Parameters:
        dir_name (Path): The name of the directory to create.

    Returns:
        int: 0 if the directory was created successfully, 1 if it already exists, -1 if an error occurred.

    Raises:
        PermissionError: If the user does not have permission to create the directory.
        OSError: If an error occurs while creating the dire
    """
    # if isinstance(dir_name, str):
    dir_name = Path(dir_name)

    try:
        if dir_name.exists():
            logger.info(f"Directory already exists: {dir_name}")
            return 1

        os.makedirs(dir_name)
        logger.info(f"Directory created: {dir_name}")
        return 0
    except FileExistsError:
        logger.info(f"Directory already exists: {dir_name}")
        return 1
    except PermissionError as e:
        logger.error(f"Permission denied while creating directory: {dir_name}")
        logger.exception(str(e))
        return -1
    except OSError as e:
        logger.error(f"Error creating directory: {dir_name}")
        logger.exception(str(e))
        return -1

def remove(path: Path) -> int:
    """
    Removes a file or directory.

    Parameters:
        path (Path): The path of the file or directory to be removed.

    Returns:
        int: 0 if the file or directory was successfully removed, 1 if it does not exist, -1 if an error occurred.

    Raises:
        PermissionError: If the user does not have permission to remove the file or directory.
        OSError: If an error occurs while removing the file or directory.
    """
    # if isinstance(path, str):
    path = Path(path)

    try:
        if path.is_file():
            # Remove a file
            if path.exists():
                os.remove(path)
                logger.info(f"File '{path}' successfully removed.")
                return 0
            else:
                logger.info(f"File '{path}' does not exist.")
                return 1
        elif path.is_dir():
            # Remove a directory
            if path.exists():
                shutil.rmtree(path)
                logger.info(f"Directory '{path}' successfully removed.")
                return 0
            else:
                logger.info(f"Directory '{path}' does not exist.")
                return 1
        else:
            logger.info(f"Path '{path}' is neither a file nor a directory.")
            return 1
    except FileNotFoundError:
        logger.info(f"File or directory '{path}' does not exist.")
        return 1
    except PermissionError as e:
        logger.error(f"Permission denied while removing '{path}': {e}")
        return -1
    except OSError as e:
        logger.error(f"Error while removing '{path}': {e}")
        return -1

def copy_file(src: Union[str, Path], dst: Union[str, Path]) -> None:
    """
    Copies a file from the source path to the destination path while displaying a progress bar.
    If the user interrupts the process (e.g., by pressing ctrl + c), the program exits gracefully and removes the partially copied file.

    Parameters:
        src (Path): The source file path.
        dst (Path): The destination file path.

    Returns:
        None

    Raises:
        KeyboardInterrupt: If the user interrupts the process, it raises this exception to exit gracefully and remove the partially copied file.
    """
    src = Path(src)
    dst = Path(dst)

    try:
        # Get the size of the source file
        file_size = src.stat().st_size
        # Open the source file in binary mode for reading
        with src.open("rb") as fsrc:
            # Open the destination file in binary mode for writing
            with dst.open("wb") as fdst:
                # Create a progress bar using tqdm
                with tqdm(
                        total=file_size,
                        unit="B",
                        desc=f"Copying ({src.name})",
                        unit_scale=True,
                        unit_divisor=1024,
                        ncols=shutil.get_terminal_size().columns,
                ) as pbar:
                    # Read the source file in chunks of 1024 bytes
                    while True:
                        buf = fsrc.read(1024)
                        # If we have reached the end of the file, stop reading
                        if not buf:
                            break
                        # Write the chunk to the destination file
                        fdst.write(buf)
                        # Update the progress bar
                        pbar.update(len(buf))
    except KeyboardInterrupt:
        # If the user presses ctrl + c, exit gracefully
        print("\nTerminating...")
        remove(dst)
        exit(0)

def copy_folder(src: Path, dst: Path) -> None:
    """
    Copies a folder and its contents from the source path to the destination path while displaying a progress bar.
    If the user interrupts the process (e.g., by pressing ctrl + c), the program exits gracefully.

    Parameters:
        src (Path): The source folder path.
        dst (Path): The destination folder path.

    Returns:
        None

    Raises:
        KeyboardInterrupt: If the user interrupts the process, it raises this exception to exit gracefully.
    """
    src = Path(src)
    dst = Path(dst)

    try:
        # Calculate the total size of all files in the source folder
        total_size = 0
        for dirpath, dirnames, filenames in os.walk(src):
            for f in filenames:
                fp = Path(dirpath, f)
                total_size += fp.stat().st_size

        # Create a progress bar using tqdm
        with tqdm(
                total=total_size, unit="B", unit_scale=True, unit_divisor=1024
        ) as pbar:
            # Walk through all subdirectories and files in the source folder
            for dirpath, dirnames, filenames in os.walk(src):
                # Create the corresponding destination directory path
                dst_dirpath = Path(dst, os.path.relpath(dirpath, src))
                # If the destination directory does not exist, create it
                if not dst_dirpath.exists():
                    os.makedirs(dst_dirpath)
                # Copy each file from the source to the destination directory
                for f in filenames:
                    src_file = Path(dirpath, f)
                    dst_file = Path(dst_dirpath, f)
                    # Open the source file in binary mode for reading
                    with src_file.open("rb") as fsrc:
                        # Open the destination file in binary mode for writing
                        with dst_file.open("wb") as fdst:
                            # Read the source file in chunks of 1024 bytes
                            while True:
                                buf = fsrc.read(1024)
                                # If we have reached the end of the file, stop reading
                                if not buf:
                                    break
                                # Write the chunk to the destination file
                                fdst.write(buf)
                                # Update the progress bar
                                pbar.update(len(buf))
    except KeyboardInterrupt:
        # If the user presses ctrl + c, exit gracefully
        print("\nTerminating...")
        exit(0)

def dir_size(path: str, verbose_mode: bool = False) -> int:
    """
    Calculates the size of a directory or file in bytes.

    This function uses the `DiskUsage` class to calculate the size of a directory or file on the host system. The size is calculated based on a 1K block size.

    Parameters:
        path (str): The path of the directory or file to calculate the size of.
        verbose_mode (bool): If True, prints the path being calculated. Default is False.

    Returns:
        int: The size of the directory or file in bytes.
    """
    if verbose_mode:
        logger.info(f"Calculating size of {path}")

    return int(DiskUsage().calc_disk_usage(path=path, is_top_level=False))

def count(directory: Path) -> int:
    """
    Returns the count of files and directories in the specified directory.

    Parameters:
        directory (Path): The directory to calculate the count on.

    Returns:
        int: The number of files and directories.

    Raises:
        FileNotFoundError: If the specified directory does not exist.
    """
    directory = Path(directory)

    if not directory.exists():
        raise FileNotFoundError(
            f"The specified directory '{directory}' does not exist."
        )

    count = sum([len(files) + len(dirs) for _, dirs, files in os.walk(directory)])
    return count

def cat(
        in_file: Optional[str] = None, msg: Optional[str] = None, out_file: str = None
) -> None:
    """
    Writes the contents of the input file or a message into the output file.

    Parameters:
        in_file (str, optional): The path to the input file. Default is None.
        msg (str, optional): The message to write to the file. Default is None.
        out_file (str): The path to the output file.

    Raises:
        FileNotFoundError: If the input file does not exist.
        PermissionError: If the program does not have permission to read from the input file or write to the output file.
        OSError: If an error occurs while reading from the input file or writing to the output file.
    """
    if out_file is None:
        raise FileNotFoundError("The output file must be specified.")

    try:
        with open(out_file, "a", encoding="UTF-8") as output_file:
            if in_file is not None:
                with open(in_file, "r", encoding="UTF-8") as input_file:
                    output_file.write(input_file.read())
            if msg is not None:
                output_file.write(f"{msg}\n")
    except FileNotFoundError as e:
        print(f"Input file not found: {e}")
    except PermissionError as e:
        print(
            f"Permission denied while reading from input file or writing to output file: {e}"
        )
    except OSError as e:
        print(
            f"Error occurred while reading from input file or writing to output file: {e}"
        )

def init_folders(project: str) -> None:
    """
    Initialize project folders.

    This function creates a set of folders for a given project, as specified in the configuration file.

    Parameters:
        project (str): The name of the project for which to create the folders.

    Raises:
        FileNotFoundError: If the configuration file could not be found.
        PermissionError: If the program does not have permission to create the directories.
        OSError: If an error occurs while creating the directories.
    """
    try:
        # Load the list of folders to create from the configuration file
        folders: List[str] = config.load_config("MAIN", "proj_folders").split(" ")

        # Iterate over each folder in the list
        for folder in folders:
            # Create the full path to the folder by joining the project and folder names
            folder_path = Path(project).joinpath(folder)

            # Create the directory and its parents if they do not exist
            create_directory(folder_path)
    except FileNotFoundError as e:
        print(f"Configuration file not found: {e}")
    except PermissionError as e:
        print(f"Permission denied while creating directories: {e}")
    except OSError as e:
        print(f"Error occurred while creating directories: {e}")

def list_folder(folder_name: Path) -> dict:  # type: ignore
    """
    Lists the contents of a folder.

    This function returns a dictionary containing the contents of the specified folder.

    Parameters:
        folder_name (Path): The name of the folder to list.

    Returns:
        dict: A dictionary containing the contents of the specified folder, where the keys are integers and the values are strings representing the names of the files or directories in the folder.

    Raises:
        FileNotFoundError: If the specified folder does not exist.
        PermissionError: If the program does not have permission to access the specified folder.
        OSError: If an error occurs while accessing the specified folder.
    """
    folder_name = Path(folder_name)

    try:
        if not folder_name.exists():
            logger.error("No Projects directory found.")
            raise FileNotFoundError(f"No such directory: {folder_name}")

        directory_list = os.listdir(folder_name)
        # Create a dictionary from the list of projects
        dict_projects = {}
        for i, proj in enumerate(directory_list):
            dict_projects[i + 1] = proj
        logger.info(
            "List of projects:\n"
            + "\n".join(
                [f"\t{key:<4}: {value}" for key, value in dict_projects.items()]
            )
        )
        return dict_projects
    except FileNotFoundError as e:
        print(f"Folder not found: {e}")
    except PermissionError as e:
        print(f"Permission denied while accessing directory: {e}")
    except OSError as e:
        print(f"Error occurred while accessing directory: {e}")

def init_project(prj_name: str) -> None:
    """
    Initialize a project with the given name.

    This function creates a new project with the given name, or overwrites an existing project with the same name if the user confirms.

    Parameters:
        prj_name (str): The name of the project to create.

    Raises:
        FileNotFoundError: If the configuration file could not be found.
        PermissionError: If the program does not have permission to create or delete directories.
        OSError: If an error occurs while creating or deleting directories.
    """
    try:
        # Log the project name
        logger.info(f"Project Name: {prj_name}")

        # Update the configuration file with the main project path
        data = {"main_project": Path("Projects", prj_name)}
        config.update_config("MAIN", data)

        # Construct the full path to the project directory
        project_path = Path("Projects", prj_name)

        # Check if the project directory already exists
        if project_path.is_dir():
            # Log a warning message
            logger.warning("This project exists")

            # Prompt the user for confirmation to overwrite the existing project
            choice = input(
                "If you want to continue, this will delete the existing project [y/n]: "
            )

            # If the user confirms, delete the existing project and initialize a new one
            if choice.lower() == "y":
                logger.info(f"Removing project {project_path}")
                remove(project_path)
                init_folders(config.load_config("MAIN", "main_project"))

            # If the user does not confirm, initialize a new project without deleting the existing one
            else:
                init_folders(config.load_config("MAIN", "main_project"))

        # If the project directory does not exist, initialize a new project
        else:
            init_folders(config.load_config("MAIN", "main_project"))

        # Update the configuration file with the main project path
        data = {"main_project": Path("Projects", prj_name)}
        config.update_config("MAIN", data)
    except FileNotFoundError as e:
        print(f"Configuration file not found: {e}")
    except PermissionError as e:
        print(f"Permission denied while creating or deleting directories: {e}")
    except OSError as e:
        print(f"Error occurred while creating or deleting directories: {e}")

def replace_in_file(filename: Path, pattern: str, repl: str) -> None:
    """
    Replaces occurrences of a pattern in a file with a replacement string.

    Parameters:
        filename (Path): The name of the file to perform the replacement on.
        pattern (str): The pattern to search for in the file.
        repl (str): The string to replace the pattern with.

    Raises:
        FileNotFoundError: If the specified file does not exist.
        PermissionError: If the program does not have permission to read from or write to the specified file.
        OSError: If an error occurs while reading from or writing to the specified file.
    """
    # Ensure that filename is a Path object
    # if isinstance(filename, str):
    filename = Path(filename)

    try:
        with open(filename, encoding="UTF-8") as file:
            lines = file.readlines()

        with open(filename, "w", encoding="UTF-8") as file:
            for line in lines:
                file.write(re.sub(pattern, repl, line))
    except FileNotFoundError as e:
        print(f"File not found: {e}")
    except PermissionError as e:
        print(f"Permission denied while reading from or writing to file: {e}")
    except OSError as e:
        print(f"Error occurred while reading from or writing to file: {e}")

def find_text_in_file(filename: Path, text: str, sep: str = ":", level: int = 1) -> str:
    """
    Find a specific text in a file and return a specific part of the line where the text is found.

    Parameters:
        filename (Path): The path of the file to search in.
        text (str): The text to search for in the file.
        sep (str, optional): The separator used to split the line. Defaults to ':'.
        level (int, optional): The index of the split part to return. Defaults to 1.

    Returns:
        str or None: The specified part of the line where the text is found, or None if the text is not found.

    Raises:
        FileNotFoundError: If the specified file does not exist.
        IndexError: If the level index is out of range for the split line.
        UnicodeDecodeError: If the file cannot be decoded using UTF-8.
    """
    # Ensure that filename is a Path object
    # if isinstance(filename, str):
    filename = Path(filename)

    try:
        # Check if the file exists
        if not filename.is_file():
            raise FileNotFoundError(f"No such file: '{filename}'")

        # Open the file using a context manager
        with filename.open("r", encoding="UTF-8") as file:
            # Iterate over each line in the file
            for line in file:
                # Check if the text is present in the line
                if text in line:
                    # Split the line and return the specified level of the split
                    return line.split(sep)[level].strip()

        # Return None if the text is not found
        return None
    except FileNotFoundError as e:
        print(f"File not found: {e}")
    except IndexError as e:
        print(f"Level index out of range for split line: {e}")
    except UnicodeDecodeError as e:
        print(f"File cannot be decoded using UTF-8: {e}")

def check_sparse(input_img: Path) -> bool:
    """
    Check if the image is sparse.

    Parameters:
        input_img (Path): The path to the image file.

    Returns:
        bool: True if the image is sparse, False otherwise.

    Raises:
        FileNotFoundError: If the specified image file does not exist.
        PermissionError: If the program does not have permission to read from the specified image file.
        OSError: If an error occurs while reading from the specified image file.
    """
    # if isinstance(input_img, str):
    input_img = Path(input_img)

    try:
        # Read the first 28 bytes of the image file
        with input_img.open("rb") as f:
            header_bin = f.read(28)

        # Unpack the binary data into variables
        header = struct.unpack("<I4H4I", header_bin)
        magic = header[0]

        # Check if the magic number matches the expected value
        if magic == 0xED26FF3A:
            return True
        else:
            return False
    except FileNotFoundError as e:
        print(f"Image file not found: {e}")
    except PermissionError as e:
        print(f"Permission denied while reading from image file: {e}")
    except OSError as e:
        print(f"Error occurred while reading from image file: {e}")

def create_gzip(input_file: Path, out_gzip: Path) -> None:
    """
    Create a gzip file from an existing file.

    Parameters:
        input_file (Path): The path to the input file.
        out_gzip (Path): The path to the output gzip file.

    Raises:
        FileNotFoundError: If the input file does not exist.
        PermissionError: If the program does not have permission to read from the input file or write to the output gzip file.
        OSError: If an error occurs while reading from the input file or writing to the output gzip file.
    """
    # if isinstance(input_file, str):
    input_file = Path(input_file)
    # elif isinstance(out_gzip, str):
    out_gzip = Path(out_gzip)

    try:
        # Ensure that the output file has a .gz extension
        out_gzip = out_gzip if out_gzip.suffix == ".gz" else f"{out_gzip}.gz"

        # Compress the input file to the output gzip file
        with input_file.open("rb") as f_in, gzip.open(out_gzip, "wb") as f_out:
            shutil.copyfileobj(f_in, f_out)
    except FileNotFoundError as e:
        print(f"Input file not found: {e}")
    except PermissionError as e:
        print(
            f"Permission denied while reading from input file or writing to output gzip file: {e}"
        )
    except OSError as e:
        print(
            f"Error occurred while reading from input file or writing to output gzip file: {e}"
        )

def create_zstd(input_file: Path, out_zstd: Path) -> None:
    """
    Compresses a file with zstd.

    Parameters:
        input_file (Path): The path to the input file.
        out_zstd (Path): The path to the output file.

    Raises:
        FileNotFoundError: If the input file does not exist.
        PermissionError: If the program does not have permission to read from the input file or write to the output file.
        OSError: If an error occurs while reading from the input file or writing to the output file.
    """
    # if isinstance(input_file, str):
    input_file = Path(input_file)
    # elif isinstance(out_zstd, str):
    out_zstd = Path(out_zstd)

    try:
        # Add .zst to the previous suffix of the output file
        out_zstd = out_zstd.with_suffix(out_zstd.suffix + ".zst")

        logger.info(f"Compress [{input_file}] to [{out_zstd}]")

        # create a zstd compressor object with multithreading enabled
        cctx = zstandard.ZstdCompressor(threads=-1)

        # open the input and output files in binary mode
        with input_file.open("rb") as input_f, out_zstd.open("wb") as output_f:
            # create a stream reader object that compresses data on the fly
            reader = cctx.stream_reader(input_f)
            # copy the data from the reader to the output file
            shutil.copyfileobj(reader, output_f)
    except FileNotFoundError as e:
        print(f"Input file not found: {e}")
    except PermissionError as e:
        print(
            f"Permission denied while reading from input file or writing to output file: {e}"
        )
    except OSError as e:
        print(
            f"Error occurred while reading from input file or writing to output file: {e}"
        )

def get_rom_info(output_dir: Path) -> Tuple[str, str, str]:
    """
    Returns the ROM type, incremental version, and security patch level of a ROM.

    This method reads the build.prop files in the output directory to determine the ROM type, incremental version, and security patch level of a ROM.

    Parameters:
        output_dir (Path): The path to the output directory containing the build.prop files.

    Returns:
        tuple: A tuple containing the ROM type (str), incremental version (str), and security patch level (str) of the ROM.

    Raises:
        FileNotFoundError: If any of the build.prop files are not found.
        ValueError: If the ROM type, incremental version, or security patch level cannot be determined.

    """
    # Define the path to the system build.prop file
    build_prop_file = Path(output_dir, "system", "system", "build.prop")

    # Attempt to open and read the system build.prop file
    try:
        with build_prop_file.open() as f:
            lines = f.readlines()
    except FileNotFoundError as exc:
        raise FileNotFoundError(f"Could not find file: {build_prop_file}") from exc

    # Initialize variables for storing the extracted incremental version and security patch level
    incremental = None
    security_patch = None

    # Extract incremental version and security patch level
    for line in lines:
        if line.startswith("ro.system.build.version.incremental="):
            incremental = line.split("=")[1].strip()
        elif line.startswith("ro.build.version.security_patch="):
            security_patch = line.split("=")[1].strip()

        if incremental and security_patch:
            break

    # If either the incremental version or security patch level could not be determined, raise an error
    if not incremental or not security_patch:
        raise ValueError(
            "Could not determine incremental version or security patch level"
        )

    # Define a dictionary mapping build properties to ROM types
    rom_types = {
        "ro.miui.ui.version.name": "MIUI",
        "ro.build.version.opporom": "ColorOS",
        "ro.build.version.EMUI": "EMUI",
        "ro.build.version.samsung": "One UI",
        "ro.build.version.release": "AOSP",
        "lineageos": "LineageOS",
    }

    # Define a list of paths to other build.prop files to search for the ROM type
    build_prop_files = [
        Path(output_dir, "product", "etc", "build.prop"),
        Path(output_dir, "vendor", "build.prop"),
        Path(output_dir, "system", "system", "build.prop"),
        Path(output_dir, "system_ext", "etc", "build.prop"),
        Path(output_dir, "odm", "etc", "build.prop"),
    ]

    # Initialize a variable for storing the detected ROM type
    rom_type = None

    # Iterate over each build.prop file in the list of paths
    for file in build_prop_files:
        # Attempt to open and read the current build.prop file
        try:
            with open(file, encoding="utf-8") as f:
                for line in f:
                    for prop, name in rom_types.items():
                        if line.startswith(prop):
                            rom_type = name
                            break
                    if rom_type:
                        break
        except FileNotFoundError:
            continue
        if rom_type:
            break

    # If no ROM type could be determined, raise an error
    if not rom_type:
        raise ValueError("Could not determine ROM type")

    return rom_type, incremental, security_patch


import pygame
import sys
import csv
import copy
import time

pygame.init()

WIDTH = 800
HEIGHT = 600
COLOR = (0,101,149)

screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Sudoku')
title_font = pygame.font.Font('MachineGunk-nyqg.ttf',80)
path_font = pygame.font.Font('MachineGunk-nyqg.ttf',15)
inp_font = pygame.font.SysFont('calibri',12)

menu_bg = pygame.image.load('bg.jpg')
title = title_font.render('Sudoku',False,COLOR)
path = path_font.render('Enter Puzzle path :',False,COLOR)
inp_txt = ''
inp_field = pygame.Rect(80,280,300,15)
menu_flag = True

def empty(puzzle):
    empties = []
    for i in range(len(puzzle)):
        for j in range(len(puzzle)):
            if puzzle[i][j]=='0':
                empties.append((i,j))
    return empties

def menu():
    inp = inp_font.render(inp_txt, False, 'White')
    screen.blit(menu_bg, (0, 0))
    screen.blit(title, (80, 180))
    screen.blit(path, (80, 260))
    screen.blit(inp, (85, 282.5))
    pygame.draw.rect(screen, 'White', inp_field, 2)

def board(puzzle):
    board_origin = (200,100)
    tile_size = 40

    for i in range(len(puzzle)):
        for j in range(len(puzzle)):
            rect = pygame.Rect(
                board_origin[0] + j*tile_size,
                board_origin[1] + i* tile_size,
                tile_size, tile_size
            )
            pygame.draw.rect(screen,'White',rect,3)
            if puzzle[i][j]!='0':
                cell = path_font.render(puzzle[i][j],True,COLOR)
                cellRect = cell.get_rect()
                cellRect.center = rect.center
                screen.blit(cell,cellRect)

def revise(puzzle):
    maps = {}
    rank = []
    empties = empty(puzzle)
    for cell in empties:
        domain= list(range(1,10))
        maps[cell] = list(range(1,10))
        (i,j) = cell
        vert = [puzzle[a][j] for a in range(len(puzzle))]
        i_start = (i//3)*3
        j_start = (j//3)*3
        grid = [puzzle[c][b] for c in range(i_start,i_start+3) for b in range(j_start,j_start+3)]
        for val in domain:
            if str(val) in puzzle[i]:
                maps[cell].remove(val)
            elif str(val) in vert:
                maps[cell].remove(val)
            elif str(val) in grid:
                maps[cell].remove(val)
        rank_cell = len(maps[cell])
        if rank_cell==0:
            return (maps,False)
        if len(rank)==0:
            rank.append(cell)
        for r in range(len(rank)):
            if len(maps[rank[r]])>rank_cell:
                if cell not in rank:
                    rank = rank[:r]+[cell]+rank[r:]
        if cell not in rank:
            rank.append(cell)

    return (maps,rank)

def backtrack(puzzle,rank,maps):
    domains = copy.deepcopy(maps)
    empties = empty(puzzle)
    if len(empties)==0:
        return puzzle
    cell = rank[0]
    (i,j) = cell
    domain = copy.deepcopy(maps[cell])
    for val in domain:
        maps = copy.deepcopy(domains)
        puzzle[i][j] = str(val)
        out = revise(puzzle)
        if out[-1]==False:
            puzzle[i][j] = '0'
            maps[cell].remove(val)
            continue
        solved = backtrack(puzzle,out[-1],out[0])
        if solved!=False:
            return solved
        puzzle[i][j] = '0'
        maps[cell].remove(val)
    maps = domains
    return False

def solve(puzzle):
    (maps,rank) = revise(puzzle)
    #if rank==False:
    solved = backtrack(puzzle,rank,maps)
    return solved

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_BACKSPACE:
                inp_txt = inp_txt[:-1]
            else:
                if len(inp_txt)<=45:
                    inp_txt += event.unicode
        if event.type == pygame.KEYDOWN:
            if event.key == 13:
                try:
                    with open(inp_txt.strip()) as file:
                        f = csv.reader(file)
                        puzzle = []
                        for row in f:
                            puzzle.append(row)
                    menu_flag = False
                except:
                    pass
            if event.key == pygame.K_q:
                menu_flag = True
    if menu_flag:
        menu()
    else:
        screen.fill((35, 31, 32))
        board(puzzle)
        time.sleep(3)
        puzzle = solve(puzzle)

    pygame.display.update()


'''
Nomenclature of variables:
Lillicrap, Timothy P, Hunt, Jonathan J, Pritzel, Alexander, Heess, Nicolas, Erez, Tom, Tassa,
Yuval, Silver, David, and Wierstra, Daan. Continuous control with deep reinforcement learning.
'''
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras.optimizers import Adam
from buffer import ReplayBuffer
from networks import ActorNetwork, CriticNetwork

class Agent:
    # alpha = learning rate for actor network
    # beta = learning rate for critic network
    # gamma = discount factor for update equation
    # max_size = maximum size of replay buffer
    # tau = update factor for target networks
    def __init__(self, input_dims, alpha=0.001, beta=0.002, env=None,
                 gamma=0.99, n_actions=2, max_size=1000000, tau=0.005,
                 fc1=400, fc2=300, batch_size=64, noise=0.1):
        self.gamma = gamma
        self.tau = tau
        self.memory = ReplayBuffer(max_size, input_dims, n_actions)
        self.batch_size = batch_size
        self.n_actions = n_actions
        self.noise = noise
        self.max_action = env.action_space.high[0]
        self.min_action = env.action_space.low[0]

        self.actor = ActorNetwork(n_actions=n_actions, name='actor')
        self.critic = CriticNetwork(name='critic')
        self.target_actor = ActorNetwork(n_actions=n_actions,
                                         name='target_actor')
        self.target_critic = CriticNetwork(name='target_critic')

        self.actor.compile(optimizer=Adam(learning_rate=alpha))
        self.critic.compile(optimizer=Adam(learning_rate=beta))
        self.target_actor.compile(optimizer=Adam(learning_rate=alpha))
        self.target_critic.compile(optimizer=Adam(learning_rate=beta))

        self.update_network_parameters(tau=1)

    def update_network_parameters(self, tau=None):
        # base case: if we don't supply a value for tau, we use tau = 1
        if tau is None:
            tau = self.tau

        # lines 16, 17, 18 from the paper
        weights = []
        targets = self.target_actor.weights
        for i, weight in enumerate(self.actor.weights):
            weights.append(weight * tau + targets[i] * (1 - tau))
        self.target_actor.set_weights(weights)

        weights = []
        targets = self.target_critic.weights
        for i, weight in enumerate(self.critic.weights):
            weights.append(weight * tau + targets[i] * (1 - tau))
        self.target_critic.set_weights(weights)

    # function to store transitions in the replay buffer
    def remember(self, state, action, reward, new_state, done):
        self.memory.store_transition(state, action, reward, new_state, done)

    def save_models(self):
        print('... saving models ...')
        self.actor.save_weights(self.actor.checkpoint_file)
        self.target_actor.save_weights(self.target_actor.checkpoint_file)
        self.critic.save_weights(self.critic.checkpoint_file)
        self.target_critic.save_weights(self.target_critic.checkpoint_file)

    def load_models(self):
        print('... loading models ...')
        self.actor.load_weights(self.actor.checkpoint_file)
        self.target_actor.load_weights(self.target_actor.checkpoint_file)
        self.critic.load_weights(self.critic.checkpoint_file)
        self.target_critic.load_weights(self.target_critic.checkpoint_file)

    # evaluate is a flag used to choose between TESTING the agent or TRAINING the agent
    def choose_action(self, observation, evaluate=False):

        state = tf.convert_to_tensor([observation], dtype=tf.float32)
        actions = self.actor(state)
        # If we are training... = if we are not evaluating
        if not evaluate:
            # add some Gaussian noise to the action set
            actions += tf.random.normal(shape=[self.n_actions],
                                        mean=0.0, stddev=self.noise)
        # note that if the env has an action > 1, we have to multiply by
        # max action at some point
        # we clip it here so that we guarantee we are not passing any illegal action to the environment.
        actions = tf.clip_by_value(actions, self.min_action, self.max_action)

        # in a tensor, the zeroth element is the value of the tensor
        return actions[0]
    # if the memory is not full enough to be batched, don't batch. This means we are not learning anything, but we are
    # waiting for the memory to get full enough.
    def learn(self):
        if self.memory.mem_counter < self.batch_size:
            return

        state, action, reward, new_state, done = self.memory.sample_buffer(self.batch_size)

        states = tf.convert_to_tensor(state, dtype=tf.float32)
        states_ = tf.convert_to_tensor(new_state, dtype=tf.float32)
        rewards = tf.convert_to_tensor(reward, dtype=tf.float32)
        actions = tf.convert_to_tensor(action, dtype=tf.float32)

        # the GradientTape records operations for automatic differentiation.
        # Code below follows line 13, 14, and 15 of the DDPG algorithm

        # For the Critic
        with tf.GradientTape() as tape:
            target_actions = self.target_actor(states_)
            critic_value_ = tf.squeeze(self.target_critic(states_, target_actions), 1)
            critic_value = tf.squeeze(self.critic(states, actions), 1)
            # (1 - done) = (1 - boolean value). Done can be 1 (last episode) or 0 (keep updating the target)
            target = rewards + self.gamma * critic_value_ * (1 - done)
            critic_loss = keras.losses.MSE(target, critic_value)
        # trainable_variables come from the fact that we derive our Critic/Network class from the
        # keras Network class
        critic_network_gradient = tape.gradient(critic_loss,
                                                self.critic.trainable_variables)
        # The zip() function returns a zip object, which is an iterator of tuples where the first item in each
        # passed iterator is paired together, and then the second item in each passed iterator are paired together etc.
        self.critic.optimizer.apply_gradients(zip(
            critic_network_gradient, self.critic.trainable_variables))
        # For the actor Loss
        with tf.GradientTape() as tape:
            new_policy_actions = self.actor(states)
            # the loss is negative, because we are trying to maximize the total score.
            # By default, we do gradient descent but with the minus sign, it becomes gradient ascent.
            actor_loss = -self.critic(states, new_policy_actions)
            # tf.math.reduce_mean = computes the mean of elements across dimensions of a tensor.
            actor_loss = tf.math.reduce_mean(actor_loss)

        actor_network_gradient = tape.gradient(actor_loss,
                                               self.actor.trainable_variables)
        self.actor.optimizer.apply_gradients(zip(
            actor_network_gradient, self.actor.trainable_variables))

        # soft update of target networks
        self.update_network_parameters()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 18 18:51:16 2019

@author: anishumesh
"""

import pandas as pd

df=pd.read_csv('/Users/anishumesh/Downloads/Picking-dishes-from-Yelp-master/triples.csv')
food_reviews = df.groupby('restaurant_id').agg({'menu_item':','.join,'text': 'first','review_rating':'first','review_date':'first','user_name':'first' }).reset_index()

#VADER
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
analyser = SentimentIntensityAnalyzer()
sentiment = food_reviews['text'].apply(lambda x: analyser.polarity_scores(x))
food_reviews = pd.concat([food_reviews,sentiment.apply(pd.Series)],1)


#請先將selenium版本設定為3.141.0版
# !pip install selenium == 3.141.0

# 操作 browser 的 API
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 處理逾時例外的工具
from selenium.common.exceptions import TimeoutException

from selenium.common.exceptions import ElementNotInteractableException

# 面對動態網頁，等待某個元素出現的工具，通常與 exptected_conditions 搭配
from selenium.webdriver.support.ui import WebDriverWait

# 搭配 WebDriverWait 使用，對元素狀態的一種期待條件，若條件發生，則等待結束，往下一行執行
from selenium.webdriver.support import expected_conditions as EC

# 期待元素出現要透過什麼方式指定，通常與 EC、WebDriverWait 一起使用
from selenium.webdriver.common.by import By

from selenium.common.exceptions import NoSuchElementException

# 強制等待 (執行期間休息一下)
from time import sleep

# 執行 command 的時候用的
import os

from selenium.webdriver.support.ui import Select

def web_setting(foldername):
    # 啟動瀏覽器工具的選項
    my_options = webdriver.ChromeOptions()
    my_options.add_argument("--start-maximized")         #最大化視窗
    my_options.add_argument("--incognito")               #開啟無痕模式
    my_options.add_argument("--disable-popup-blocking") #禁用彈出攔截
    my_options.add_argument("--disable-notifications")  #取消 chrome 推播通知
    my_options.add_argument("--lang=zh-TW")  #設定為正體中文
    # 建立儲存檔案的資料夾
    folderPath = foldername
    if not os.path.exists(folderPath):
        os.makedirs(folderPath)

    # os.getcwd()為抓到當前目錄的路徑，windows的路徑會用\做分隔，但在Python裡\為跳脫字元，所以下面要放\\
    fullDownloadPath = os.getcwd() + '\\' + folderPath

    # 設定WebDriver的行為，"prefs"為偏好設定
    my_options.add_experimental_option("prefs", {

        # 將fullDownloadPath的路徑設定為默認下載檔案會放的路徑
        "download.default_directory": fullDownloadPath,

        # 可以設定要不要禁用詢問如何處理下載的提示。
        "download.prompt_for_download": False,

        # 在訪問危險網站或下載危險文件時，不會收到任何警告(須確定網頁是否安全再關閉這個功能)
        "safebrowsing.enabled": False,
    })

    # 使用 Chrome 的 WebDriver(請先到https://chromedriver.chromium.org/downloads下載與自己Chrome版本相符的chromedriver)
    # 將driver_path變更為chromedriver.exe的所在路徑
    driver_path = r'C:\\Users\\Ethen\\GitHub程式\\iSpan_BDSE30_final_project\\weather_wep_scraping\\chromedriver.exe'
    driver = webdriver.Chrome(executable_path=driver_path, options=my_options)

    return driver

# 走訪頁面
def visit():
    driver.get('https://e-service.cwb.gov.tw/HistoryDataQuery/DayDataController.do?command=viewMain&station=467770&stname=%25E6%25A2%25A7%25E6%25A3%25B2&datepicker=2013-01-01&altitude=31.73m')

# 手動或其他原因停止執行此方法
def visit1(url):
    #將網址會成停止的日期的測站網址
    driver.get(url)

# 將csv下載下來
def download_weather_csv(stop_point):
    error = False
    try:
        # 等待元素出現
        WebDriverWait(driver, 10).until(
            EC.presence_of_element_located(
                (By.CSS_SELECTOR, "select#selectStno")
            )
        )

        # 找到下拉式選單元素
        select_element = driver.find_element(By.CSS_SELECTOR, "select#selectStno")

        # 創建 Select 對象
        select = Select(select_element)

        # 獲取下拉式選單的選項数量
        options_count = len(select.options)

        sleep(1)

        #如果停止將0變為停止的數字
        for j in range(stop_point,options_count+1):
            print(j)
            # 等待元素出現
            WebDriverWait(driver, 10).until(
                EC.presence_of_element_located(
                    (By.CSS_SELECTOR, "select#selectStno")
                )
            )

            # 找到下拉式選單元素
            select_element = driver.find_element(By.CSS_SELECTOR, "select#selectStno")

            # 創建 Select 對象
            select = Select(select_element)

            # 選擇選項
            select.select_by_index(j)

            while True:
                try:
                    url = driver.current_url
                    # 等待CSV下載的按件出現
                    WebDriverWait(driver, 10).until(
                        EC.presence_of_element_located(
                            (By.CSS_SELECTOR, "a#downloadCSV input")
                        )
                    )

                    # 點擊CSV下載的按件
                    driver.find_element(
                        By.CSS_SELECTOR,
                        "a#downloadCSV input"
                    ).click()

                # 等待下一天的按件出現
                    WebDriverWait(driver, 10).until(
                        EC.presence_of_element_located(
                            (By.CSS_SELECTOR, "a#nexItem input")
                        )
                    )
                    # 點擊下一天的按件
                    driver.find_element(
                        By.CSS_SELECTOR,
                        "a#nexItem input"
                    ).click()

                except ElementNotInteractableException:
                    break

            driver.get('https://e-service.cwb.gov.tw/HistoryDataQuery/DayDataController.do?command=viewMain&station=467770&stname=%25E6%25A2%25A7%25E6%25A3%25B2&datepicker=2013-01-01&altitude=31.73m')

            sleep(1)

        not_done = False

    except TimeoutException:
        error = True
        print("等待逾時")

    return error ,url, j, not_done

    # 最一開始執行的主程式
# if __name__ == '__main__':
#     visit()
#     download_weather_csv(0)

# 停止後主程式
if __name__ == '__main__':
    # 放入想建立的資料夾名稱
    driver = web_setting("台中市天氣")
    stop_point = 0
    #"放入要爬的縣市網址"
    url = 'https://e-service.cwb.gov.tw/HistoryDataQuery/DayDataController.do?command=viewMain&station=467770&stname=%25E6%25A2%25A7%25E6%25A3%25B2&datepicker=2013-01-01&altitude=31.73m'
    not_done = True
    visit1(url)
    while not_done:
        error_stop, stop_url, stop_point, not_done = download_weather_csv(stop_point)
        if error_stop == True:
            visit1(stop_url)
            error_stop, stop_url, stop_point, not_done = download_weather_csv(stop_point)


import time
import turtle

#Δημιουργία λίστας λέξεων

words = ['programming','supernatural','ability','malfunction','virus']
splited_words = []
for i in range(len(words)):
    letters = []
    for j in words[i]:
        letters.append(j)
    splited_words.append(letters)

#-Εκκίνηση αντίστροφης μέτρησης πριν αρχήσει το παιχνίδι-
#-Εμ΄φανιση μηνυμάτων στην αρχή και στο τέλος παιχνιδιού-
#-Κλήση word_generator-

def timer():
    for i in range(3,0,-1):
        print("GAME STARTS IN",i)
        time.sleep(1)
    else:
        print("GAME STARTED...")
        word_generator(words)
        print("GAME OVER...")

#-Όταν ο χρήστης καταφέρνει να βρει κάποια λέξη καλείται να βρει την επόμενη της λίστας words-
#-Ορισμός λίστας hidden_word η οποία εμφανίζει "_" για κάθε γράμμα της λέξης που δεν έχει βρει ο χρήστης-
#-Οριμός λίστας chosen_word με τη λέξη που πρέπει να βρει ο χρήστης-
#-Κινήσεις turtle-
#-Κλήση της word_guessing-
#-Ειδοποίηση του χρήστη όταν βρει όλες τις λέξεις που υπάρχουν στη λίστα words και στην εναλλαγή λέξεων-

def word_generator(words):
    k = 0
    while k < len(words):
        chosen_word = words[k]
        hidden_word = []
        for i in words[k]:
            hidden_word.append("_")
        for i in range(len(hidden_word)):
            if i == len(hidden_word) - 1:
                print("_")
            else:
                print("_",end=" ")
        word_guessing(chosen_word,hidden_word,10)
        if k == len(words) - 1:
            turtle.goto(425,-360)
            print("Congratulations, you found all the words! You have reached the point.")
            break
        else:
            print("Prepare for the next word...")
            time.sleep(2)
            k += 1
            if k == 1:
                turtle.goto(-250,310)
            elif k == 2:
                turtle.goto(-180,240)
            elif k == 3:
                turtle.goto(100,-80)
            else:
                turtle.goto(230,-250)

#-Καταχώρηση γραμμάτων από τον χρήστη προκειμένου να βρει τη λέξη-
#-Περιορισμός προσπαθειών με τη μεταβλητή tries-

def word_guessing(chosen_word,hidden_word,tries):
    while True:
        flag = False
        if chosen_word == hidden_word:
            print("Congratulations!")
            print("You found the word:")
            for i in range(len(hidden_word)):
                if i == len(hidden_word) - 1:
                    print(hidden_word[i])
                else:
                    print(hidden_word[i],end="")
            break
        elif tries == 0:
            print("You are out of tries... Better luck next time!")
            break
        letter = str(input("Guess a letter of the word: "))
        for i in range(len(chosen_word)):
            if letter == hidden_word[i]:
                flag = True
                print("You have already found this letter, guess another one!")
                break
            if letter == chosen_word[i]:
                hidden_word[i] = chosen_word[i]
                flag = True
                print("Correct letter!")
                for characters in range(len(hidden_word)):
                    if characters == len(hidden_word) - 1:
                        print(hidden_word[characters])
                    else:
                        print(hidden_word[characters],end=" ")
        if flag == False:
            tries -= 1
            print("Wrong letter...")
            print(tries,"Tries remaining...")
            continue

#-Σχεδιασμός του σημείου στο οποίο το turtle προσεγγίζει όλο και περισσότερο με την εύρεση κάθε λέξης-

def turtle_point_drawing():
    print("Find all the words to reach the point!")
    turtle.penup()
    turtle.goto(455,-390)
    turtle.left(90)
    turtle.pendown()
    for i in range(4):
        turtle.forward(30)
        turtle.left(90)
    for i in range(3):
        turtle.forward(30)
        turtle.left(90)
        turtle.forward(5)
        turtle.left(90)
        turtle.forward(30)
        turtle.right(90)
        turtle.forward(5)
        turtle.right(90)
    else:
        turtle.right(90)
    for i in range(3):
        turtle.forward(30)
        turtle.left(90)
        turtle.forward(5)
        turtle.left(90)
        turtle.forward(30)
        turtle.right(90)
        turtle.forward(5)
        turtle.right(90)
    turtle.penup()
    turtle.goto(-455,390)
    turtle.pendown()

#-Τρέξιμο του προγράμματος-

turtle_point_drawing()
timer()


import re
import json

f = open('jawiki-country.json','r',encoding='utf-8')
for line in f:
    f_data = json.loads(line)
    if f_data['title'] =='イギリス':
        target = f_data['text']

pattern = r'\|(.+?)\s=\s*(.+)'
result = dict(re.findall(pattern,target,re.MULTILINE))

result_s = {}
for i,j in result.items():
    pattern = r'\'{2,5}'
    match = re.sub(pattern,'',j)
    result_s[i] = match
print(result_s)
'''
{'略名 ': 'イギリス', '日本語国名': 'グレートブリテン及び北アイルランド連合王国', '公式国名': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:
', '国旗画像': 'Flag of the United Kingdom.svg', '国章画像': '[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]', '国章リンク': '（[[イギリスの国章|国章]]）', '標語': '{{lang|fr|[[Dieu et mon droit]]}}
（[[フランス語]]:[[Dieu et mon droit|神と我が権利]]）', '国歌': '[[女王陛下万歳|{{lang|en|God Save the Queen}}]]{{en icon}}
神よ女王を護り賜え
{
'''