from django.urls import include, path
from rest_framework.routers import DefaultRouter
from .views import TagViewSet, RecipeViewSet, IngredientsViewSet, FollowViewSet

app_name = 'api'

router = DefaultRouter()

router.register('tags', TagViewSet, basename='tags')
router.register('recipes', RecipeViewSet, basename='recipes')
router.register('ingredients', IngredientsViewSet, basename='ingredients')
router.register('users', FollowViewSet, basename='users')

urlpatterns = [
    # Все зарегистрированные в router пути доступны в router.urls
    # Включены в головной urls.py
    path('', include(router.urls)),
    # Работа с пользователями:
    path('', include('djoser.urls')),
    # Работа с токенами:
    path('auth/', include('djoser.urls.authtoken')),
]


#!/usr/bin/env python3
# flake8: noqa
import argparse
from json import JSONDecodeError
from botocore.exceptions import ClientError

import boto3
import json
import logging
import os
import subprocess
import requests

import sys

logger = logging.getLogger()
ecs_client = boto3.client('ecs')
ecr_client = boto3.client('ecr')
webhook_url = os.environ.get('ECS_DEPLOYER_WEBHOOK_URL')

class DockerImage:
    def __init__(self, name, dockerfile, tagCommand, repository, build) -> None:
        self.name = name
        self.dockerfile = dockerfile
        self.tag_command = tagCommand
        self.repository = repository
        self.build = build

    @property
    def tag(self) -> str:
        try:
            return self._tag
        except AttributeError:
            self._tag = run_command(self.tag_command, shell=True).strip()
            return self._tag

    @property
    def tagged_name(self) -> str:
        return '{}:{}'.format(self.name, self.tag)

    @property
    def tagged_repo_name(self) -> str:
        return '{}:{}'.format(self.repository, self.tag)

    def build_image(self) -> None:
        run_command(['docker', 'build', '-t', self.tagged_name, '-f', self.dockerfile, '.'])
        run_command(['docker', 'tag', self.tagged_name, self.tagged_repo_name])

    def tag_image(self) -> None:
        run_command(['docker', 'tag', self.name, self.tagged_repo_name])

    def push(self) -> None:
        run_command(['docker', 'push', self.tagged_repo_name])

    def delete_local(self) -> None:
        run_command(['docker', 'rmi', self.tagged_name])

    def handle(self, keep_image, force_push_image) -> str:
        try:
            response = ecr_client.describe_images(repositoryName=self.repository.split('/')[1], imageIds=[{'imageTag': self.tag}])
            image_exists = len(response['imageDetails'])
        except ClientError:
            image_exists = False

        if not image_exists or force_push_image:
            if self.build:
                self.build_image()
            else:
                self.tag_image()
            self.push()

            if self.build and not keep_image:
                self.delete_local()
        else:
            print("Image {} exists, skipping.".format(self.tagged_repo_name))
        return self.tagged_repo_name

    def __str__(self) -> str:
        return "<Docker Image> - {}".format(self.name)

class TaskDefinition:
    def __init__(self, name, config) -> None:
        self.name = name
        self.config = config
        self.revision = None

    @property
    def deregister_previous_definitions(self) -> bool:
        return self.config.get('deregisterPreviousDefinitions', True)

    @property
    def family(self) -> str:
        return self.config['family']

    @property
    def task_role_arn(self) -> str:
        return self.config.get('taskRoleArn')

    @property
    def network_mode(self) -> str:
        return self.config.get('networkMode', 'bridge')

    @property
    def container_definitions(self) -> list:
        return self.config['containerDefinitions']

    @property
    def volumes(self) -> list:
        return self.config.get('volumes', [])

    @property
    def placement_constraints(self) -> list:
        return self.config.get('placementConstraints', [])

    def update_environment(self, envs) -> None:
        json_envs = [{"name": key, "value": value} for key, value in envs.items()]
        for container_def in self.container_definitions:
            if 'environment' in container_def:
                container_def['environment'] += json_envs
            else:
                container_def['environment'] = json_envs

    def set_images(self, images) -> None:
        for container_def in self.container_definitions:
            container_def['image'] = images[container_def['image']]

    def deregister_existing_definitions(self) -> None:
        if not self.revision:
            return
        definitions = ecs_client.list_task_definitions(familyPrefix=self.family)['taskDefinitionArns']

        for definition in definitions:
            if definition.split(':')[-1] != str(self.revision):
                ecs_client.deregister_task_definition(taskDefinition=definition)

    def register(self) -> str:
        print("Registering task definition: '{}'".format(self.family))
        result = ecs_client.register_task_definition(
            family=self.family,
            taskRoleArn=self.task_role_arn,
            networkMode=self.network_mode,
            containerDefinitions=self.container_definitions,
            volumes=self.volumes,
            placementConstraints=self.placement_constraints,
        )
        self.revision = result['taskDefinition']['revision']

        return '{}:{}'.format(self.family, self.revision)

    def deregister(self) -> None:
        if self.revision is not None:
            ecs_client.deregister_task_definition(taskDefinition='{}:{}'.format(self.family, self.revision))

    def __str__(self) -> str:
        return "<TaskDefinition> - {}".format(self.name)

class Task:
    def __init__(self, name, config) -> None:
        self.name = name
        self.config = config

    def run(self):
        print("Running task: '{}'".format(self.name))
        ecs_client.run_task(**self.config)

    def handle(self):
        self.run()

    def __str__(self) -> str:
        return "<Task> - {}".format(self.name)

class Service:
    def __init__(self, name, config) -> None:
        self.name = name
        self.config = config

    @property
    def cluster(self):
        return self.config['cluster']

    def update(self) -> None:
        print("Updating service: '{}'".format(self.name))
        ecs_client.update_service(service=self.name, **self.config)

    def handle(self):
        self.update()

    def __str__(self) -> str:
        return "<Service> - {}".format(self.name)

def run_command(command, ignore_error=False, silent=False, **kwargs) -> str:
    """f
    :param command: Command as string or tuple of args.
    :param ignore_error: Fail silently.
    :param silent: Do not log command execution.
    :return:
    """
    if not isinstance(command, (list, tuple)):
        command = (command,)

    if not silent:
        print('Running command: %s' % ' '.join(command))

    try:
        stdout = subprocess.check_output(command, **kwargs)
        return stdout.decode()
    except subprocess.CalledProcessError as e:
        if not ignore_error:
            print('Command failed: %s', str(e), file=sys.stderr)
            raise

def docker_login() -> None:
    cmd = run_command(['aws', 'ecr', 'get-login', '--no-include-email']).rstrip('\n').split(' ')
    run_command(cmd)

def get_json(file_path, fail_silently=False):
    try:
        with open(file_path, 'rt') as f:
            return json.loads(f.read())
    except:
        if fail_silently:
            return {}
        else:
            raise

def verify_config_files(config_dir):
    config_data = {}
    skipped_files = []
    invalid_files = []

    for conf_type in ('images', 'task_definitions', 'tasks', 'services', 'envs'):
        try:
            config_data[conf_type] = get_json(os.path.join(config_dir, '{}.json'.format(conf_type)))
        except FileNotFoundError:
            config_data[conf_type] = {}
            skipped_files.append(conf_type)
        except JSONDecodeError:
            invalid_files.append(conf_type)

    if skipped_files:
        logger.warning("Config files skipped (not found): {}".format(skipped_files))
    if invalid_files:
        raise ValueError("Invalid configuration files: {}".format(invalid_files))

    return config_data

def send_webhook_message(config_dir, success):
    if webhook_url is not None:
        if success:
            text = "Successfully deployed configuration `{}`.".format(config_dir)
            color = 'good'
        else:
            text = "Failed to deploy configuration `{}`.".format(config_dir)
            color = 'danger'

        try:
            tag, message = run_command(['git', 'log', '--oneline', '-1'], silent=True).strip().split(" ", 1)
            text += '\n`{}` {}'.format(tag, message)
        except:
            pass

        data = {'attachments': [
            {
                'fallback': text,
                'color': color,
                'text': text,
                'mrkdwn_in': ['text']
            }
        ]}
        requests.post(webhook_url, data=json.dumps(data), headers={'Content-Type': 'application/json'})

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description="Build and/or deploy Docker image to specified repo and update services/task definitions.")
    parser.add_argument('env', help='Path to config directory')
    parser.add_argument('-f', '--force-push-image', action='store_true', help='Push image even if tag exists in ecr.')
    parser.add_argument('-k', '--keep-image', action='store_true', help='Keep dockers image after pushing.')
    parser.add_argument('--skip-stash', action='store_true', help='Keep dockers image after pushing.')
    args = parser.parse_args()

    stashed = False
    if not args.skip_stash:
        # Stash changes so the deploy actually sends out correct code.
        try:
            stashed = run_command(['git', 'stash']).strip() != 'No local changes to save'
        except subprocess.CalledProcessError:
            pass

    config_dir = os.path.abspath(args.env)
    try:
        config_data = verify_config_files(config_dir)
    except:
        send_webhook_message(args.env, False)
        sys.exit(1)

    success = False

    try:
        docker_images = {}
        updated_task_definitions = []

        docker_login()

        # Handling docker containers based on config file.
        print("\nPreparing docker images...")
        for name, image_config in config_data['images'].items():
            image = DockerImage(name, **image_config)
            docker_images[name] = image.handle(args.keep_image, args.force_push_image)

        try:
            # Handling task definitions based on config file.
            print("\nUpdating task definitions...")
            for name, task_def_config in config_data['task_definitions'].items():
                task_def = TaskDefinition(name, task_def_config)
                task_def.update_environment(config_data['envs'])
                task_def.set_images(docker_images)
                task_def.register()
                updated_task_definitions.append(task_def)
        except:
            print("\nError updating task definitions, deregistering!")
            for task_def in updated_task_definitions:
                task_def.deregister()
        else:
            for task_def in updated_task_definitions:
                task_def.deregister_existing_definitions()

            # Handling one-time tasks
            print("\nRunning one-time tasks...")
            for name, task_config in config_data['tasks'].items():
                task_def = Task(name, task_config)
                try:
                    task_def.handle()
                except Exception as e:
                    logger.warning("Unable to run task {name}: {error}".format(name=name, error=str(e)))

            # Handling services based on config file
            print("\nUpdating services...")
            for name, service_config in config_data['services'].items():
                service = Service(name, service_config)
                service.handle()

            success = True
    finally:
        if stashed:
            run_command(['git', 'stash', 'pop'])
        send_webhook_message(args.env, success)


import os
from enum import Enum

import pyxel
import Box2D
from Box2D import b2

import main
import scenes

PPM = 16.0  # pixels per meter
TARGET_FPS = 30
TIME_STEP = 1.0 / TARGET_FPS
SCREEN_WIDTH, SCREEN_HEIGHT = 224, 126
SCREEN_Y_ZERO_OFFSET = 120
STAGE_WIDTH_M = 70  # m
STAGE_ITEMEND_X_M = 67  # ここまでしかものが置かない

SCREEN_WIDTH_M = int(SCREEN_WIDTH/PPM)
SCREEN_HIGHT_M = int(SCREEN_HEIGHT/PPM)

DEBUG_DRAW=False

STAGE_NUM = 12
GAME_TIMEOUT_S = 60 # 秒

# プレイヤーの移動の起点
PLAYER_SCROLL_X_M = 3

# プレイヤーの移動に合わせた全体の描画の移動量
DRAW_OFFSET_X = 0
DRAW_OFFSET_X_M = 0

SPRITE_SETS = [
    [0,0,16,16], # プレイヤー
    [0,16,16,16],
    [0, 48, 16, 16], # コイン
    [0, 64, 16, 16], # わな
    [0, 32, 16, 16], # 旗
]
class SpriteSet(Enum):
    PLAYER = 0
    COIN = 2
    TRAP = 3
    FLAG = 4

    @staticmethod
    def map_rect(n):
        if isinstance(n, SpriteSet):
            n = n.value
        if n<0 or n >= len(SPRITE_SETS):
            return None
        return SPRITE_SETS[n]

def draw_sprite_world(pos, sprite_n):
    pos = world_to_draw_pos(pos)

    r = SpriteSet.map_rect(sprite_n)
    if r is None:
        return
    w = r[2]
    h = r[3]

    pyxel.blt(pos[0]-w/2 + DRAW_OFFSET_X,
        pos[1]-h/2,
        0,
        r[0],r[1],r[2],r[3],
        11)

def draw_body_sprite(body, sprite_n):
    pos = body_pos(body)
    draw_sprite_world(pos, sprite_n)

def draw_sprite(pos, sprite_n):
    r = SpriteSet.map_rect(sprite_n)
    if r is None:
        return
    pyxel.blt(pos[0] + DRAW_OFFSET_X,
        pos[1],
        0,
        r[0],r[1],r[2],r[3],
        11)

# 描画の全体のオフセット値を設定
def set_draw_offset_x_m(offset_m):
    global DRAW_OFFSET_X_M
    global DRAW_OFFSET_X

    DRAW_OFFSET_X_M = offset_m
    DRAW_OFFSET_X = int(offset_m * PPM)

# ボディの位置を取得　ワールド座標
def body_pos(body):
    return body.transform * (0,0)

def set_body_pos(body, pos):
    body.transform = (pos, 0)

# ボディの位置を取得　描画座標
def body_draw_pos(body):
    return world_to_draw_pos(body.transform * (0,0))

# 位置をワールド座標から描画座標に変換
def world_to_draw_pos(pos):
    return int(pos[0]* PPM), int(SCREEN_Y_ZERO_OFFSET - pos[1] * PPM)

# ポリゴンを描画
# 引数は描画座標の位置
def draw_polygon(vertices, color):
    n = len(vertices)
    for i in range(n-1):
        pyxel.line(vertices[i][0] + DRAW_OFFSET_X, vertices[i][1],
            vertices[i+1][0] + DRAW_OFFSET_X, vertices[i+1][1],
            color)

    pyxel.line(vertices[n-1][0] + DRAW_OFFSET_X, vertices[n-1][1],
        vertices[0][0] + DRAW_OFFSET_X, vertices[0][1],
        color)

# ボディを描画
def draw_body(body, color):
    for fixture in body.fixtures:
        shape = fixture.shape

        if type(shape) is Box2D.b2PolygonShape:
            # print(shape.vertices)
            vertices = [(body.transform * v) * PPM for v in shape.vertices]
            vertices = [(int(v[0]), int(SCREEN_Y_ZERO_OFFSET - v[1])) for v in vertices]
            # print(vertices)
            draw_polygon(vertices, color)
        elif type(shape) is Box2D.b2CircleShape:
            pos = (body.transform * shape.pos) * PPM
            pos = int(pos[0]), int(SCREEN_Y_ZERO_OFFSET - pos[1])
#            print(pos)
            pyxel.circb(pos[0] + DRAW_OFFSET_X, pos[1], int(fixture.shape.radius*PPM), color)

def draw_center_x(text, y, color):
    w = len(text)*5
    pyxel.text(int((SCREEN_WIDTH-w)/2),
        y,
        text,
        color)

class GameMode(Enum):
    TITLE = 0
    MAIN = 1
    STAGE = 2
    END = 3

class InputKey(Enum):
    UP = 0
    DOWN = 1
    LEFT = 2
    RIGHT = 3
    A = 4
    B = 5
    COUNT = 6

class Input:
    def __init__(self):
        self.current_keys = [False] * InputKey.COUNT.value
        self.pref_keys = [False] * InputKey.COUNT.value

        self.record = []
        self.recoding = False

        self.replaying = False
        self.replay_counter = 0
        self.replay_record = None

    def update(self):
        self.pref_keys = self.current_keys[:]

        key_check = {
            InputKey.UP: pyxel.KEY_UP,
            InputKey.DOWN: pyxel.KEY_DOWN,
            InputKey.LEFT: pyxel.KEY_LEFT,
            InputKey.RIGHT: pyxel.KEY_RIGHT,
            InputKey.A: pyxel.KEY_X,
            InputKey.B: pyxel.KEY_R,
        }
        for key, value in key_check.items():
            self.current_keys[key.value] = pyxel.btn(value)

        if self.recoding:
            code = 0
            for n in range(InputKey.COUNT.value):
                if self.current_keys[n]:
                    code += pow(2, n)
            self.record.append(code)

        if self.replaying:
            if len(self.replay_record) > self.replay_counter:
                code = self.replay_record[self.replay_counter]
                for n in range(InputKey.COUNT.value):
                    self.current_keys[n] = True if (code & pow(2, n)) else False

            self.replay_counter += 1

    def draw(self):
        X = SCREEN_WIDTH - 15
        Y = 2

        LINES = [
            [2,0,2,1],
            [2,3,2,4],
            [0,2,1,2],
            [3,2,4,2],
            [8,3,8,4],
            [6,3,6,4],
        ]

        for n in range(InputKey.COUNT.value):
            c = 8 if self.current_keys[n] else 6
            p = LINES[n]

            pyxel.line(X+p[0], Y+p[1],
                X+p[2], Y+p[3],
                c
            )

        if self.replaying:
            t = "REPLAY"
            draw_center_x(t, SCREEN_HEIGHT/2, 8)

    def game_start(self, replay):
        if replay:
            self.recoding = False
            self.replaying = True
        else:
            self.recoding = True
            self.record = []
            self.replaying = False

    def game_end(self):
        if self.recoding:
            self.recoding = False
            self.replay_record = self.record[:]
        if self.replaying:
            self.replaying = False

    def btn(self, key):
        return self.current_keys[key.value]

    def btnp(self, key):
        return self.current_keys[key.value] and not self.pref_keys[key.value]

class Game:
    def __init__(self):
        pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT)
        pyxel.load(os.path.join(os.path.dirname(__file__), "main.pyxel"))

        self.mode = GameMode.TITLE
        self.coins = 0
        self.score = 0
        self.stage = 0
        self.stages = [False] * STAGE_NUM
        self.timecount = 1000*GAME_TIMEOUT_S

        self.next_mode = GameMode.TITLE
        self.next_param = {}

        self.input = Input()

    def run(self):
        pyxel.run(self.update, self.draw)

    def update(self):
        self.input.update()

        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()

        if self.next_mode:
            self.goto_next_mode()

        self.scene.update()

        if self.is_gaming():
            self.timecount -= (1000/TARGET_FPS)
            if self.timecount <= 0:
                self.game_end()

    def goto_next_mode(self):
        next_scenes = {
            GameMode.TITLE: scenes.SceneTitle,
            GameMode.STAGE: scenes.SceneStageSelect,
            GameMode.MAIN: main.SceneMain,
            GameMode.END: scenes.SceneEnd,
        }
        self.mode = self.next_mode
        self.scene = (next_scenes[self.next_mode])(self.next_param)
        self.next_mode = None
        self.next_param = None

    def is_gaming(self):
        return self.mode == GameMode.STAGE or self.mode == GameMode.MAIN

    def draw(self):
        pyxel.cls(0)
        self.scene.draw()

        if self.is_gaming():
            t = "TIME: %02d:%02d.%03d  SCORE:%03d" % (int(self.timecount/60/1000),
                int(self.timecount/1000)%60,
                self.timecount%1000,
                self.score)
            pyxel.text(10,3, t, 7)

        self.input.draw()

    def move_scene(self, next_mode, next_param):
        self.next_mode = next_mode
        self.next_param = next_param

    # ゲーム開始
    def game_start(self, replay):
        self.coins = 0
        self.score = 0
        self.stages = [False] * STAGE_NUM
        self.timecount = 1000*GAME_TIMEOUT_S

        self.move_scene(GameMode.STAGE, {})

        self.input.game_start(replay)

    def game_end(self):
        self.move_scene(GameMode.END, {})
        self.input.game_end()

    def stage_start(self, stage):
        self.coins = 0
        self.stage = stage
        self.move_scene(GameMode.MAIN, {"stage": stage})

    def stage_end(self):
        self.score += (self.coins+5)
        self.coins = 0
        self.stages[self.stage] = True
        self.move_scene(GameMode.STAGE, {})

    def get_coin(self):
        self.coins += 1

game = None
def game_main():
    global game
    game = Game()
    game.run()


import abc
from typing import Callable, Dict, Optional

class Query:
    """Base Query class.

    Examples
    --------
    >>> from clinica.pydra.query import Query
    >>> q = Query()
    >>> len(q)
    0
    """

    _default_queries = {}
    repr_indent = 4

    def __init__(self, query: Optional[Dict] = None):
        self._query = self.format_query(query)

    @property
    def query(self):
        return self._query

    def format_query(self, input_query: Optional[Dict] = None) -> Dict:
        """Format the input query in a form suitable for DataGrabbers.

        If the query is None, return an empty dictionary.

        Otherwise, `format_query` does two things:

            - parse the input query
            - potentially combine the parsed input query with default values

        The input query is a dictionary but has a heterogeneous structure
        depending on whether we wish to query BIDS or CAPS folders.

        More precisely, it can have the following form :

            {"label" : {query dict, possibly incomplete}}

            example : {"T1w": {"suffix": "T1w"}}

        which is the usual format for BIDS queries. In this case, we simply need
        to filter out queries for labels not supported for BIDS (for example we'd
        keep "T1w" but drop "dartel" or "mask_tissues" if these were present since
        these are labels for CAPS queries).

        The input query can also have the following form:

            {"label" : {kwargs for a query maker}}

            example: {"mask_tissues": {'tissue_number': (1, 2), 'modulation': False}}

        which is the usual format for CAPS queries. In this case, we need to
        filter out queries for labels not supported (for example we'd keep "mask_tissues"
        but drop "T1w" or "pet" if these were present since these are labels for BIDS queries).
        And we need to call the appropriate query maker to obtain a proper query dict.
        In this example, the query maker corresponding to the label "mask_tissues" is the
        function `clinica.utils.input_files.t1_volume_native_tpm_in_mni`. We call this
        function with arguments `tissue_number=(1, 2), modulation=False`.

        After parsing, the query structure is the same for both BIDS and CAPS:

            {"label" : {query dict, possibly incomplete} or list of query dicts}

        The query is then completed with potential default values:

            {"label" : {query dict} or list of query dicts}

            example: {"T1w": {"suffix": "T1w", "extension": [".nii.gz"]}}

        Parameters
        ----------
        input_query : Dict, optional
            Raw input query to format.

        Returns
        -------
        formatted_query : Dict
            Resulting formatted query.
        """
        formatted_query = {}
        if not input_query:
            return formatted_query
        for k, q in self.parse_query(input_query).items():
            if isinstance(q, dict):
                formatted_query[k] = {**self.default_query(k), **q}
            elif isinstance(q, list):
                formatted_query[k] = [{**self.default_query(k), **qq} for qq in q]
            else:
                raise TypeError(
                    f"Unexpected type {type(q)} for query {q}."
                    "Only dictionaries and lists are supported."
                )
        return formatted_query

    @abc.abstractmethod
    def parse_query(self, query: Dict) -> Dict:
        pass

    def default_query(self, label: str) -> Dict:
        """Returns the default query corresponding to the given label.
        If there is no such query, returns an empty dict.

        Parameters
        ----------
        label : str
            Label of the default query to look for.

        Returns
        -------
        Dict :
            The default query corresponding to the provided label.
        """
        return self._default_queries.get(label, {})

    def __getitem__(self, name):
        return self._query[name]

    def __iter__(self):
        return iter(self._query)

    def keys(self):
        return self._query.keys()

    def items(self):
        return self._query.items()

    def values(self):
        return self._query.values()

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

    def __str__(self):
        import json

        return json.dumps(self._query, indent=self.repr_indent)

class BIDSQuery(Query):
    """BIDSQuery class.

    Examples
    --------
    >>> from clinica.pydra.query import BIDSQuery
    >>> q = BIDSQuery({"T1w": {"suffix": "T1w"}})
    >>> len(q)
    1
    >>> q.query
    {'T1w': {'suffix': 'T1w', 'extension': ['.nii.gz']}}
    """

    _default_queries = {
        "T1w": {"suffix": "T1w", "extension": [".nii.gz"]},
        "pet": {"suffix": "pet", "extension": [".nii.gz"]},
    }

    def parse_query(self, query: Dict) -> Dict:
        """Parse the provided query.

        BIDS query are already specified in a proper dictionary format.
        Parsing is therefore equivalent to filtering out queries corresponding
        to invalid labels (for example labels for CAPS).
        """
        return {k: v for k, v in query.items() if k in self._default_queries}

class CAPSQuery(Query):
    """CAPSQuery class."""

    # Query makers are specified in subclasses
    _query_makers = {}

    def parse_query(self, query: Dict) -> Dict:
        """Parse the provided query.

        For CAPS, the user is providing a dictionary of kwargs for some function
        responsible for building the query dictionary (for example
        `clinica.utils.input_files.t1_volume_deformation_to_template`).
        These functions are stored in a mapping and accessed through the `query_maker`
        method which uses the labels to look for these functions.
        Parsing the query is equivalent to calling these functions for each label with
        the associated user-provided kwargs.

        Parameters
        ----------
        query : Dict
            The user provided query to be parsed.

        Returns
        -------
        parsed_query : Dict
            The parsed query.
        """
        parsed_query = {}
        for label, params in query.items():
            query_maker = self._query_maker(label)
            formatted_query = query_maker(**params)
            if len(formatted_query) > 0:
                parsed_query[label] = formatted_query
        return parsed_query

    def _query_maker(self, label: str) -> Callable:
        """Retrieve the query-making-function associated with the
        provided label.

        Parameters
        ----------
        label : str
            The label to use to get the function.

        Returns
        -------
        Callable :
            The function to use to generate the query dictionary for this label.
            If the label does not match any entry, a default maker which return
             an empty dict for any passed parameters is returned.
        """
        return self._query_makers.get(label, lambda **kwargs: {})

class CAPSFileQuery(CAPSQuery):
    """CAPSFileQuery class.

    This class only holds the mapping between labels and query makers
    to be used with the `CAPSFileDataGrabber`.

    Examples
    --------
    >>> from clinica.pydra.query import CAPSFileQuery
    >>> q = CAPSFileQuery({'mask_tissues': {'tissue_number': (1, 2), 'modulation': False}})
    >>> len(q)
    1
    >>> import json
    >>> print(json.dumps(q.query, indent=2))
    {
        "mask_tissues": [
            {
                "pattern": "t1/spm/segmentation/normalized_space/*_*_T1w_segm-graymatter_space-Ixi549Space_modulated-off_probability.nii*",
                "description": "Tissue probability map graymatter based on native MRI in MNI space (Ixi549) without modulation.",
                "needed_pipeline": "t1-volume-tissue-segmentation"
            },
            {
                "pattern": "t1/spm/segmentation/normalized_space/*_*_T1w_segm-whitematter_space-Ixi549Space_modulated-off_probability.nii*",
                "description": "Tissue probability map whitematter based on native MRI in MNI space (Ixi549) without modulation.",
                "needed_pipeline": "t1-volume-tissue-segmentation"
            }
        ]
    }
    """

    from clinica.utils.input_files import (
        custom_pipeline,
        pet_volume_normalized_suvr_pet,
        t1_volume_dartel_input_tissue,
        t1_volume_deformation_to_template,
        t1_volume_native_tpm,
        t1_volume_native_tpm_in_mni,
        t1_volume_template_tpm_in_mni,
    )

    def t1w_to_mni_transform():
        from clinica.utils.input_files import T1W_TO_MNI_TRANSFORM

        return T1W_TO_MNI_TRANSFORM

    _query_makers = {
        "tissues": t1_volume_native_tpm,
        "mask_tissues": t1_volume_native_tpm_in_mni,
        "flow_fields": t1_volume_deformation_to_template,
        "pvc_mask_tissues": t1_volume_native_tpm,
        "dartel_input_tissue": t1_volume_dartel_input_tissue,
        "t1w_to_mni": t1w_to_mni_transform,
        "pet_volume": pet_volume_normalized_suvr_pet,
        "t1_volume": t1_volume_template_tpm_in_mni,
        "custom_pipeline": custom_pipeline,
    }

class CAPSGroupQuery(CAPSQuery):
    """CAPSGroupQuery class.

    This class only holds the mapping between the labels and query makers
    to be used with the `CAPSGroupDataGrabber`.

    Examples
    --------
    >>> from clinica.pydra.query import CAPSGroupQuery
    >>> import json
    >>> q = CAPSGroupQuery({'dartel_template': {'group_label': "UnitTest"}})
    >>> len(q)
    1
    >>> print(json.dumps(q.query, indent=2))
    {
        "dartel_template": {
        "pattern": "group-UnitTest/t1/group-UnitTest_template.nii*",
        "description": "T1w template file of group UnitTest",
        "needed_pipeline": "t1-volume or t1-volume-create-dartel"
        }
    }
    """

    from clinica.utils.input_files import (
        custom_group,
        t1_volume_final_group_template,
        t1_volume_i_th_iteration_group_template,
    )

    _query_makers = {
        "dartel_template": t1_volume_final_group_template,
        "dartel_iteration_templates": t1_volume_i_th_iteration_group_template,
        "t_map": custom_group,
    }

def query_factory(query: Dict, query_type: str) -> Query:
    """Return the Query instance initialized from passed `query`,
    based on provided `query_type`.

    Parameters
    ----------
    query : dict
        The query in dictionary format.

    query_type : {"bids", "caps_file", "caps_group"}
        The type of query to build.

    Returns
    -------
    Query :
        The resulting Query instance.

    Raises
    ------
    ValueError
        If `query_type` is not a valid value.
    """
    if query_type == "bids":
        return BIDSQuery(query)
    elif query_type == "caps_file":
        return CAPSFileQuery(query)
    elif query_type == "caps_group":
        return CAPSGroupQuery(query)
    else:
        raise ValueError(
            f"query_factory() received an invalid argument for 'query_type' : {query_type}"
            f"Supported values are 'bids', 'caps_file', and 'caps_group'."
        )


import gym
import numpy as np
from itertools import count
from collections import namedtuple

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

gamma = 0.99
actor_lr = 1e-2
critic_lr = 1e-2
max_step = 10000

print_interval = 10
test_num = 3

RENDER = False
render_num = 200

Memory_unit = namedtuple('Memory_unit', ['state','action','next_state', 'reward'])

class Actor(nn.Module):

    def __init__(self,state_szie,action_size,hidden_size=40,init_w=3e-3):
        super(Actor, self).__init__()
        self.fc1 = nn.Linear(state_szie,hidden_size)
        self.fc2 = nn.Linear(hidden_size,hidden_size)
        self.fc3 = nn.Linear(hidden_size,action_size)
        self.init_weight(init_w)

    def forward(self,s):
        out = F.relu(self.fc1(s))
        out = F.relu(self.fc2(out))
        out = F.softmax(self.fc3(out))
        return out

    def init_weight(self,init_w):
        self.fc1.weight.data = fanin_init(self.fc1.weight.data.size())
        self.fc2.weight.data = fanin_init(self.fc2.weight.data.size())
        self.fc3.weight.data.uniform_(-init_w,init_w)

class Critic(nn.Module):

    def __init__(self,input_size,hidden_size=40,output_size=1,init_w=3e-3):
        super(Critic, self).__init__()
        self.fc1 = nn.Linear(input_size,hidden_size)
        self.fc2 = nn.Linear(hidden_size,hidden_size)
        self.fc3 = nn.Linear(hidden_size,output_size)
        self.init_weight(init_w)

    def forward(self,s):
        out = F.relu(self.fc1(s))
        out = F.relu(self.fc2(out))
        out = self.fc3(out)
        return out

    def init_weight(self,init_w):
        self.fc1.weight.data = fanin_init(self.fc1.weight.data.size())
        self.fc2.weight.data = fanin_init(self.fc2.weight.data.size())
        self.fc3.weight.data.uniform_(-init_w, init_w)

class Advantage_Actor_Critic():
    def __init__(self,nb_state,nb_action,critic_lr,actor_lr,init_w=3e-3):
        self.memory = []
        self.critic = Critic(nb_state,init_w=init_w)
        self.optimizer_critic = torch.optim.Adam(self.critic.parameters(),lr=critic_lr)

        self.actor = Actor(nb_state,nb_action,init_w=init_w)
        self.optimizer_actor = torch.optim.Adam(self.actor.parameters(),lr=actor_lr)

    # in test case, only return the action with max prob
    def select_action(self,state,is_train=True):
        state = torch.FloatTensor(state).unsqueeze(0)
        probs = self.actor(Variable(state))
        if not is_train:
            return torch.max(probs,1,keepdim=True)[1].data[0,0]
        return probs

    def discount_reward(self,r, gamma,final_r):
        discounted_r = np.zeros_like(r)
        running_add = final_r
        for t in reversed(range(0, len(r))):
            running_add = running_add * gamma + r[t]
            discounted_r[t] = running_add
        return discounted_r

    def train_episode(self):

        batch = Memory_unit(*zip(*self.memory))

        state_batch = Variable(torch.Tensor(batch.state).view(-1,nb_state))
        action_batch = Variable(torch.LongTensor(batch.action).view(-1,1))
        # next_state_batch = Variable(torch.FloatTensor(batch.next_state).view(-1,nb_state))
        # reward_batch = Variable(torch.FloatTensor(batch.reward).view(-1,1))

        #---------------update critic---------------------
        v_eval = self.critic(state_batch)
        q_target = Variable(torch.FloatTensor(self.discount_reward(batch.reward,0.99,1))).unsqueeze(1)

        value_loss = torch.nn.functional.mse_loss(v_eval,q_target)
        self.optimizer_critic.zero_grad()
        value_loss.backward()
        torch.nn.utils.clip_grad_norm(self.critic.parameters(),0.8)
        self.optimizer_critic.step()

        #----------------update actor----------------------
        self.optimizer_actor.zero_grad()
        log_softmax_actions = torch.log(self.actor(state_batch))
        v_eval = self.critic(state_batch)
        q_target = Variable(torch.FloatTensor(self.discount_reward(batch.reward,0.99,1))).unsqueeze(1)
        advantage = q_target - v_eval
        policy_loss = - torch.mean(log_softmax_actions.gather(1,action_batch)* advantage)
        policy_loss.backward()
        torch.nn.utils.clip_grad_norm(self.actor.parameters(),0.8)
        self.optimizer_actor.step()

        self.memory = []

# only chose the action with max prob
def test(env,agent,episode):
    total_length = 0
    total_reward = 0
    for i in range(test_num):
        state = env.reset()
        for test_step in range(max_step):
            if RENDER:
                env.render()
            action = agent.select_action(state,is_train=False)
            next_state, reward, done, info = env.step(action)
            total_reward += reward
            state = next_state
            if done:
                break
        total_length += test_step
    print('Episode {}\tAvg_Length:{:5f}\tAvg_Reward:{:5f}'.format(episode, total_length / test_num,
                                                                  total_reward / test_num))

def fanin_init(size, fanin=None):
    fanin = fanin or size[0]
    v = 1. / np.sqrt(fanin)
    return torch.Tensor(size).uniform_(-v, v)

env = gym.make('CartPole-v0')

nb_aciton = env.action_space.n
nb_state = env.observation_space.shape[0]

a2c = Advantage_Actor_Critic(nb_state,nb_aciton,critic_lr,actor_lr)

for i_episode in count(1):
    state = env.reset()
    if i_episode > render_num:
        RENDER = True
    for t in range(max_step):
        actions_prob = a2c.select_action(state)
        action = actions_prob.multinomial(1).data[0,0]
        next_state, reward, done, _ = env.step(action)

        a2c.memory.append(Memory_unit(state,action,next_state,reward))

        if done:
            break
        state = next_state

    a2c.train_episode()

    if i_episode%print_interval == 0:
        test(env,a2c,i_episode)


from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = r'''
    name: linode
    plugin_type: inventory
    author:
      - Luke Murphy (@decentral1se)
    short_description: Ansible dynamic inventory plugin for Linode.
    requirements:
        - python >= 2.7
        - linode_api4 >= 2.0.0
    description:
        - Reads inventories from the Linode API v4.
        - Uses a YAML configuration file that ends with linode.(yml|yaml).
        - Linode labels are used by default as the hostnames.
        - The inventory groups are built from groups and not tags.
    options:
        plugin:
            description: marks this as an instance of the 'linode' plugin
            required: true
            choices: ['linode']
        access_token:
            description: The Linode account personal access token.
            required: true
            env:
                - name: LINODE_ACCESS_TOKEN
        regions:
          description: Populate inventory with instances in this region.
          default: []
          type: list
          required: false
        types:
          description: Populate inventory with instances with this type.
          default: []
          type: list
          required: false
'''

EXAMPLES = r'''
# Minimal example. `LINODE_ACCESS_TOKEN` is exposed in environment.
plugin: linode

# Example with regions, types, groups and access token
plugin: linode
access_token: foobar
regions:
  - eu-west
types:
  - g5-standard-2
'''

import os

from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.six import string_types
from ansible.plugins.inventory import BaseInventoryPlugin

try:
    from linode_api4 import LinodeClient
    from linode_api4.errors import ApiError as LinodeApiError
except ImportError:
    raise AnsibleError('the Linode dynamic inventory plugin requires linode_api4.')

class InventoryModule(BaseInventoryPlugin):

    NAME = 'community.general.linode'

    def _build_client(self):
        """Build the Linode client."""

        access_token = self.get_option('access_token')

        if access_token is None:
            try:
                access_token = os.environ['LINODE_ACCESS_TOKEN']
            except KeyError:
                pass

        if access_token is None:
            raise AnsibleError((
                'Could not retrieve Linode access token '
                'from plugin configuration or environment'
            ))

        self.client = LinodeClient(access_token)

    def _get_instances_inventory(self):
        """Retrieve Linode instance information from cloud inventory."""
        try:
            self.instances = self.client.linode.instances()
        except LinodeApiError as exception:
            raise AnsibleError('Linode client raised: %s' % exception)

    def _add_groups(self):
        """Add Linode instance groups to the dynamic inventory."""
        self.linode_groups = set(
            filter(None, [
                instance.group
                for instance
                in self.instances
            ])
        )

        for linode_group in self.linode_groups:
            self.inventory.add_group(linode_group)

    def _filter_by_config(self, regions, types):
        """Filter instances by user specified configuration."""
        if regions:
            self.instances = [
                instance for instance in self.instances
                if instance.region.id in regions
            ]

        if types:
            self.instances = [
                instance for instance in self.instances
                if instance.type.id in types
            ]

    def _add_instances_to_groups(self):
        """Add instance names to their dynamic inventory groups."""
        for instance in self.instances:
            self.inventory.add_host(instance.label, group=instance.group)

    def _add_hostvars_for_instances(self):
        """Add hostvars for instances in the dynamic inventory."""
        for instance in self.instances:
            hostvars = instance._raw_json
            for hostvar_key in hostvars:
                self.inventory.set_variable(
                    instance.label,
                    hostvar_key,
                    hostvars[hostvar_key]
                )

    def _validate_option(self, name, desired_type, option_value):
        """Validate user specified configuration data against types."""
        if isinstance(option_value, string_types) and desired_type == list:
            option_value = [option_value]

        if option_value is None:
            option_value = desired_type()

        if not isinstance(option_value, desired_type):
            raise AnsibleParserError(
                'The option %s (%s) must be a %s' % (
                    name, option_value, desired_type
                )
            )

        return option_value

    def _get_query_options(self, config_data):
        """Get user specified query options from the configuration."""
        options = {
            'regions': {
                'type_to_be': list,
                'value': config_data.get('regions', [])
            },
            'types': {
                'type_to_be': list,
                'value': config_data.get('types', [])
            },
        }

        for name in options:
            options[name]['value'] = self._validate_option(
                name,
                options[name]['type_to_be'],
                options[name]['value']
            )

        regions = options['regions']['value']
        types = options['types']['value']

        return regions, types

    def verify_file(self, path):
        """Verify the Linode configuration file."""
        if super(InventoryModule, self).verify_file(path):
            endings = ('linode.yaml', 'linode.yml')
            if any((path.endswith(ending) for ending in endings)):
                return True
        return False

    def parse(self, inventory, loader, path, cache=True):
        """Dynamically parse Linode the cloud inventory."""
        super(InventoryModule, self).parse(inventory, loader, path)

        self._build_client()

        self._get_instances_inventory()

        config_data = self._read_config_data(path)
        regions, types = self._get_query_options(config_data)
        self._filter_by_config(regions, types)

        self._add_groups()
        self._add_instances_to_groups()
        self._add_hostvars_for_instances()


from math import floor
from typing import List

class Solution:
    def subMatrix(self, matrix: List[List[int]], left_top: List[int], right_bottom: List[int]) -> List[List[int]]:
        new_matrix = []
        if left_top[0] == right_bottom[0]:
            right_bottom[0] += 1
        if left_top[1] == right_bottom[1]:
            right_bottom[1] += 1
        for i in range(left_top[0], min(right_bottom[0] + 1, len(matrix))):
            row = []
            for j in range(left_top[1] + 1, right_bottom[1]):
                row.append(matrix[i][j])
            if row:
                new_matrix.append(row)
        return new_matrix

    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:
            return False
        height = len(matrix)
        width = len(matrix[0])
        if height <= 2 and width <= 2:
            for row in matrix:
                for i in row:
                    if i == target:
                        return True
            return False
        m_y = floor(height / 2)
        m_x = floor(width / 2)
        if matrix[m_y][m_x] == target:
            return True
        elif matrix[m_y][m_x] > target:
            return self.searchMatrix(self.subMatrix(matrix, [0, 0], [m_y, m_x]), target)
        else:
            return self.searchMatrix(self.subMatrix(matrix, [0, m_x], [m_y, width]), target) or self.searchMatrix(self.subMatrix(matrix, [m_y, m_x], [height, width]), target) or self.searchMatrix(self.subMatrix(matrix, [m_y, 0], [height, m_x]), target)

if __name__ == "__main__":
    matrix = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13,
                                                  14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]
    print(Solution().subMatrix(matrix, [0, 2], [5]))
    target = 15
    print(Solution().searchMatrix(matrix, target))


import itertools
import random

class CellularAutomata():
    def __init__(self, rule_number=120, already_in_base=False, neighborhood=3, states=('0', '1'),
                    random_first_row=False, width=100, colors=None):
        # Set up basic info about automata.
        self.neighborhood = neighborhood
        self.states = states
        self.rule_number = rule_number
        self.maximum_rule_number = len(self.states) ** (len(self.states) ** self.neighborhood)
        self.width = width

        if not colors:
            self.colors = {
                # Colors assigned to each possible state
                "0": (255, 255, 255),
                "1": (255, 144, 251),
                "2": (160, 220, 252),
            }
        else:
            self.colors = colors

        # `rule_input_keys` is the list of all combinations of the state that are `neighborhood`
        # ... characters in length in reverse order that they're provided, like so:
        # `['222', '221', '220' '212' '211' '210' '202', '201', '200' ...]`
        self.rule_input_keys = list(map(''.join, itertools.product(self.states, repeat=self.neighborhood)))[::-1]

        if rule_number:
            if not already_in_base:
                self.rule_number = self._convert_rule_to_base(rule_number)
            self.rule_dictionary = self._create_rule_dictionary()
        else:
            self.rule_dictionary = None

        # If we have a randomly assigned first row, randomly decide values for each cell
        if random_first_row:
            self.curr_row = [random.choice(self.states) for _ in range(self.width)]
        else:
            # Center the problem string on the first row
            self.curr_row = ['0' for _ in range(self.width)]
            self.curr_row[self.width//2] = '1'

    # Converts `rule_number` to target base `len(states)`, with a maximum value of...
    # ... `maximum_rule_number = len(states) ** (len(states) ** neighborohood)`
    # Anything above that just uses unnecessary computer cycles, as they're...
    # ... equivalent to `rule_number % maximum_rule_number`
    def _convert_rule_to_base(self, rule_number):
        # Treat 0 as special otherwise we're dividing by 0
        if rule_number == 0:
            # Return a number that's just the length of
            return ''.join(['0'] * (len(self.states) ** self.neighborhood))
        if rule_number > self.maximum_rule_number:
            rule_number = rule_number % self.maximum_rule_number
        # We will generate the new rule one digit at a time, so we'll add the digits to a list
        new_rule_number_digits = []
        # Generate each digit of the new rule number in the target base
        while rule_number:
            rule_number, remainder = divmod(rule_number, len(self.states))
            new_rule_number_digits.append(str(remainder))

        # Complicated. Rule numbers in Cellular Automata are defined by the following
        new_rule_number = ''.join(new_rule_number_digits)[::-1].zfill(len(self.states) ** self.neighborhood)
        return new_rule_number

    # Returns a dictionary of possible inputs to the digits of
    def _create_rule_dictionary(self):
        # Maps the keys produced to the digits of `rule_number`
        return dict(zip(self.rule_input_keys, self.rule_number))

    def _decide_value_for_cell(self, cell_index, rules):
        # First cell used
        p_cell = (cell_index - self.neighborhood//2)
        # Joins the current values for the cells and uses it as
        input = "".join([self.curr_row[j % self.width] for j in range(p_cell, p_cell + self.neighborhood)])
        value = rules[input]
        return value

    # Expects a string similar to `011010001` to be passed in to determine the values of the rule outputs
    # `rule_values` is assumed to be in-base. We only check if it's the correct length to be used
    def advance_generation(self, rule_values=None):
        if rule_values:
            if len(rule_values) == len(self.rule_input_keys):
                # Use a custom transition function
                rule_dict = dict(zip(self.rule_input_keys, rule_values))
            else: # If the lengths don't match up...
                print("`rule_values` passed in is incorrect length to be used. Break time.")
                print("Length of rule_input_keys: " + len(self.rule_input_keys)
                    + "\nLength of rule_values: " + len(rule_values))
                rule_dict = dict()
        else:
            rule_dict = self.rule_dictionary

        new_row = [self._decide_value_for_cell(cell_index, rule_dict) for cell_index in range(len(self.curr_row))]
        self.curr_row = new_row


import argparse

try:
    import importlib.metadata as metadata
except ImportError:
    import importlib_metadata as metadata

import numpy as np

from attractors.attractor import ATTRACTOR_PARAMS, Attractor

def case_convert(snakecase_string):
    return snakecase_string.replace("_", " ").title().replace("Cnn", "CNN")

def cli():
    parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS)
    required = parser.add_argument_group("required arguments")
    optional = parser.add_argument_group("other arguments")

    parser.add_argument(
        "-v",
        "--version",
        action="version",
        version=metadata.version("attractors"),
    )

    parser.add_argument(
        "-h",
        "--help",
        action="help",
        help="show this help message and exit",
    )

    required.add_argument(
        "-t",
        "--type",
        help="choose simulation type",
        type=str,
        choices=["multipoint", "gradient"],
        required=True,
    )

    optional.add_argument(
        "--des",
        help="choose the Differential Equation Solver. Default: rk4",
        type=str,
        choices=Attractor.list_des(),
        default="rk4",
    )

    optional.add_argument(
        "--width",
        help="set width of the figure Default: 16",
        type=int,
    )
    optional.add_argument(
        "--height",
        help="set height of the figure Default: 9",
        type=int,
    )
    optional.add_argument(
        "--dpi",
        help="set DPI of the figure Default: 120",
        type=int,
    )
    optional.add_argument(
        "--theme", help="choose theme (color palette) to be used", type=str
    )
    required.add_argument(
        "-s",
        "--simtime",
        help="set the simulation time",
        type=int,
        required=True,
    )
    required.add_argument(
        "-p",
        "--simpoints",
        help="set the number of points to be used for the simulation",
        type=int,
        required=True,
    )
    optional.add_argument(
        "--bgcolor",
        help=(
            "background color for figure in hex. Overrides theme settings if"
            " specified Default: #000000"
        ),
        type=str,
    )
    optional.add_argument(
        "--cmap",
        help=(
            "matplotlib cmap for palette. Overrides theme settings if"
            " specified Default: jet"
        ),
        type=str,
    )
    optional.add_argument(
        "--fps",
        help="set FPS for animated video (or interactive plot) Default: 60",
        type=int,
    )
    optional.add_argument(
        "--n",
        help="number of initial points for Multipoint animation Default: 3",
        type=int,
        default=3,
    )
    optional.add_argument(
        "--rk2",
        help="method for 2nd order Runge-Kutta if specified to be used. Default: heun",
        type=str,
        choices=["heun", "imp_poly", "ralston"],
        default="heun",
    )

    optional.add_argument(
        "--outf",
        help="output video filename Default: output.mp4",
        type=str,
    )
    optional.add_argument(
        "--live",
        help="live plotting instead of generating video.",
        action="store_true",
    )
    subparsers = parser.add_subparsers(
        title="Attractor settings",
        description="Choose one of the attractors and specify its parameters",
        dest="attractor",
        metavar="ATTRACTOR",
    )

    for attr, attrparams in ATTRACTOR_PARAMS.items():
        attrparser = subparsers.add_parser(
            f"{attr}",
            help=f"{case_convert(attr)} attractor",
            argument_default=argparse.SUPPRESS,
        )
        attrgroup = attrparser.add_argument_group(
            title=f"{case_convert(attr)} attractor parameters"
        )

        for i in range(len(attrparams["params"])):
            attrgroup.add_argument(
                f"--{attrparams['params'][i]}",
                help=(
                    f"Parameter for {case_convert(attr)} attractor "
                    f"Default: {attrparams['default_params'][i]}"
                ),
                type=float,
            )
        attrgroup.add_argument(
            "--initcoord",
            help=(
                f"Initial coordinate for {case_convert(attr)} attractor. Input"
                f" format: \"x y z\" Default: {attrparams['init_coord']}"
            ),
            type=float,
            nargs=3,
        )
        for k in ["x", "y", "z"]:
            attrgroup.add_argument(
                f"--{k}lim",
                help=(
                    f"{k} axis limits for figure. Input format:"
                    f" \"{k}min {k}max\" Default: {attrparams[f'{k}lim']}"
                ),
                type=float,
                nargs=2,
            )

    args = parser.parse_args()
    kwargs = vars(args)

    attractor = args.attractor
    if args.type == "multipoint":
        objs = [Attractor(attractor, kwargs=kwargs) for _ in range(args.n)]
        for obj in objs[1:]:
            obj.coord += np.random.normal(0, 0.01, size=3)
        itrs = []
        for obj in objs:
            func = getattr(obj, args.des)
            if args.des == "rk2":
                itr = func(0, args.simtime, args.simpoints, args.rk2)
            else:
                itr = func(0, args.simtime, args.simpoints)
            itrs.append(itr)
        Attractor.set_animate_multipoint(*itrs, **kwargs).animate(**kwargs)
    else:
        obj = Attractor(attractor, kwargs=kwargs)
        func = getattr(obj, args.des)
        if args.des == "rk2":
            itr = func(0, args.simtime, args.simpoints, args.rk2)
        else:
            itr = func(0, args.simtime, args.simpoints)
        Attractor.set_animate_gradient(itr, **kwargs).animate(**kwargs)

if __name__ == " __main__":
    cli()


from janome.tokenizer import Tokenizer
from gensim.models import Word2Vec
import itertools
from sklearn.decomposition import PCA
import matplotlib.patches as patches
import matplotlib.pyplot as plt
from matplotlib import rcParams
import random

rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'Noto Sans CJK JP']

path = "./data/"
lfiles = [
    "01.txt","02.txt","03.txt","04.txt","05.txt","06.txt","07.txt","08.txt","09.txt","10.txt",
    "11.txt","12.txt","13.txt","14.txt","15.txt","16.txt","17.txt","18.txt","19.txt","20.txt",
    "21.txt","22.txt","23.txt","24.txt","25.txt","26.txt","27.txt","28.txt","29.txt","30.txt",
    "41.txt","42.txt","43.txt","44.txt","45.txt","46.txt","47.txt","48.txt","49.txt","40.txt",
    "51.txt","52.txt","53.txt","54.txt","55.txt"
]

t = Tokenizer() # Tokenneizerインスタンスの生成
word_all = []   # 全ての単語をリスト形式で格納

### 関数 ###
# テキストを引数として、形態素解析の結果、名詞・動詞・形容詞の原形のみを配列で抽出する関数を定義
def extract_words(text):
    tokens = t.tokenize(text)
    return [token.base_form for token in tokens
        if token.part_of_speech.split(',')[0] in['名詞', '動詞','形容詞']]
# 類似単語の表示
def model_simulate( target_word ):
    try:
        print("■ {0}".format(target_word) )
        ret = model.wv.most_similar(positive=[target_word])
        for item in ret:
            print("\t{0} ({1})".format(item[0], item[1]) )
    except:
        print("[ERROR] {0}".format(target_word) )

def replaceStr(data):
    data = data.lower()
    # 文字列を置換する一覧 『 変換前：変換後 』
    dlist = {
        "protoout":"プロトアウト",
        "studio":"スタジオ",
        "protoout studio":"プロトアウトスタジオ",
        "protoout.studio":"プロトアウトスタジオ",
        "プロトアウト スタジオ":"プロトアウトスタジオ",
        "\"":"",
        "/":"",
        "画像":"",
        "0":"",
        "1":"",
        "2":"",
        "3":"",
        "4":"",
        "5":"",
        "6":"",
        "7":"",
        "8":"",
        "9":"",
        "月":"",
        "期生":"",
        "期":"",
        "土井":"",
        "com":"",
        ".":"",
        "-":"",
        "さん":"",
        "のびすけ":"",
        "コロナ":"",
        "(":"",
        ")":"",
        ":":"",
        "１":"",
        "飲む":"",
        "変化":"",
        "事":"",
    }

    for d in dlist:
        data = data.replace(d,dlist[d])
    return(data)

for file in lfiles:
    f = open( path + file, 'r', encoding='UTF-8')
    data = f.read()
    data = replaceStr(data)
    sentences = data.split('。')    # 全体のテキストを句点('。')で区切った配列にする。
    word_list = [extract_words(sentence) for sentence in sentences] # それぞれの文章を単語リストに変換(処理に数分かかります)
    word_all += word_list
    f.close()

model = Word2Vec(
        word_all,
        size=200,       # size: 圧縮次元数
        min_count=35,   # min_count: 出現頻度の低いものをカットする
        window=5,       # window: 前後の単語を拾う際の窓の広さを決める
        iter=100        # iter: 機械学習の繰り返し回数(デフォルト:5)十分学習できていないときにこの値を調整する
    )

target_word_list = [
    "プロトアウトスタジオ",
    "プロダクト",
    "アウトプット",
    "クラウドファンディング",
    "qiita",
]

for target_word in target_word_list:
    model_simulate( target_word )

########################################
# 参考：https://programming-info.dream-target.jp/python_word2vec
# プロットしたい単語を設定する
# 以下の例は、fire,earthquakeなどを設定しています。
words = []

for word in model.wv.index2word:
    words.append([word,"r"])

length = len(words)
data = []

j = 0
while j < length:
    data.append(model[words[j][0]])
    j += 1

#主成分分析により２次元に圧縮する
pca = PCA(n_components=2)
pca.fit(data)
data_pca= pca.transform(data)

length_data = len(data_pca)

### グラフ化 ######################

fig=plt.figure(figsize=(20,12),facecolor='w')
ax = plt.axes()

plt.rcParams["font.size"] = 10
i = 0
while i < length_data:
    plt.plot(data_pca[i][0], data_pca[i][1], ms=5.0, zorder=2, marker="x", color=words[i][1])   #点プロット
    plt.annotate(words[i][0], (data_pca[i][0], data_pca[i][1]), size=12)    #文字プロット
    for wd in target_word_list:
        if( words[i][0] == wd ):
            # 円を描く。色はランダム
            r=random.uniform(1,0)
            g=random.uniform(1,0)
            b=random.uniform(1,0)
            c = patches.Circle(xy=(data_pca[i][0], data_pca[i][1]), label=wd, radius=1.0, color=(r,g,b,0.5) )
            ax.add_patch(c)
    i += 1
ax.legend()
plt.show()


import logging
import os
from logging.handlers import RotatingFileHandler

formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s', datefmt='%H:%M:%S')

def setup_logger(name, level=logging.DEBUG):
    """Function setup as many loggers as you want"""
    if not os.path.exists('logs'):
        os.mkdir('logs')

    file_handler = logging.handlers.RotatingFileHandler('logs/%s.log' % name.split('.')[-1],
                                                        maxBytes=10000000,
                                                        backupCount=2)  # 10 Mb
    file_handler.setFormatter(formatter)

    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(formatter)

    logger = logging.getLogger(name)
    logger.setLevel(level)
    logger.addHandler(file_handler)
    logger.addHandler(stream_handler)

    return logger


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

import subprocess

from jinja2 import Environment, PackageLoader

from .._compat import decode, PY3K

TEMPLATE_ENV = Environment(
    loader=PackageLoader('poet', 'templates'),
    autoescape=False,
    lstrip_blocks=True,
    trim_blocks=True
)

TEMPLATE_ENV.globals.update({
    'isinstance': isinstance,
    'list': list,
    'sorted': sorted,
    'repr': repr
})

def call(args):
    """
    Calls a command and return the output.

    :param args: The command args.
    :type args: list

    :rtype: str
    """
    output = subprocess.check_output(args, stderr=subprocess.STDOUT)

    if PY3K:
        return decode(output)

    return output

def template(name):
    """
    Returns a template given a name.

    :param name: The name of the template.
    :type name: str

    :rtype: jinja2.Template
    """
    if not name.endswith('.jinja2'):
        name += '.jinja2'

    return TEMPLATE_ENV.get_template(name)


# Import the example classes

import fire
import numpy as np
# Useful imports
# from example_save_trials import *
import tensorflow as tf
# Import the necessary garage classes
# from garage.baselines.linear_feature_baseline import LinearFeatureBaseline
# from garage.misc import logger
from garage.experiment import run_experiment
from garage.tf.experiment import LocalTFRunner

import ast_toolbox.mcts.BoundedPriorityQueues as BPQ
from ast_toolbox.algos import MCTS
from ast_toolbox.algos import MCTSBV
from ast_toolbox.algos import MCTSRS
# Import the AST classes
from ast_toolbox.envs import ASTEnv
from ast_toolbox.rewards import ExampleAVReward
from ast_toolbox.samplers import ASTVectorizedSampler
from ast_toolbox.simulators import ExampleAVSimulator
from ast_toolbox.spaces import ExampleAVSpaces
from ast_toolbox.utils.go_explore_utils import load_convert_and_save_mcts_expert_trajectory
import pickle

def runner(
    mcts_type=None,
    env_args=None,
    run_experiment_args=None,
    sim_args=None,
    reward_args=None,
    spaces_args=None,
    algo_args=None,
    runner_args=None,
    bpq_args=None,
    sampler_args=None,
    save_expert_trajectory=False,
    # log_dir='.',
):
    if mcts_type is None:
        mcts_type = 'mcts'

    if env_args is None:
        env_args = {}

    if run_experiment_args is None:
        run_experiment_args = {}

    if sim_args is None:
        sim_args = {}

    if reward_args is None:
        reward_args = {}

    if spaces_args is None:
        spaces_args = {}

    if algo_args is None:
        algo_args = {}

    if runner_args is None:
        runner_args = {}

    if sampler_args is None:
        sampler_args = {}

    if bpq_args is None:
        bpq_args = {}

    if 'n_parallel' in run_experiment_args:
        n_parallel = run_experiment_args['n_parallel']
    else:
        n_parallel = 1
        run_experiment_args['n_parallel'] = n_parallel

    if 'max_path_length' in sim_args:
        max_path_length = sim_args['max_path_length']
    else:
        max_path_length = 50
        sim_args['max_path_length'] = max_path_length

    if 'batch_size' in runner_args:
        batch_size = runner_args['batch_size']
    else:
        batch_size = max_path_length * n_parallel
        runner_args['batch_size'] = batch_size

    def run_task(snapshot_config, *_):

        seed = 0
        # top_k = 10
        np.random.seed(seed)

        config = tf.ConfigProto()
        config.gpu_options.allow_growth = True
        with tf.Session(config=config) as sess:
            with tf.variable_scope('AST', reuse=tf.AUTO_REUSE):

                with LocalTFRunner(
                        snapshot_config=snapshot_config, max_cpus=4, sess=sess) as local_runner:

                    # Instantiate the example classes
                    sim = ExampleAVSimulator(**sim_args)
                    reward_function = ExampleAVReward(**reward_args)
                    spaces = ExampleAVSpaces(**spaces_args)

                    # Create the environment
                    if 'id' in env_args:
                        env_args.pop('id')
                    env = ASTEnv(simulator=sim,
                                 reward_function=reward_function,
                                 spaces=spaces,
                                 **env_args
                                 )

                    top_paths = BPQ.BoundedPriorityQueue(**bpq_args)

                    if mcts_type == 'mcts':
                        print('mcts')
                        algo = MCTS(env=env,
                                    top_paths=top_paths,
                                    **algo_args)
                    elif mcts_type == 'mctsbv':
                        print('mctsbv')
                        algo = MCTSBV(env=env,
                                      top_paths=top_paths,
                                      **algo_args)
                    elif mcts_type == 'mctsrs':
                        print('mctsrs')
                        algo = MCTSRS(env=env,
                                      top_paths=top_paths,
                                      **algo_args)
                    else:
                        raise NotImplementedError

                    sampler_cls = ASTVectorizedSampler
                    sampler_args['sim'] = sim
                    sampler_args['reward_function'] = reward_function

                    local_runner.setup(algo=algo,
                                       env=env,
                                       sampler_cls=sampler_cls,
                                       sampler_args=sampler_args)

                    # Run the experiment
                    local_runner.train(**runner_args)

                    log_dir = run_experiment_args['log_dir']

                    if save_expert_trajectory:
                        load_convert_and_save_mcts_expert_trajectory(
                            best_actions_filename=log_dir + '/best_actions.p',
                            expert_trajectory_filename=log_dir + '/expert_trajectory.p',
                            sim=sim,
                            s_0=env_args['s_0'],
                            reward_function=reward_function)
                    objects = []
                    with (open(log_dir + '/expert_trajectory.p', "rb")) as openfile:
                        while True:
                            try:
                                objects.append(pickle.load(openfile))
                            except EOFError:
                                break
                    #print(objects)
    run_experiment(
        run_task,
        **run_experiment_args,
    )

if __name__ == '__main__':
    fire.Fire()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun May 20 00:53:34 2018

@author: abhay
"""

import bs4 as bs
import urllib.request
import pandas as pd

##------------------------data to fetch from the website##################

details=['Name of the Company','Contact Person','Designation','Street Address','City','State'
         ,'Pincode','Email','Phone','Mobile','Fax','Website']

Na=[]
Contact=[]
De=[]
Street=[]
City=[]
State=[]
Pincode=[]
Email=[]
Phone=[]
Mobile=[]
Fax=[]
Website=[]

link=pd.read_csv('website_list.csv')

print(link['Address'].head())

#link=['http://www.iato.in/members/view/1925 ',
#      'http://www.iato.in/members/view/11402',
#      'http://www.iato.in/members/view/1844',
#      'http://www.iato.in/members/view/2053',
#      'http://www.iato.in/members/view/314']

for url in link['Address']:
    source=urllib.request.urlopen(url).read()
    soup = bs.BeautifulSoup(source,'html5lib')
    te=[]
    for p_tags in  soup.find_all('p'):
        te.append(p_tags.text)
        print(p_tags.text)

    cont=[]
    for t in te:
        cont.append(t.split(':'))

    for i in range(0,len(cont)):
       if details[0] in cont[i]:
           Na.append(cont[i][1])
       if details[1] in cont[i]:
           Contact.append(cont[i][1])
       if details[2] in cont[i]:
           De.append(cont[i][1])
       if details[3] in cont[i]:
           Street.append(cont[i][1])
       if details[4] in cont[i]:
           City.append(cont[i][1])
       if details[5] in cont[i]:
           State.append(cont[i][1])
       if details[6] in cont[i]:
           Pincode.append(cont[i][1])
       if details[7] in cont[i]:
           Email.append(cont[i][1])
       if details[8] in cont[i]:
           Phone.append(cont[i][1])
       if details[9] in cont[i]:
           Mobile.append(cont[i][1])
       if details[10] in cont[i]:
           Fax.append(cont[i][1])
       if details[11] in cont[i]:
           Website.append(cont[i][1])

del(Mobile[1659])
data={details[0]:Na,details[1]:Contact,details[2]:De,details[3]:Street,details[4]:City,
      details[5]:State,details[6]:Pincode,details[7]:Email,details[8]:Phone,details[9]:Mobile,
       details[10]:Fax,details[11]:Website }

df=pd.DataFrame(data)
df.to_csv('content_deatils.csv')


"""
This code is supported by the website: https://www.guanjihuan.com
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/1247
"""

import random
import math
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

def function(x):  # 期望样品的分布，target distribution function
    y = (norm.pdf(x, loc=2, scale=1)+norm.pdf(x, loc=-5, scale=1.5))/2   # loc代表了均值,scale代表标准差
    return y

T = 100000  # 取T个样品
pi = [0 for i in range(T)]  # 任意选定一个马尔科夫链初始状态
for t in np.arange(1, T):
    pi_star = np.random.uniform(-10, 10)  # a proposed distribution， 例如是均匀分布的，或者是一个依赖pi[t - 1]的分布
    alpha = min(1, (function(pi_star) / function(pi[t - 1])))  # 接收率
    u = random.uniform(0, 1)
    if u < alpha:
        pi[t] = pi_star    # 以alpha的概率接收转移
    else:
        pi[t] = pi[t - 1]  # 不接收转移

pi = np.array(pi)  # 转成numpy格式
print(pi.shape)  # 查看抽样样品的维度
plt.plot(pi, function(pi), '*')  # 画出抽样样品期望的分布   # 或用plt.scatter(pi, function(pi))
plt.hist(pi, bins=100, density=1, facecolor='red', alpha=0.7)   # 画出抽样样品的分布   # bins是分布柱子的个数，density是归一化，后面两个参数是管颜色的
plt.show()


from collections import deque

# it's basically a double ended queue
# so you can append and pop from both sides

d = deque()

d.append(1)
d.append(2)
d.appendleft(0)

print(d[0])


#!/usr/bin/python3
"""Starts a Flask application on 0.0.0.0:5000"""

from flask import Flask, abort, render_template

app = Flask(__name__)

@app.route('/', strict_slashes=False)
def hello():
    """Returns a simple greeting page"""

    return ('Hello HBNB!')

@app.route('/hbnb', strict_slashes=False)
def hbnb():
    """Returns a page containing the string 'HBNB'"""

    return ('HBNB')

@app.route('/c/<text>', strict_slashes=False)
def dear_c(text):
    """Returns a page about C"""

    text = text.split('_')
    text = " ".join(text)

    return ("C {}".format(text))

@app.route('/python', strict_slashes=False)
@app.route('/python/<text>', strict_slashes=False)
def dear_python(text="is cool"):
    """Returns a page about Python"""

    if text != 'is cool':
        text = text.split('_')
        text = " ".join(text)
    return ("Python {}".format(text))

@app.route('/number/<n>', strict_slashes=False)
def is_number(n):
    """Checks if input is a number"""

    if n.isdigit():
        return ("{} is a number".format(n))
    else:
        abort(404)

@app.route('/number_template/<n>')
def is_number_template(n):
    """Checks if input is an integer and responds with a template"""

    if n.isdigit():
        return (render_template('5-number.html', n=n))
    else:
        abort(404)

@app.route('/number_odd_or_even/<n>')
def odd_or_even(n):
    """Returns if input is odd or even"""

    if n.isdigit():
        if int(n) % 2:
            return (render_template(
                '6-number_odd_or_even.html', n=n,  mod='odd'))
        else:
            return (render_template(
                '6-number_odd_or_even.html', n=n, mod='even'))
    else:
        abort(404)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')


#! /usr/bin/python3

from string import ascii_lowercase
from itertools import combinations
from math import factorial
from functools import lru_cache

letters = [x for x in ascii_lowercase]

@lru_cache(maxsize=None)
def binomial(x, y):
	return int(factorial(x)/(factorial(y)*factorial(x-y)))

#for length in range(3,26):
#	print( length, len( list( combinations( letters, length))))

#check now if all 1 height words can be generated with neighbour transpotions and rotations on the ordered words

#def is1Height( word):
#	vals = list(map(ord, word))
#	flagged = False
#	for i in range( len( vals)-1):
#		if vals[i+1] < vals[i]:
#			if not flagged:
#				flagged = True
#			else:
#				return False #at least two heights
#	return flagged
#
#
#letters = [x for x in "abcd"]
#from itertools import permutations
#for p in permutations( letters):
#	word = "".join( p)
#	if is1Height( word):
#		print( word)

def p(n):
	p = 0
	for l1 in range(1,n):
		l2 = n - l1
		for w1 in combinations(letters, l1):
			complement = [l for l in letters if l not in w1]
			#second loop could be replaced by some smart counting
			#for w2 in combinations(complement, l2):
			#	if w1[-1] > w2[0]:
			#		p += 1
			for index, l in enumerate(complement):#[:-l2+1]):
				if w1[-1] > l and len(complement) - 1 - index >= l2 - 1:
					p += binomial( len(complement) - 1 - index, l2-1)
	return p

for n in range(15,20):
	print( n, p(n))

#solve by splitting with combinations part1 (length 1) + part2 (length 2) with height between part1 and part2


import nltk

def load_and_tag_words(filename):
    words = []
    with open(filename, 'r') as words_file:
        for line in words_file:
            words.append(line.strip())

    tags = []
    for word in words:
        text = nltk.word_tokenize(word)
        a = nltk.pos_tag(text)
        for item in a:
            tags.append(f'1    {item[1]} {item[0]}')

    tags.sort()
    return tags

if __name__ == "__main__":
    tags = load_and_tag_words('allowed_words.txt')
    with open('G_Vocab.gr', 'w') as vocab_file:
        for tag in tags:
            vocab_file.write(f'{tag}\n')


import time
import datetime
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.ticker as ticker
import pandas as pd

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.uic import *

class GraphWindow(QDialog):
    def __init__(self, input_df):
        super(GraphWindow, self).__init__()
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.resize(1200, 800)
        self.setWindowTitle("Plot of the Working time")
        self.setWindowFlags(Qt.Window | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
        self.setModal(True)

        # a figure instance to plot on
        plt.rcParams["date.autoformatter.day"] = "%y/%m/%d"
        self.figure = plt.figure(figsize=(13, 8), dpi=128)
        # adds a button to go back
        self.backbutton = QPushButton("< Back")
        # sets the minimum size and the fontsize
        self.backbutton.setMinimumSize(QSize(0, 50))
        font = QFont()
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.backbutton.setFont(font)
        self.backbutton.clicked.connect(lambda: self.close())
        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)
        # set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.backbutton)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        # clears the old values and then adds a subplot to isert all the data
        self.figure.clear()
        ax = self.figure.add_subplot(111)

        df = input_df.copy()
        df["pause"] = df["pause"] / 60
        df["work"] = df["worktime"] / 60 - df["pause"]
        df["overtime"] = df["work"] - 8
        df["overtime"] = df["overtime"].clip(lower=0)
        df["work"] = df["work"].clip(upper=8, lower=0)
        plotdf = df[["work", "overtime", "pause"]]
        plotdf.plot.bar(stacked=True, ax=ax, width=0.8, color=["#2693ff", "#ff4e26", "#25cf5e"])
        ax.legend(fancybox=True, framealpha=0.7)
        plt.axhline(8, color="k", ls="--", lw=1)
        ax.xaxis.get_label().set_visible(False)

        ticklabels = [""] * len(df.index)
        ticklabels[::2] = [item.strftime("%y/%m/%d") for item in df.index[::2]]
        ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))
        plt.gcf().autofmt_xdate()

        # plt.tight_layout()
        self.canvas.draw()


# -*- coding: utf-8 -*-
"""
Created on 20.04.2023

@author: Roman A.

Create and save plots of photometry performed on 1-minute stacked frames

"""

import matplotlib.pyplot as plt
import pathlib
import numpy as np
import pandas as pd
import linecache
import matplotlib.dates as mdates
from tqdm import trange
from matplotlib.dates import DateFormatter
from astropy import wcs, stats

def get_Lightcurve(file):
    ''' retrieve lightcurve data from .txt files
    input: file name (pathlib.Path object)
    output: lightcurve (dict) '''
    # print(file)
    lightcurve = {}

    flux = pd.read_csv(file, delim_whitespace = True, names = ['filename', 'time', 'flux', 'flux_err', 'rel_flux', 'x', 'y'], comment = '#')

    coords = linecache.getline(str(file),6).split(': ')[1].split(' ')
    # med = np.median(flux['rel_flux'])                                   #median flux
    # std = np.std(flux['rel_flux'])

    med=stats.sigma_clipped_stats(flux['rel_flux'])[1]
    std=stats.sigma_clipped_stats(flux['rel_flux'])[2]
    try:
        SNR = med/std
    except:
        SNR=0

    lightcurve = {'flux': flux, 'coords': coords, 'median': med, 'std': std, 'SNR': SNR}
    return lightcurve

def lookLightcurve(star, lightcurve, save_path):
    ''' used to plot lightcurve against time
    input: star number (str), star lightcurve (dict),

    output: None'''

    #get star info
    med = lightcurve['median']
    std = lightcurve['std']
    flux = lightcurve['flux']
    coords = lightcurve['coords']
    SNR = lightcurve['SNR']

    seconds=flux['time']

    fig, ax1 = plt.subplots()

    ax1.scatter(seconds, flux['rel_flux']) #can also plot raw flux
    ax1.hlines(med, min(seconds), max(seconds), color = 'black', label = 'median: %.5f' % med)
    ax1.hlines(med + std, min(seconds), max(seconds), linestyle = '--', color = 'black', label = 'stddev: %.5f' % std)
    ax1.hlines(med - std, min(seconds), max(seconds), linestyle = '--', color = 'black')
    ax1.set_xlabel('time (UT)')
    ax1.set_ylabel('relative counts')
    ax1.set_title('Star #%s [%.1f, %.1f], SNR = %.2f' %(star, float(coords[0]), float(coords[1]), SNR))
    xfmt = DateFormatter('%H:%M') #time format works even for JD
    ax1.xaxis.set_major_formatter(xfmt)
    ax1.legend()
    directory = save_path
    plt.savefig(directory.joinpath(str(star) + '_'+telescope+'_rel.png'), bbox_inches = 'tight',dpi=500)
    # plt.show()
    plt.close()

if __name__ == '__main__':
    base_path=pathlib.Path('/','E:')
    field_name='field6'
    obs_date='2023-04-10'
    telescope='Green'
    lc_path=base_path.joinpath('/StackedData',field_name,obs_date, telescope, 'lightcurves')#path where photometry results are
    stars=[f for f in lc_path.iterdir() if '.txt' in f.name]#list of txts with photometry data
    rel_SNRs=[]#for statistics only
    rel_MEDs=[]#for statistics only
    for i in trange(len(stars)):

        lightcurve = get_Lightcurve(stars[i]) #dictionary with photometric results
        # flux = lightcurve['flux']
        # clipped_flux=stats.sigma_clip(flux['flux'],masked=False,axis=0)
        # rel_SNRs.append(lightcurve['SNR'])
        # rel_MEDs.append(lightcurve['median'])
        lookLightcurve(stars[i].name.split('_')[0], lightcurve, lc_path) #plot each star


# import lib
import streamlit as st
import numpy as np
from PIL import Image
from keras.preprocessing.image import img_to_array
from keras.models import load_model
import requests
from bs4 import BeautifulSoup
# import io

labels = {0: 'apple', 1: 'banana', 2: 'beetroot', 3: 'bell pepper', 4: 'cabbage', 5: 'capsicum', 6: 'carrot',
          7: 'cauliflower', 8: 'chilli pepper', 9: 'corn', 10: 'cucumber', 11: 'eggplant', 12: 'garlic', 13: 'ginger',
          14: 'grapes', 15: 'jalepeno', 16: 'kiwi', 17: 'lemon', 18: 'lettuce', 19: 'mango', 20: 'onion', 21: 'orange',
          22: 'paprika', 23: 'pear', 24: 'peas', 25: 'pineapple', 26: 'pomegranate', 27: 'potato', 28: 'raddish',
          29: 'soy beans', 30: 'spinach', 31: 'sweetcorn', 32: 'sweetpotato', 33: 'tomato', 34: 'turnip', 35: 'watermelon'}

fruits = [ 'banana', 'apple', 'pear', 'grapes', 'orange', 'kiwi', 'watermelon', 'pomegranate', 'pineapple', 'mango']

vegetables = ['cucumber', 'carrot', 'capsicum', 'onion', 'potato', 'lemon', 'tomato', 'raddish', 'beetroot', 'cabbage', 'lettuce', 'spinach', 'soy bean', 'cauliflower', 'bell pepper', 'chilli pepper', 'turnip', 'corn', 'sweetcorn', 'sweet potato', 'paprika', 'jalepeño', 'ginger', 'garlic', 'peas', 'eggplant']

model = load_model("FruitModel.h5")

def fetch_calories(prediction):
    try:
        url = 'https://www.google.com/search?&q=calories in a ' + prediction
        headers = {'User-Agent': 'Mozilla/5.0'}
        req = requests.get(url, headers=headers).text
        scrap = BeautifulSoup(req, 'html.parser')

        # Debugging: Print the HTML to check if it's what you expect
        # print(scrap.prettify())

        # calories = scrap.find("div", class_="BNeawe iBp4i AP7Wnd")
        calories = scrap.find("div", class_="Z0LcW.an_fna")
        if calories:
            return calories.text
        else:
            st.error("Sorry! Element not found.")
            return None

    except Exception as e:
        st.error("Sorry! Calories not found.")
        print(e)  # Debugging: Print exception to see what went wrong

def process_image(image_stream):
    image = Image.open(image_stream).resize((224, 224))
    img_array = img_to_array(image)
    img_array = img_array / 255
    img_array = np.expand_dims(img_array, axis=0)
    prediction = model.predict(img_array)
    predicted_class = np.argmax(prediction, axis=-1)[0]
    return labels[predicted_class].capitalize()

def main():
    st.title("Fruit and Vegetable Calories Predictor")
    st.subheader("This is a simple web app to predict calories of fruits and vegetables")
    st.write("Please upload an image of a fruit or vegetable")

    image_file = st.file_uploader("Upload Image", type=["png", "jpg", "jpeg"])
    if image_file:
        img = Image.open(image_file).resize((250, 250))
        st.image(img, use_column_width=True)

        result = process_image(image_file)
        category = "Vegetables" if result.lower() in vegetables else "Fruits"

        st.info(f"Category : {category}")
        st.success(f"The predicted class is: {result}")

        calories = fetch_calories(result)
        if calories:
            st.warning(f"Calories : {calories}")

if __name__ == "__main__":
    main()


import os
import torch
import torchvision
from torchsummary import summary
from matplotlib import pyplot as plt
from torch.utils.data import DataLoader as dataloader
from tensorboardX import SummaryWriter
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim
import torch.nn as nn
import numpy as np
import time

# hyper parameters
path_model = "./checkpoint/"
batch_size = 512
epochs = 50
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])
# sampler = torch.utils.data.SubsetRandomSampler(indices=list(range(2000)))

# download mnist dataset
data_train = torchvision.datasets.MNIST(root='./data/',train=True,download=True,transform=transform)
data_test = torchvision.datasets.MNIST(root='./data/',train=False,download=True,transform=transform)

class_names = data_train.classes  # 获取数据集的分类信息 返回一个字典
# load dataset
data_train = dataloader(dataset=data_train,batch_size=batch_size,shuffle=False)
data_test = dataloader(dataset=data_test,batch_size=batch_size,shuffle=True)

"""
# 查看测试数据的构成
examples = enumerate(data_test)
batch_idx, (example_data, example_targets) = next(examples)
print(example_targets)
print(example_data.shape)

fig = plt.figure()
for i in range(6):
  plt.subplot(2,3,i+1)
  plt.tight_layout()
  plt.imshow(example_data[i][0], cmap='gray', interpolation='none')
  plt.title("Ground Truth: {}".format(example_targets[i]))
  plt.xticks([])
  plt.yticks([])
plt.show()
"""
def test():
    net.eval()  # 切换到测试模式
    test_correct_num = 0
    with torch.no_grad():   # 不更新参数

        for batch_idx,(data,target) in enumerate(data_test):
            # data = data.to(device)
            # target = target.to(device)
            output = net(data) # 正向传播得到预测值
            _, pred = torch.max(output.data, 1)
            test_correct_num += torch.sum(pred==target).item()
            print("Test Epoch:{} [{}/{} ({:.0f}%)]\t acc:{:.2f}".format(epoch,batch_idx*batch_size,len(data_test.dataset),
                                                 100. * batch_size*batch_idx/len(data_test.dataset),test_correct_num/len(data_test.dataset)))
def train():

    for batch_idx, (data, target) in enumerate(data_train):
        # 清除grad累积值
        optimizer.zero_grad()
        # 读取dataloader中的数据，前半部分是tensor变量，后半部分是真实label
        data = data.to(device)
        target = target.to(device)
        # forward之后得到预测值
        output = net(data)
        # 计算loss
        loss = cost_fun(output, target)
        # backward
        loss.backward()
        # 收集一组新的梯度，并使用optimizer.step()将其传播回每个网络参数
        optimizer.step()
        # 给出loss和acc
        train_loss.append(loss)
        _, pred = torch.max(output.data, 1)
        correct_num = torch.sum(pred == target).item()
        train_acc.append(correct_num / batch_size)
        print("Train Epoch:{}[{}/{} ({:.0f}%)]\t Loss:{:.6f} acc:{:.2f}".format(epoch, batch_idx * batch_size,
               len(data_train.dataset),100. * batch_size * batch_idx / len(data_train.dataset), loss.item(),correct_num / batch_size))

def save_state():
    print('===> Saving weights...')
    state = {
        'state': net.state_dict(),
        'epoch': epoch  # 将epoch一并保存
    }
    if not os.path.isdir('checkpoint'):
        os.mkdir('./checkpoint')
    torch.save(state, path_model + 'Epoch:' + str(epoch) + ' Loss:' + str(train_loss[-1].item()) + '.pth')

def predict():
    state_path = './checkpoint/***' #  ***为指定加载的权重文件名称
    print('===> Loading weights : ' + state_path)
    torch.load(state_path)  # 加载最后训练出的权重
    # 从测试集中选取一个batch做预测
    pred_test = enumerate(data_test)
    batch_idx, (pred_data, pred_gt) = next(pred_test)
    output = net(pred_data)
    _, pred = torch.max(output.data, 1) # 得到预测值
    print("ground truth: ",pred_gt)
    print("predict value: ",pred)

# 构建网络
class LeNet(nn.Module): 					# 继承于nn.Module这个父类
    def __init__(self):						# 初始化网络结构
        super(LeNet, self).__init__()    	# 多继承需用到super函数
        self.block_1 = nn.Sequential(
            nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, stride=1, padding=2),  # 输出为6*28*28
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),  # 输出为6*14*14
            nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1),  # 输出为16*10*10
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),  # 输出为16*5*5
        )
        self.block_2 = nn.Sequential(
            nn.Linear(16*5*5, 120),
            nn.ReLU(),
            nn.Linear(120, 84),
            nn.ReLU(),
            nn.Linear(84, 10),
        )

    def forward(self, x):  # 正向传播过程
        x = self.block_1(x)
        x = x.view(-1,16*5*5)
        x = self.block_2(x)
        return

# 显示各层参数量和训练过程batch所占内存大小
def variaes_show():
    net = LeNet()
    data_input = Variable(torch.randn(16,1,28,28))
    print(data_input.size())
    net(data_input)
    print(summary(net,(1,28,28)))
if __name__ == '__main__':
    writer = SummaryWriter('logs')
    device = torch.device('cuda:0')
    net = LeNet()  # 实例化网络
    # data_input = Variable(torch.randn(16,1,28,28))
    # print(net(data_input))
    net.to(device) # 将参数送入GPU中
    cost_fun = nn.CrossEntropyLoss()
    # optim
    optimizer = torch.optim.SGD(net.parameters(), lr=1e-3, momentum=0.95, weight_decay=1e-3)

    # train
    for epoch in range(epochs):

        # train
        train_loss = []
        train_acc = []
        # train
        train()
        writer.add_scalar('Train/Loss', train_loss[-2].item(), epoch)
        writer.add_scalar('Train/Acc', train_acc[-2], epoch)

        # ----------------------------------------- #
        # save_state
        # ----------------------------------------- #
        print('===> Saving models...')
        state = {
            'state': net.state_dict(),
            'epoch': epoch  # 将epoch一并保存
        }
        if not os.path.isdir('checkpoint'):
            os.mkdir('./checkpoint')
        torch.save(state, path_model + 'Epoch:' + str(epoch) + ' Loss:'+ str(train_loss[-1].item()) + '.pth')

        # ----------------------------------------- #
        # test
        # ----------------------------------------- #
        test()
    writer.close()

    # ----------------------------------------- #
    # 加载指定的weights进行预测
    # ----------------------------------------- #
    # predict()