import urllib.request
try:
    fhand = urllib.request.urlopen("https://www.python.org/")
    # print(type(fhand))
    print(fhand.read())
    count = dict()
    for line in fhand:
        words = line.decode().strip()
        for word in words:
            count[word] = count.get(word, 0)+1

    # print(count)
    fhand.close()

except Exception as e:
    print(e)
    print("WEb page not found")
    exit()


#!/usr/bin/env python

import argparse
from pwn import *
import re

########################################################################
#
# boilerplate script setup
#
# command line arguments
CMDLINE = None

def parse_cmdline():

	parser = argparse.ArgumentParser(description="AdventOfCode 2018 - day 24")
	parser.add_argument('-t', '--testing', action='store_true', default=False)
	parser.add_argument('-v', '--verbose', action='store_true', default=False)
	parser.add_argument('-p', '--part')
	global CMDLINE
	CMDLINE = parser.parse_args()

	context.log_level = 'debug' if CMDLINE.verbose else 'info'

def get_input():

	filename = "./input" if not CMDLINE.testing else "./input-test"
	with open(filename, "r") as infile:

		groups = []
		curren_army = None

		lines = infile.readlines()
		for ix, l in enumerate(lines):

			if re.match("^$", l):
				current_army = None
				continue

			m = re.match("(.*):", l)
			if m:
				current_army = m.group(1)
				log.info("current army: %s", current_army)
				continue
			else:
				groups.append(Group(current_army, l))

		return groups

def do_part(part):
    if not CMDLINE.part or CMDLINE.part == part:
        return True
    else:
        return False

########################################################################
#
# Classes

_counts = {}

class Group:

	def __init__(self, army, line):

		m = re.match("(\d+) units each with (\d+) hit points(.*)with an attack that does (\d+) (.*) damage at initiative (\d+)", line)
		if m:
			self.army = army
			self.count = int(m.group(1))
			self.hp = int(m.group(2))
			self.ap = int(m.group(4))
			self.type = m.group(5).replace(' ', '')
			self.initiative = int(m.group(6))
			self.weaknesses = ""
			self.immunities = ""

			# parse weaknesses and immunitities (wni)
			wnis = m.group(3).replace(' (', '').replace(') ', '')
			if wnis != ' ':
				wnis = wnis.split('; ')
				for wni in wnis:
					m = re.match("(\w+) to (.*)", wni)
					if m:
						which = m.group(1)
						attacks = m.group(2)
						if which == 'weak':
							self.weaknesses = attacks
						elif which == 'immune':
							self.immunities = attacks
						else:
							raise Exception("unexpected w&i: {}; which: {}".format(wni, which))
					else:
						raise Exception("no w&i found in: {}".format(wni))

			_counts[army] = _counts[army] + 1 if army in _counts else 1
			self.name = "{} {}".format(army, _counts[army])

			# state params used during battles
			self.target = None
			self.targeted = False
			self.kills = 0

		else:
			raise Exception("unexpected format: %s", line)

	''' effective power = # units x attack power / unit '''
	def effective_power(self):
		return self.count * self.ap

	def does_damages_to(self, target):

		damages = self.effective_power()
		if self.type in target.immunities:
			damages = 0
		elif self.type in target.weaknesses:
			damages *= 2

		return damages

	def __repr__(self):
		m = ''
		m += "name: {}".format(self.name)
		m += ", count: {}".format(self.count)
		m += ", hp: {}".format(self.hp)
		m += ", ep: {}".format(self.effective_power())
		m += ", ap: {}".format(self.ap)
		m += ", type: {}".format(self.type)
		m += ", weaknesses: {}".format(self.weaknesses)
		m += ", immunities: {}".format(self.immunities)
		m += ", initiative: {}".format(self.initiative)
		return m

''' Comparator for determining which group goes first in selecting targets
Groups are selected by:
	1. highest effective power, then by
	2. initiative
'''
def compare_groups(a, b):

	ep_a = a.effective_power()
	ep_b = b.effective_power()
	if ep_a != ep_b:
		return ep_b - ep_a
	else:
		return b.initiative - a.initiative

''' Comparator for determining target selections order:
Targets are selected by:
	1. highest expected damage, then by
	2. highest effective power, then by
	3. highest initiative
'''
def compare_targets(a, b):
	da = a.does_damages_to(b)
	db = b.does_damages_to(a)

	if da != db:
		return da - db
	else:
		return compare(groups(a, b))

########################################################################
#
# PART A

def do_partA():

	log.info("AdventOfCode 2018 - day 24 part A")

	groups = get_input()
	while True:

		# sort the groups into targeting order
		groups.sort(key=lambda x: (x.effective_power(), x.initiative), reverse=True)
		log.debug("targt selection order:")
		for g in groups:
			log.debug("  %s: ep:%d, inititive: %d", g.name, g.effective_power(), g.initiative)
			g.target = None
			g.targeted = False
			g.kills = 0

		log.debug("")

		# select the targets
		for g in groups:
			targets = [ t for t in groups if ((t.count > 0) and (t.army != g.army) and not t.targeted) ]
			#log.debug("attacker: %s", g.name)
			#log.debug("targets : %s", [ t.name for t in targets ])

			best_damage = 0
			best_choice = None
			for t in targets:
				damage = g.does_damages_to(t)
				if damage == 0:
					continue
				elif damage > best_damage:
					g.target = t
					best_damage = damage
				elif damage == best_damage:
					if t.initiative < g.target.initiative:
						g.target = t
			if g.target is not None:
				g.target.targeted = True

			#log.debug("%s targets %s for %d damage", g.name, g.target.name, best_damage)
			#log.debug("")

		attacks = sorted([ g for g in groups if g.target != None ], key= lambda x: x.initiative, reverse=True)
		for a in attacks:
			damages = a.does_damages_to(a.target)
			units = min(damages/a.target.hp, a.target.count)
			a.target.count -= units
			log.debug("%s attacks %s killing %d units (damage: %d, hp: %d)", a.name, a.target.name, units, damages, a.target.hp)
		log.debug("")

		# check to see if anyone won
		armies = set([ g.army for g in groups if g.count > 0 ])
		log.debug("armies: %s", armies)
		if len(armies) == 1:
			total = 0
			for g in groups:
				log.debug("%s: %d", g.name, g.count)
				total += g.count
			log.success(total)
			return

########################################################################
#
# PART B

def do_partB():

	log.info("AdventOfCode 2018 - day 24 part B")
	log.failure("not implemented")

if __name__ == "__main__":

	parse_cmdline()

	if do_part('a'):
		do_partA()

	if do_part('b'):
		do_partB()


# Credit for this code goes to the following three sources:
# https://medium.com/@m.alzantot/deep-reinforcement-learning-demysitifed-episode-2-policy-iteration-value-iteration-and-q-978f9e89ddaa
# https://medium.com/swlh/introduction-to-reinforcement-learning-coding-q-learning-part-3-9778366a41c0
# https://towardsdatascience.com/reinforcement-learning-with-openai-d445c2c687d2

import numpy as np
import timeit
import gym

def run_episode(env, q_table, max_steps, gamma):
    obs = env.reset()
    total_reward = 0
    step_idx = 0
    for _ in range(max_steps):
        action = np.argmax(q_table[obs, :])
        obs, reward, done, _ = env.step(action)
        total_reward += gamma ** step_idx * reward
        step_idx += 1
        if done:
            break

    return total_reward

def get_q_table(env, epsilon, epis, max_steps, lr_rate, gamma):
    Q = np.zeros((env.observation_space.n, env.action_space.n))
    rev_list = []

    # Start
    for i in range(epis):
        s = env.reset()
        rAll = 0
        t = 0

        while t < max_steps:
            a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))

            if np.random.uniform(0, 1) < epsilon:
                a = env.action_space.sample()

            s1, r, done, _ = env.step(a)

            Q[s,a] = Q[s,a] + lr_rate*(r + gamma*np.max(Q[s1,:]) - Q[s,a])

            s = s1
            rAll += r

            t += 1

            if done:
                break

        rev_list.append(rAll)

    return Q

def run_q_learning(env_name, epsilon=0, lr_rate = 0.81, gamma = 1.0, total_episodes=10000, max_steps=1000):
    env = gym.make(env_name)
    env.seed(99)
    np.random.seed(99)

    start = timeit.default_timer()

    q_table = get_q_table(env, epsilon, total_episodes, max_steps, lr_rate, gamma)

    stop = timeit.default_timer()
    total_time = stop - start

    scores = [run_episode(env, q_table, max_steps, gamma) for _ in range(1000)]
    # print("Average score of solution = ", np.mean(scores))
    # print('Time = ', total_time)

    return scores, total_time

if __name__ == '__main__':
    run_q_learning('FrozenLake-v0')


# -*- coding: utf-8 -*-
"""
Created on Tues Jan 26 2021
License is GNU GPLv2
@author: Jay Unruh
"""
from napari_plugin_engine import napari_hook_implementation
import importroi
import numpy as np
import os

def roi_file_reader(path):
    decoder=importroi.RoiDecoder()
    if(path.endswith('.zip')):
        rois=decoder.readzip(path)
    else:
        rois=[decoder.readroi(path)]
    rtype=rois[0].getType()
    if(rtype=='rect'): rtype='rectangle'
    thickness=rois[0].thickness
    rois2=[rois[i].getNapariArray() for i in range(len(rois))]
    if(rtype=='point'):
        params={
            "name":os.path.basename(path),
            "edge_color":'red',
            "edge_width": thickness,
            "opacity": 0.3,
        }
        return [(rois2,params,'points')]
    else:
        params={
            "name":os.path.basename(path),
            "shape_type":rtype,
            "edge_color":'red',
            "edge_width": thickness,
            "opacity": 0.3,
        }
        return [(rois2,params,'shapes')]

@napari_hook_implementation
def napari_get_reader(path):
    if isinstance(path,str) and (path.lower().endswith('.zip') or path.lower().endswith('.roi')):
        return roi_file_reader
    return None


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Oct 16 19:20:27 2022

@author: cmr1
"""

import re

matches = 0
cigartally = 0
mismatches = 1
identity = 0

match = (re.findall(r'\d+[A-Z]', "100S84M16S"))
if match != None:
    for element in match:
        print(element)
        if element[-1] == "M":
            print("matches")
            cigartally += int(element[:-1])
        else:
            mismatches += int(element[:-1])
#code lifted straight from linked resource "on calculating percent identity from SAM files"
identity = 100 * (matches / (matches + mismatches))

print(identity)
print(cigartally)


# coding: utf-8

"""
    MongoDB Atlas Administration API

    The MongoDB Atlas Administration API allows developers to manage all components in MongoDB Atlas. To learn more, review the [Administration API overview](https://www.mongodb.com/docs/atlas/api/atlas-admin-api/). This OpenAPI specification covers all of the collections with the exception of Alerts, Alert Configurations, and Events. Refer to the [legacy documentation](https://www.mongodb.com/docs/atlas/reference/api-resources/) for the specifications of these resources.  # noqa: E501

    The version of the OpenAPI document: 2.0
    Generated by: https://openapi-generator.tech
"""

from __future__ import annotations
from inspect import getfullargspec
import json
import pprint
import re  # noqa: F401

from typing import Any, List, Optional
from pydantic import BaseModel, Field, StrictStr, ValidationError, validator
from atlas.models.data_lake_atlas_store import DataLakeAtlasStore
from atlas.models.data_lake_http_store import DataLakeHTTPStore
from atlas.models.data_lake_online_archive_store import DataLakeOnlineArchiveStore
from atlas.models.data_lake_s3_store import DataLakeS3Store
from typing import Any, List
from pydantic import StrictStr, Field

DATALAKESTORE_ONE_OF_SCHEMAS = ["DataLakeAtlasStore", "DataLakeHTTPStore", "DataLakeOnlineArchiveStore", "DataLakeS3Store"]

class DataLakeStore(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """
    # data type: DataLakeS3Store
    oneof_schema_1_validator: Optional[DataLakeS3Store] = None
    # data type: DataLakeOnlineArchiveStore
    oneof_schema_2_validator: Optional[DataLakeOnlineArchiveStore] = None
    # data type: DataLakeAtlasStore
    oneof_schema_3_validator: Optional[DataLakeAtlasStore] = None
    # data type: DataLakeHTTPStore
    oneof_schema_4_validator: Optional[DataLakeHTTPStore] = None
    actual_instance: Any
    one_of_schemas: List[str] = Field(DATALAKESTORE_ONE_OF_SCHEMAS, const=True)

    class Config:
        validate_assignment = True

    discriminator_value_class_map = {
    }

    @validator('actual_instance')
    def actual_instance_must_validate_oneof(cls, v):
        instance = cls()
        error_messages = []
        match = 0
        # validate data type: DataLakeS3Store
        if type(v) is not DataLakeS3Store:
            error_messages.append(f"Error! Input type `{type(v)}` is not `DataLakeS3Store`")
        else:
            match += 1

        # validate data type: DataLakeOnlineArchiveStore
        if type(v) is not DataLakeOnlineArchiveStore:
            error_messages.append(f"Error! Input type `{type(v)}` is not `DataLakeOnlineArchiveStore`")
        else:
            match += 1

        # validate data type: DataLakeAtlasStore
        if type(v) is not DataLakeAtlasStore:
            error_messages.append(f"Error! Input type `{type(v)}` is not `DataLakeAtlasStore`")
        else:
            match += 1

        # validate data type: DataLakeHTTPStore
        if type(v) is not DataLakeHTTPStore:
            error_messages.append(f"Error! Input type `{type(v)}` is not `DataLakeHTTPStore`")
        else:
            match += 1

        if match > 1:
            # more than 1 match
            raise ValueError("Multiple matches found when deserializing the JSON string into DataLakeStore with oneOf schemas: DataLakeAtlasStore, DataLakeHTTPStore, DataLakeOnlineArchiveStore, DataLakeS3Store. Details: " + ", ".join(error_messages))
        elif match == 0:
            # no match
            raise ValueError("No match found when deserializing the JSON string into DataLakeStore with oneOf schemas: DataLakeAtlasStore, DataLakeHTTPStore, DataLakeOnlineArchiveStore, DataLakeS3Store. Details: " + ", ".join(error_messages))
        else:
            return v

    @classmethod
    def from_dict(cls, obj: dict) -> DataLakeStore:
        return cls.from_json(json.dumps(obj))

    @classmethod
    def from_json(cls, json_str: str) -> DataLakeStore:
        """Returns the object represented by the json string"""
        instance = cls()
        error_messages = []
        match = 0

        # use oneOf discriminator to lookup the data type
        _data_type = json.loads(json_str).get("provider")
        if not _data_type:
            raise ValueError("Failed to lookup data type from the field `provider` in the input.")

        # check if data type is `DataLakeAtlasStore`
        if _data_type == "DataLakeAtlasStore":
            instance.actual_instance = DataLakeAtlasStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeHTTPStore`
        if _data_type == "DataLakeHTTPStore":
            instance.actual_instance = DataLakeHTTPStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeOnlineArchiveStore`
        if _data_type == "DataLakeOnlineArchiveStore":
            instance.actual_instance = DataLakeOnlineArchiveStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeS3Store`
        if _data_type == "DataLakeS3Store":
            instance.actual_instance = DataLakeS3Store.from_json(json_str)
            return instance

        # check if data type is `DataLakeAtlasStore`
        if _data_type == "atlas":
            instance.actual_instance = DataLakeAtlasStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeHTTPStore`
        if _data_type == "http":
            instance.actual_instance = DataLakeHTTPStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeOnlineArchiveStore`
        if _data_type == "online_archive":
            instance.actual_instance = DataLakeOnlineArchiveStore.from_json(json_str)
            return instance

        # check if data type is `DataLakeS3Store`
        if _data_type == "s3":
            instance.actual_instance = DataLakeS3Store.from_json(json_str)
            return instance

        # deserialize data into DataLakeS3Store
        try:
            instance.actual_instance = DataLakeS3Store.from_json(json_str)
            match += 1
        except ValidationError as e:
            error_messages.append(str(e))
        # deserialize data into DataLakeOnlineArchiveStore
        try:
            instance.actual_instance = DataLakeOnlineArchiveStore.from_json(json_str)
            match += 1
        except ValidationError as e:
            error_messages.append(str(e))
        # deserialize data into DataLakeAtlasStore
        try:
            instance.actual_instance = DataLakeAtlasStore.from_json(json_str)
            match += 1
        except ValidationError as e:
            error_messages.append(str(e))
        # deserialize data into DataLakeHTTPStore
        try:
            instance.actual_instance = DataLakeHTTPStore.from_json(json_str)
            match += 1
        except ValidationError as e:
            error_messages.append(str(e))

        if match > 1:
            # more than 1 match
            raise ValueError("Multiple matches found when deserializing the JSON string into DataLakeStore with oneOf schemas: DataLakeAtlasStore, DataLakeHTTPStore, DataLakeOnlineArchiveStore, DataLakeS3Store. Details: " + ", ".join(error_messages))
        elif match == 0:
            # no match
            raise ValueError("No match found when deserializing the JSON string into DataLakeStore with oneOf schemas: DataLakeAtlasStore, DataLakeHTTPStore, DataLakeOnlineArchiveStore, DataLakeS3Store. Details: " + ", ".join(error_messages))
        else:
            return instance

    def to_json(self) -> str:
        """Returns the JSON representation of the actual instance"""
        if self.actual_instance is not None:
            return self.actual_instance.to_json()
        else:
            return "null"

    def to_dict(self) -> dict:
        """Returns the dict representation of the actual instance"""
        if self.actual_instance is not None:
            return self.actual_instance.to_dict()
        else:
            return dict()

    def to_str(self) -> str:
        """Returns the string representation of the actual instance"""
        return pprint.pformat(self.dict())


from rest_framework import viewsets
from api.v1.booking.serializers import BookingSerializer
from core.models import Booking
from drf_yasg2.utils import swagger_auto_schema
from drf_yasg2 import openapi

from django.http.response import JsonResponse
from rest_framework.exceptions import ValidationError
from services.email.send import send_email

import re

class BookingViewSet(viewsets.ModelViewSet):
    queryset = Booking.objects.all().order_by('-id')
    serializer_class = BookingSerializer
    permission_classes = []

    status_param = openapi.Parameter(
        'status', openapi.IN_QUERY, description="Enter status", type=openapi.TYPE_STRING)

    @swagger_auto_schema(manual_parameters=[status_param])
    def list(self, request, *args, **kwargs):
        queryset = self.queryset
        status = self.request.query_params.get('status', None)
        if status is not None:
            queryset = queryset.filter(status=status)
        page = self.paginate_queryset(queryset)
        serializer = BookingSerializer(page, many=True)
        response = self.get_paginated_response(serializer.data)
        return response

    response_schema_dict = {
        "200": openapi.Response(
            description="Success",
            examples={
                "application/json": {
                    "message": "Booking created successfully.",
                    "status": "True"
                }
            }
        ),
        "400": openapi.Response(
            description="Failed",
            examples={
                "application/json": {
                    "message": "Invalid arguments",
                    "status": "False"
                }
            }
        ),
        "400:Bad": openapi.Response(
            description="Failed",
            examples={
                "application/json": {
                    "message": "Phone is required.",
                    "status": "False"
                }
            }
        ),
    }

    @swagger_auto_schema(request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            'name': openapi.Schema(type=openapi.TYPE_STRING, description='string'),
            'phone': openapi.Schema(type=openapi.TYPE_STRING, description='string'),
            'email': openapi.Schema(type=openapi.TYPE_STRING, description='string'),
            'company': openapi.Schema(
                type=openapi.TYPE_STRING, description='string'),
            'status': openapi.Schema(
                type=openapi.TYPE_INTEGER, description='integer'),
            'category': openapi.Schema(
                type=openapi.TYPE_INTEGER, description='integer'),
        }
    ), responses=response_schema_dict)
    def create(self, request, *args, **kwargs):
        name = request.data.get('name', None)
        if not name:
            raise ValidationError({
                "status": 'False',
                "message": "Name is required."
            })
        phone = request.data.get('phone', None)
        if not phone:
            raise ValidationError({
                "status": 'False',
                "message": "Phone is required."
            })
        if phone:
            if len(phone) != 10:
                raise ValidationError({
                    "status": 'False',
                    "message": "Phone length should be 10 digits."
                })
        email = request.data.get('email', None)
        if not email:
            raise ValidationError({
                "status": 'False',
                "message": "Email is required"
            })
        if email:
            regex = '^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$'
            match = re.match(regex, email)
            if not match:
                raise ValidationError({
                    "status": 'False',
                    "message": "Email is Invalid"
                })
        company = request.data.get('company', None)
        category = request.data.get('category', None)
        booking_data = {
            "name": name,
            "phone": phone,
            "email": email,
            "company": company,
            "category": category,
        }
        serializer = BookingSerializer(data=booking_data)
        if serializer.is_valid():
            serializer.save()

            company_first_name = company.split(' ')[0]

            # mail to user
            send_email(
                "Activate your " + str(company_first_name) + " Employee Wallet",
                "booking_email",
                [email],
                'contact@dailysalary.in',
                None,
                name,
                company_first_name,
            )

            # mail to admin
            send_email(
                str(name) + " from " + str(company) + " wants to connect with you",
                "booking_admin_email",
                ['basuki@dailysalary.in', 'shantanu@dailysalary.in', 'ravi@dailysalary.in'],
                'contact@dailysalary.in',
                None,
                name,
                company,
                email,
                phone,
            )

            return JsonResponse({
                "status": 'True',
                "message": "Booking created successfully."
            })
        raise ValidationError({
            "status": 'False',
            "message": "Invalid arguments"
        })


"""
Module for managing platforms.
"""
import pygame

from spritesheet_functions import SpriteSheet
import constants
# from levels import mobs
# import bullet

# These constants define our platform types:
#   Name of file
#   X location of sprite
#   Y location of sprite
#   Width of sprite
#   Height of sprite

WORM            = (0,0,128,128)

class Enemy(pygame.sprite.Sprite):
    """ Platform the user can jump on """
    frames_r = []
    frames_l = []
    def __init__(self, sprite_sheet_data):
        """ Platform constructor. Assumes constructed with user passing in
            an array of 5 numbers like what's defined at the top of this
            code. """
        pygame.sprite.Sprite.__init__(self)

        sprite_sheet = SpriteSheet("img/worm_spritesheet.png")
        # Grab the image for this platform
        frame_1 = sprite_sheet.get_image(0,0,128,128)
        self.frames_r.append(frame_1)
        frame_2 = sprite_sheet.get_image(128, 0, 128, 128)
        self.frames_r.append(frame_2)

        frame_3 = sprite_sheet.get_image(0,0,128,128)
        frame_3 = pygame.transform.flip(frame_3, True, False)
        self.frames_l.append(frame_3)
        frame_4 = sprite_sheet.get_image(128, 0, 128, 128)
        frame_4 = pygame.transform.flip(frame_4, True, False)
        self.frames_l.append(frame_4)

        # self.image = pygame.transform.scale(self.image,(64,64))

        self.image = self.frames_l[0]

        # Set a reference to the image rect.
        self.rect = self.image.get_rect()

        self.index = 0

        self.counter = 0

class MovingEnemy(Enemy):
    """ This is a fancier platform that can actually move. """
    change_x = 0
    change_y = 0
    direction = "Right"

    boundary_top = 0
    boundary_bottom = 0
    boundary_left = 0
    boundary_right = 0
    player_hit = ""

    level = None
    player = None
    # max_pos_left = enemies[0][2]

    def update(self):
        """ Move the platform.
            If the player is in the way, it will shove the player
            out of the way. This does NOT handle what happens if a
            platform shoves a player into another object. Make sure
            moving platforms have clearance to push the player around
            or add code to handle what happens if they don't. """
        # Move left/right
        self.rect.x += self.change_x

        pos = self.rect.x + self.level.world_shift

        self.counter += 1           # COUNTER FOR ENEMY SPRITE ANIMATION
        if self.counter == 29:
            self.counter = 0
            self.index += 1
        if self.index >= len(self.frames_l) or self.index >= len(self.frames_r):
            self.index = 0
        cur_pos = self.rect.x - self.level.world_shift
        # if cur_pos < self.boundary_left:
        if self.direction == "Right":
            self.image = self.frames_l[self.index]
        if self.direction == "Left":
            self.image = self.frames_r[self.index]
        self.image = pygame.transform.scale(self.image,(64,64))

        # if self.change_x == -3:
        #     pygame.transform.flip(self.image, True, False)
        # See if we hit the player
        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:
            # We did hit the player. Shove the player around and
            # assume he/she won't hit anything else.

            # If we are moving right, set our right side
            # to the left side of the item we hit
            if self.change_x < 0:
                self.player.rect.right = self.rect.left
            else:
                # Otherwise if we are moving left, do the opposite.
                self.player.rect.left = self.rect.right
            MovingEnemy.player_hit = True
            constants.pain_sound.play()
            constants.health = constants.health - 10
            # self.kill()

        # shot = pygame.sprite.collide_rect(self, self.bullet)
        # if shot:
        #     if self.change_x < 0:
        #         self.bullet.rect.right = self.rect.left
        #     else:
        #         self.bullet.rect.left = self.rect.right
        #     self.kill()

        # Move up/down
        self.rect.y += self.change_y

        # Check and see if we the player
        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:
            # We did hit the player. Shove the player around and
            # assume he/she won't hit anything else.

            # Reset our position based on the top/bottom of the object.
            if self.change_y < 0:
                self.player.rect.bottom = self.rect.top
            else:
                self.player.rect.top = self.rect.bottom

        # Check the boundaries and see if we need to reverse
        # direction.
        # if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
        #     self.change_y *= -1
        #     pygame.transform.flip(self.image, True, False)

        cur_pos = self.rect.x - self.level.world_shift
        if cur_pos < self.boundary_left:
            self.direction = "Right"
        if cur_pos > self.boundary_right:
            self.direction = "Left"
        if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
            self.change_x *= -1
            self.image = pygame.transform.flip(self.image, True, False)


def read_file(path):
    rucksacks = list()
    with open(path) as f:
        for line in f:
            line = line.strip()

            rucksacks.append([line[:len(line) // 2], line[len(line) // 2:]])

    return rucksacks

def find_character(rucksacks):
    letters = list()
    for r in rucksacks:
        for c in r[0]:
            if c in r[1]:
                letters.append(c)
                break
    return letters

def calculate_priority(letters):
    priority = 0
    alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for l in letters:
        priority += alphabet.index(l) + 1
    return priority

if __name__ == '__main__':
    file = read_file('resources/testInput.txt')
    characters = find_character(file)
    print(characters)
    print(calculate_priority(characters))

    file = read_file('resources/input.txt')
    characters = find_character(file)
    print(characters)
    print(calculate_priority(characters))


#!/usr/bin/python

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#Receives a param of a C fucntion, and returns a
#structura: (is it a pointer?, type, name)
def breakParam(par):
	pointer = True
	e1 = par.rfind("*");
	if e1 < 0:
		e = par.rfind(" ");
		e1 = e
		pointer = False
	else:
		e = e1-1
	if e < 0:
		return None
	part = par[:e+1].strip()
	parn = par[e1+1:].strip()
	return [( pointer, part , parn)]

#Receives the code betwen '()' of a C fucntion,
#and returns a list of the correspondant parameters,
#broken in elements of the structure giben by
#breakParam
def breakParams(params):
	b = 0
	ps = []
	while(1):
		e = params.find(",",b)
		if(e < 0):
			bs = breakParam(params[b:].strip())
			if bs != None:
				ps += bs
			break
		else:
			bs = breakParam(params[b:e].strip())
			if bs != None:
				ps += bs
		b = e+1
	return ps

#Receives a line of C code, where we know will be
#a function declaration, and break it into a structure
#with (return type, function name, parameters struct list)
def breakFunction(fn):
	e = fn.find("(");
	if e < 0:
		return None
	b=fn[:e].strip().rfind(" ")
	fname = fn[b:e].strip()
	ftype = fn[:b].strip()
	b = e
	e = fn.find(")")
	if e < 0:
		return None
	fpars = fn[b+1:e].strip()
	ps = breakParams(fpars)
	return (ftype, fname, ps)

#Parses the text deleting the C or C+ comments it finds
def delComments(text):
	b = text.find("/");
	if text[b+1] == "/":
		e = text.find("\n", b)+1
	elif text[b+1] == "*":
		e = text.find("*/", b)+2
	else:
		return text
	return text[:b] + " " + delComments(text[e:])

#Main interface function
# filename = the name of the .h file we will read to parse
# wf = The python function we will call every time we find a C function.
def parseFile(filename, wf):
	frasebegin = "//--OLLUPAC--EXPORTABLE--FUNCTIONS--BEGIN"
	fraseend = "//--OLLUPAC--EXPORTABLE--FUNCTIONS--END"

	f = open(filename, 'r')
	f = f.read()

	b = f.find(frasebegin) + len(frasebegin);
	e = f.find(fraseend);

	f = delComments(f[b:e]).strip()

	b = 0
	while (1) :
		e = f.find(";",b)
		if e < 0:
			break
		o = f[b:e].strip()
		bf = breakFunction(o)
		b = e+1
		wf(bf)


import sys
import json
import logging
from . import gcp_cis_utils as gcp_cis_utils

def check7_1():
    # 7.1 Ensure that BigQuery datasets are not anonymously or publicly accessible (Scored)

    logging.info("7.1 Ensure that BigQuery datasets are not anonymously or publicly accessible (Scored)")
    details = []
    projects = gcp_cis_utils.get_bigquery_enabled_projects()
    for p in projects:
        output = gcp_cis_utils.run_cmd("bq ls --project_id=%s --format=json 2>/dev/null" % p)
        if output.strip() == "":
            continue
        try:
            out_json = json.loads(output)
        except ValueError:
            logging.warn("Unable to load response JSON for project [%s]...skipping it", p)
            out_json = []
        for entry in out_json:
            if entry['kind'] != "bigquery#dataset":
                continue
            dataset_id = entry['id']
            output = gcp_cis_utils.run_cmd("bq show --format=json %s 2>/dev/null" %dataset_id)
            try:
                out_json_2 = json.loads(output)
            except ValueError:
                logging.warn("Unable to load response JSON for project [%s]...skipping it", p)
                out_json_2 = {}
            access_configs = out_json_2.get('access')
            if access_configs is not None:
                for ac in access_configs:
                    if ac.get('specialGroup') == "allAuthenticatedUsers" or ac.get('iamMember') == "allUsers":
                        details.append(("BigQuery dataset [%s] in project [%s] is anonymously or publicly accessible" % (dataset_id.split(':')[1], p), [dataset_id.split(':')[1], p], dataset_id.split(':')[1]))
                        break
    if len(details) > 0:
        return gcp_cis_utils.create_issue('cis-gcp-bench-check-7.1', '7.1 [Level 1] Ensure that BigQuery datasets are not anonymously or publicly accessible (Scored)', details, '4', '', '')
    return None

def run_checks():
    config_issues = []
    gcp_cis_utils.append_issue(config_issues, check7_1())
    return config_issues


from functools import partial
import sys

from PyQt5 import QtWidgets, Qt, QtGui

class SpellTextEdit(QtWidgets.QPlainTextEdit):
    def __init__(self, *args, spelling_provider=None, **kwargs):
        super().__init__(*args, **kwargs)
        self._sp = None
        self.highlighter = SpellingHighlighter(self.document())
        self.spelling_provider = spelling_provider

    @property
    def spelling_provider(self):
        return self._sp

    @spelling_provider.setter
    def spelling_provider(self, item):
        self._sp = item
        self.highlighter.spelling_provider = item

    def contextMenuEvent(self, event):
        pos = event.pos()
        menu = self.createStandardContextMenu(pos)
        spell_items = self._get_spelling_items(
            self._get_spelling_cursor(pos), menu)
        if spell_items:
            menu.insertSeparator(menu.actions()[0])
            for item in reversed(spell_items):
                menu.insertAction(menu.actions()[0], item)
        menu.exec_(event.globalPos())

    def _get_spelling_items(self, cursor, parent=None):
        if not cursor or not self.spelling_provider:
            return None
        text = cursor.selectedText()
        suggests = self.spelling_provider.suggest(text)
        spell_items = []
        for word in suggests:
            action = QtWidgets.QAction(word, parent)
            action.setData((cursor, word))
            action.triggered.connect(partial(self.cb_correct_word, action))
            spell_items.append(action)

        return spell_items

    def _get_spelling_cursor(self, pos):
        cursor = self.cursorForPosition(pos)
        misspelled_words = getattr(cursor.block().userData(), 'misspelled', [])

        # If the cursor is within a misspelling, select the word
        for (start, end) in misspelled_words:
            if start <= cursor.positionInBlock() <= end:
                block_pos = cursor.block().position()

                cursor.setPosition(block_pos + start, QtGui.QTextCursor.MoveAnchor)
                cursor.setPosition(block_pos + end, QtGui.QTextCursor.KeepAnchor)
                break

        if cursor.hasSelection():
            return cursor
        else:
            return None

    def cb_correct_word(self, action):  # pylint: disable=no-self-use
        cursor, word = action.data()

        cursor.beginEditBlock()
        cursor.removeSelectedText()
        cursor.insertText(word)
        cursor.endEditBlock()

class SpellingHighlighter(QtGui.QSyntaxHighlighter):
    err_format = QtGui.QTextCharFormat()
    err_format.setUnderlineColor(QtGui.QColor(255, 0, 0))
    err_format.setUnderlineStyle(QtGui.QTextCharFormat.WaveUnderline)
    err_format.setForeground(QtGui.QBrush(QtGui.QColor(QtGui.QColor(255, 192, 192))))

    def __init__(self, *args, spelling_provider=None, **kwargs):
        super().__init__(*args, **kwargs)
        self._sp = None
        self.spelling_provider = spelling_provider

    @property
    def spelling_provider(self):
        return self._sp

    @spelling_provider.setter
    def spelling_provider(self, item):
        if self._sp == item:
            return
        self._sp = item
        self.rehighlight()

    def highlightBlock(self, text):
        if not self.spelling_provider:
            return
        misspellings = []
        for (word, pos) in self.spelling_provider.tokenize(text):
            if not self.spelling_provider.check(word):
                self.setFormat(pos, len(word), self.err_format)
                misspellings.append((pos, pos + len(word)))
        data = QtGui.QTextBlockUserData()
        data.misspelled = misspellings
        self.setCurrentBlockUserData(data)


#coding=utf-8
import cv2
import numpy as np
from math import sin,cos

if __name__=='__main__':
	U=np.zeros([200,200,3])
	V=np.zeros([200,200,3])

	r=0.1
	dt=0.03

	for i in range(1000):
		A = cv2.Laplacian(U,-1,ksize=5)-r*V
		A[103:105,103:105,int(i/400)%3]+=128*sin(i/10)
		U += V*dt
		V += A*dt
		if i%100==0:
			print(i)
			cv2.imwrite('U/%d.jpg'%i,U)
			cv2.imwrite('V/%d.jpg'%i,V)


from airflow.hooks.postgres_hook import PostgresHook
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults

class LoadFactOperator(BaseOperator):
    """
    Transform staging tables into the fact table in RedShift

    :param redshift_con_id: the connection id for RedShift
    :type redshift_con_id: str
    :param table: the target fact table in RedShift
    :type table: str
    :param sql: the sql statement to be executed
    :type sql: str
    """

    ui_color = '#F98866'

    @apply_defaults
    def __init__(self,
                 redshift_conn_id="",
                 table="",
                 sql="",
                 *args, **kwargs):

        super(LoadFactOperator, self).__init__(*args, **kwargs)
        self.sql = sql
        self.table = table
        self.redshift_conn_id = redshift_conn_id

    def execute(self, context):
        self.log.info('LoadFactOperator not implemented yet')
        redshift = PostgresHook(postgres_conn_id=self.redshift_conn_id)
        redshift.run(f"""
            INSERT INTO {self.table}
            {self.sql}
        """)
        self.log.info('LoadFactOperator is implemented')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Feb 16 13:08:07 2021

@author: maolasirzul
Description: . Improve Bubble Sort
"""

def bubble_sort(arr, asc=True):
    n = len(arr)

    # Traverse through all array elements
    swapFlag = False

    for i in range(n):

        # Last i elements are already in place
        for j in range(0, n-i-1):

            # traverse the array from 0 to n-i-1
            # Swap if the element found is greater
            # than the next element

            if (asc and arr[j] > arr[j+1]) or (not asc and arr[j] < arr[j+1]):
                    arr[j], arr[j+1] = arr[j+1], arr[j]
                    swapFlag = True

        if (swapFlag == False):
            break

# Tesing the given number
arr = [1, 3, 18, 10 ]
bubble_sort(arr)

print("Sorted number are:")
for i in range(len(arr)):
    print ("%d" %arr[i])


#!/bin/python
"""
entertainment_center.py uses movies_list.py and
fresh_tomatoes.py to create a web page with information about
class Movie instances defined in <moviesfile>, a JSON file. It then opens
a browser window with the generated html file.
"""

# import the media library from media.py, fresh_tomatoes.py and movies_list
import fresh_tomatoes
import movies_list

def main():
    """The main function calls all other funtions of the website.

    """
    # Read the movies.json file to define all movies
    moviesfile = "movies.json"
    movies = movies_list.populate_movies(moviesfile)
    # Call fresh_tomatoes with all movie instance pointers in list movies
    fresh_tomatoes.open_movies_page(movies)

main()


from collections import defaultdict

import tensorflow as tf

from .layers import GraphConvolutionSparseMulti, GraphConvolutionMulti, GraphConvolutionMulti2, \
    DistMultDecoder, InnerProductDecoder, DEDICOMDecoder, BilinearDecoder

flags = tf.app.flags
FLAGS = flags.FLAGS

class Model(object):
    def __init__(self, **kwargs):
        allowed_kwargs = {'name', 'logging'}
        for kwarg in kwargs.keys():
            assert kwarg in allowed_kwargs, 'Invalid keyword argument: ' + kwarg

        for kwarg in kwargs.keys():
            assert kwarg in allowed_kwargs, 'Invalid keyword argument: ' + kwarg
        name = kwargs.get('name')
        if not name:
            name = self.__class__.__name__.lower()
        self.name = name

        logging = kwargs.get('logging', False)
        self.logging = logging

        self.vars = {}

    def _build(self):
        raise NotImplementedError

    def build(self):
        """ Wrapper for _build() """
        with tf.variable_scope(self.name):
            self._build()
        variables = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=self.name)
        self.vars = {var.name: var for var in variables}

    def fit(self):
        pass

    def predict(self):
        pass

class GCNModel(Model):
    def __init__(self, edge_types1, edge_types2, decoders, num_feat, nonzero_feat, placeholders, **kwargs):
        super(GCNModel, self).__init__(**kwargs)
        self.edge_types1 = edge_types1
        self.edge_types2 = edge_types2
        self.decoders = decoders
        self.placeholders = placeholders
        self.num_feat = num_feat
        self.nonzero_feat = nonzero_feat
        self.num_obj_types1 = max([i for i, _ in self.edge_types1]) + 1
        self.num_obj_types2 = max([i for i, _ in self.edge_types2]) + 1
        self.dropout = placeholders['dropout']
        self.a = {}

        self.inputs1 = {i: placeholders['feat_%d' % i] for i, _ in self.edge_types1}
        self.adj_mats1 = {et: [
            placeholders['adj_mats1_%d,%d,%d' % (et[0], et[1], k)] for k in range(n)]
            for et, n in self.edge_types1.items()}
        self.adj_mats2 = {et: [
            placeholders['adj_mats2_%d,%d,%d' % (et[0], et[1], k)] for k in range(n)]
            for et, n in self.edge_types2.items()}
        if FLAGS.train_latent:
            self.lat_adj_mats2 = {et: [
                placeholders['lat_adj_mats2_%d,%d,%d' % (et[0], et[1], k)] for k in range(n)]
                for et, n in self.edge_types2.items()}
        else:
            self.lat_adj_mats2 = {}
        self.build()

    def _build(self):

        # chem-chem; chem-pathway; gene-gene; gene-pathway; pathway-chem; pathway-gene
        with tf.name_scope('%s_external_embed' % self.name):
            with tf.name_scope('layer_1'):
                self.hidden1_1 = defaultdict(list)
                for i, j in self.edge_types1:
                    self.hidden1_1[i].append(GraphConvolutionSparseMulti(
                        input_dim=self.num_feat[j],
                        output_dim=FLAGS.hid_units1_1,
                        edge_type=(i, j),
                        num_types=self.edge_types1[i, j],
                        adj_mats=self.adj_mats1,
                        nonzero_feat=self.nonzero_feat,
                        dropout=self.dropout,
                        act=lambda x: x,
                        logging=self.logging)(self.inputs1))
                for i, hid in self.hidden1_1.items():
                    self.hidden1_1[i] = tf.nn.relu(tf.add_n(hid))

            with tf.name_scope('layer_2'):
                self.hidden1_2 = defaultdict(list)
                for i, j in self.edge_types1:
                    self.hidden1_2[i].append(GraphConvolutionMulti(
                        input_dim=FLAGS.hid_units1_1,
                        output_dim=FLAGS.hid_units1_2,
                        edge_type=(i, j),
                        num_types=self.edge_types1[i, j],
                        adj_mats=self.adj_mats1,
                        dropout=self.dropout,
                        act=lambda x: x,
                        logging=self.logging)(self.hidden1_1))
                for i, hid in self.hidden1_2.items():
                    self.hidden1_2[i] = tf.nn.relu(tf.add_n(hid))

        # chem-gene; gene-chem
        with tf.name_scope('%s_inner_embed' % self.name):
            with tf.name_scope('layer_1'):
                self.hidden2_1 = defaultdict(list)
                for i, j in self.edge_types2:
                    outs, b = GraphConvolutionMulti2(
                        input_dim=FLAGS.hid_units1_2,
                        output_dim=FLAGS.hid_units2_1,
                        edge_type=(i, j),
                        num_types=self.edge_types2[i, j],
                        adj_mats=self.adj_mats2,
                        lat_adj_mats=self.lat_adj_mats2,
                        dropout=self.dropout,
                        act=lambda x: x,
                        logging=self.logging)(self.hidden1_2)
                    self.hidden2_1[i].append(outs)
                for i, hid in self.hidden2_1.items():
                    self.hidden2_1[i] = tf.nn.relu(tf.add_n(hid))
            with tf.name_scope('layer_2'):
                self.hidden2_2 = defaultdict(list)
                for i, j in self.edge_types2:
                    outputs, a = GraphConvolutionMulti2(
                        input_dim=FLAGS.hid_units2_1,
                        output_dim=FLAGS.hid_units2_2,
                        edge_type=(i, j),
                        num_types=self.edge_types2[i, j],
                        adj_mats=self.adj_mats2,
                        lat_adj_mats=self.lat_adj_mats2,
                        dropout=self.dropout,
                        act=lambda x: x,
                        logging=self.logging)(self.hidden2_1)
                    self.hidden2_2[i].append(outputs)
                    self.a[(i, j)] = a
                self.embeddings = [None] * self.num_obj_types2
                for i, hid in self.hidden2_2.items():
                    self.embeddings[i] = tf.add_n(hid)

        # decoder
        hid_units = FLAGS.hid_units2_2
        self.edge_type2decoder = {}
        for i, j in self.edge_types2:
            decoder = self.decoders[i, j]
            if decoder == 'innerproduct':
                self.edge_type2decoder[i, j] = InnerProductDecoder(
                    input_dim=hid_units, logging=self.logging,
                    edge_type=(i, j), num_types=self.edge_types2[i, j],
                    act=lambda x: x, dropout=self.dropout)
            elif decoder == 'distmult':
                self.edge_type2decoder[i, j] = DistMultDecoder(
                    input_dim=hid_units, logging=self.logging,
                    edge_type=(i, j), num_types=self.edge_types2[i, j],
                    act=lambda x: x, dropout=self.dropout)
            elif decoder == 'bilinear':
                self.edge_type2decoder[i, j] = BilinearDecoder(
                    input_dim=hid_units, logging=self.logging,
                    edge_type=(i, j), num_types=self.edge_types2[i, j],
                    act=lambda x: x, dropout=self.dropout)
            elif decoder == 'dedicom':
                self.edge_type2decoder[i, j] = DEDICOMDecoder(
                    input_dim=hid_units, logging=self.logging,
                    edge_type=(i, j), num_types=self.edge_types2[i, j],
                    act=lambda x: x, dropout=self.dropout)
            else:
                raise ValueError('Unknown decoder type')
        self.latent_inters = []
        self.latent_varies = []
        for edge_type in self.edge_types2:
            decoder = self.decoders[edge_type]
            for k in range(self.edge_types2[edge_type]):
                if decoder == 'innerproduct':
                    glb = tf.eye(hid_units, hid_units)
                    loc = tf.eye(hid_units, hid_units)
                elif decoder == 'distmult':
                    glb = tf.diag(self.edge_type2decoder[edge_type].vars['relation_%d' % k])
                    loc = tf.eye(hid_units, hid_units)
                elif decoder == 'bilinear':
                    glb = self.edge_type2decoder[edge_type].vars['relation_%d' % k]
                    loc = tf.eye(hid_units, hid_units)
                elif decoder == 'dedicom':
                    glb = self.edge_type2decoder[edge_type].vars['global_interaction']
                    loc = tf.diag(self.edge_type2decoder[edge_type].vars['local_variation_%d' % k])
                else:
                    raise ValueError('Unknown decoder type')
                self.latent_inters.append(glb)
                self.latent_varies.append(loc)


contacts = []

def add_contact(name, phone, email, address):
    contact = {
        "Name": name,
        "Phone": phone,
        "Email": email,
        "Address": address
    }
    contacts.append(contact)
    print("Contact added successfully!")

def view_contacts():
    if not contacts:
        print("No contacts found.")
    else:
        print("Contact List:")
        for idx, contact in enumerate(contacts, start=1):
            print(f"{idx}. {contact['Name']} - {contact['Phone']}")

def search_contact(query):
    results = []
    for contact in contacts:
        if query.lower() in contact['Name'].lower() or query in contact['Phone']:
            results.append(contact)
    if not results:
        print("No matching contacts found.")
    else:
        print("Matching Contacts:")
        for idx, contact in enumerate(results, start=1):
            print(f"{idx}. {contact['Name']} - {contact['Phone']}")

def update_contact(index, name, phone, email, address):
    if 0 <= index < len(contacts):
        contacts[index]['Name'] = name
        contacts[index]['Phone'] = phone
        contacts[index]['Email'] = email
        contacts[index]['Address'] = address
        print("Contact updated successfully!")
    else:
        print("Invalid contact index.")

def delete_contact(index):
    if 0 <= index < len(contacts):
        del contacts[index]
        print("Contact deleted successfully!")
    else:
        print("Invalid contact index.")

def main():
    while True:
        print("\nContact Book Menu:")
        print("1. Add Contact")
        print("2. View Contacts")
        print("3. Search Contact")
        print("4. Update Contact")
        print("5. Delete Contact")
        print("6. Exit")

        choice = input("Enter your choice (1-6): ")

        if choice == "1":
            name = input("Enter Name: ")
            phone = input("Enter Phone: ")
            email = input("Enter Email: ")
            address = input("Enter Address: ")
            add_contact(name, phone, email, address)
        elif choice == "2":
            view_contacts()
        elif choice == "3":
            query = input("Enter Name or Phone to search: ")
            search_contact(query)
        elif choice == "4":
            index = int(input("Enter Contact Index to update: ")) - 1
            name = input("Enter New Name: ")
            phone = input("Enter New Phone: ")
            email = input("Enter New Email: ")
            address = input("Enter New Address: ")
            update_contact(index, name, phone, email, address)
        elif choice == "5":
            index = int(input("Enter Contact Index to delete: ")) - 1
            delete_contact(index)
        elif choice == "6":
            print("Goodbye!")
            break
        else:
            print("Invalid choice. Please try again.")

if __name__ == "__main__":
    main()


import numpy as np
import matplotlib.pyplot as plt
import json

for filenr,file in enumerate(['estimates1.json','estimates2.json','estimates3.json']):
    filenr = filenr + 1
    print("results from:",file)

    #open json and get results
    f = open(file)
    results = json.load(f)
    t = results['t']
    print("where t = ", t)
    trueSum = results['trueSum']
    array = np.array(results['estimates'])
    sortedArray = np.sort(array)

    #find medians (from non-sorted array)
    medians = np.zeros(9)
    for i in range(9):
        medians[i] = np.median(array[i*11:(i+1)*11])
    #sort medians for plot
    sortedMedians = np.sort(medians)

    #print stats
    mse = 0
    for element in array:
        mse += (element-trueSum)**2/array.shape[0]
    print("mse:",mse)
    print("mean:", np.mean(array))
    print("the variance of the estimator: ",2*trueSum**2/(2**t))
    print("average time in ms: ", np.mean(results['times']))
    print("true sum:", trueSum)
    print("S - mean: ", trueSum-np.mean(array))

    #plot params
    size = (7,4)
    ymin = [13200000,13190000,13150000]
    ymax = [13240000,13260000,13350000]
    lin = np.linspace(1,array.shape[0],array.shape[0])

    #plot 1: estimates
    fig, ax = plt.subplots(figsize=size)
    A = ax.scatter(lin,sortedArray,label='estimates')
    B, = ax.plot([lin[0],lin[-1]],[trueSum,trueSum], label='true squared sum')
    ax.legend(handles=[A,B])
    ax.set_xlabel('estimate index')
    ax.set_ybound(ymin[filenr-1],ymax[filenr-1])
    ax.set_ylabel('squared sum')
    title = "Estimates, when t = "+str(t)
    ax.set_title(title)
    ax.grid()
    figname = str(filenr)+"_t"+str(t)+"estimates"
    plt.savefig(figname)

    #plot 1: medians
    fig2, ax2 = plt.subplots(figsize=size)
    A2 = ax2.scatter(lin[0:9],sortedMedians,label='medians of estimates')
    B2, = ax2.plot([lin[0],lin[8]],[trueSum,trueSum], label='true squared sum')
    ax2.legend(handles=[A2,B2])
    ax2.set_xlabel('median index')
    ax2.set_ybound(ymin[filenr-1],ymax[filenr-1])
    title = "The 9 medians, when t = "+str(t)
    ax2.set_ylabel('squared sum')
    ax2.set_title(title)
    ax2.grid()
    figname = str(filenr)+"_t"+str(t)+"medians"
    plt.savefig(figname)

    print("   ")
    print("   ")


import numpy as np
import statsmodels.api as sm
import xarray as xr
from packaging.version import Version

from mesmer.io.save_mesmer_bundle import save_mesmer_data
from mesmer.stats.auto_regression import _fit_auto_regression_xr, _select_ar_order_xr

def train_gv(gv, targ, esm, cfg, save_params=True, **kwargs):
    """
    Derive global variability parameters for a specified method.

    Parameters
    ----------
    gv : dict
        Nested global mean variability dictionary with keys

        - [scen] (2d array (run, time) of globally-averaged variability time series)

    targ : str
        target variable (e.g., "tas")

    esm : str
        associated Earth System Model (e.g., "CanESM2" or "CanESM5")

    cfg : config module
        config file containing metadata

    save_params : bool, optional
        determines if parameters are saved or not, default = True

    **kwargs : Any
        additional arguments, passed through to the training function

    Returns
    -------
    params_gv : dict
        dictionary containing the trained parameters for the chosen method / ensemble
        type

        - ["targ"] (emulated variable, str)
        - ["esm"] (Earth System Model, str)
        - ["method"] (applied method, str)
        - ["preds"] (predictors, list of strs)
        - ["scenarios"] (emission scenarios used for training, list of strs)
        - [xx] additional params depend on method employed, specified in
          ``train_gv_T_method()`` function

    Notes
    -----
    - Assumption
        - if historical data is used for training, it has its own scenario

    - TODO:
        - add ability to weight samples differently than equal weight for each scenario

    """

    # specify necessary variables from config file
    method_gv = cfg.methods[targ]["gv"]
    preds_gv = cfg.preds[targ]["gv"]
    wgt_scen_tr_eq = cfg.wgt_scen_tr_eq

    scenarios_tr = list(gv.keys())

    # initialize parameters dictionary and fill in the metadata which does not depend on
    # the applied method
    params_gv = {}
    params_gv["targ"] = targ
    params_gv["esm"] = esm
    params_gv["method"] = method_gv
    params_gv["preds"] = preds_gv
    params_gv["scenarios"] = scenarios_tr

    # apply the chosen method
    if params_gv["method"] == "AR" and wgt_scen_tr_eq:
        # specifiy parameters employed for AR process fitting

        kwargs["max_lag"] = kwargs.get("max_lag", 12)
        kwargs["sel_crit"] = kwargs.get("sel_crit", "bic")

        params_gv = train_gv_AR(params_gv, gv, kwargs["max_lag"], kwargs["sel_crit"])
    else:
        raise ValueError("No such method and/ or weighting approach.")

    # save the global variability paramters if requested
    if save_params:
        save_mesmer_data(
            params_gv,
            cfg.dir_mesmer_params,
            "global",
            "global_variability",
            filename_parts=[
                "params_gv",
                method_gv,
                *preds_gv,
                targ,
                esm,
                *scenarios_tr,
            ],
        )

    return params_gv

def train_gv_AR(params_gv, gv, max_lag, sel_crit):
    """
    Derive AR parameters of global variability under the assumption that gv does not
    depend on the scenario.

    Parameters
    ----------
    params_gv : dict
        parameter dictionary containing keys which do not depend on applied method

        - ["targ"] (variable, i.e., tas or tblend, str)
        - ["esm"] (Earth System Model, str)
        - ["method"] (applied method, i.e., AR, str)
        - ["scenarios"] (emission scenarios used for training, list of strs)

    gv : dict
        nested global mean temperature variability (volcanic influence removed)
        dictionary with keys

        - [scen] (2d array (nr_runs, nr_ts) of globally-averaged temperature variability
          time series)

    max_lag : int
        maximum number of lags considered during fitting

    sel_crit : str
        selection criterion for the AR process order, e.g., 'bic' or 'aic'

    Returns
    -------
    params : dict
        parameter dictionary containing original keys plus

        - ["max_lag"] (maximum lag considered when finding suitable AR model, hardcoded
          to 15 here, int)
        - ["sel_crit"] (selection criterion applied to find suitable AR model, hardcoded
          to Bayesian Information Criterion bic here, str)
        - ["AR_int"] (intercept of the AR model, float)
        - ["AR_coefs"] (coefficients of the AR model for the lags which are contained in
          the selected AR model, list of floats)
        - ["AR_order_sel"] (selected AR order, int)
        - ["AR_std_innovs"] (standard deviation of the innovations of the selected AR
          model, float)

    Notes
    -----
    - Assumptions
        - number of runs per scenario and the number of time steps in each scenario can
          vary
        - each scenario receives equal weight during training

    """

    params_gv["max_lag"] = max_lag
    params_gv["sel_crit"] = sel_crit

    if Version(xr.__version__) >= Version("2022.03.0"):
        method = "method"
    else:
        method = "interpolation"

    # select the AR Order
    AR_order_scen = list()
    for scen in gv.keys():

        # create temporary DataArray
        data = xr.DataArray(gv[scen], dims=["run", "time"])

        AR_order = _select_ar_order_xr(data, dim="time", maxlag=max_lag, ic=sel_crit)

        # median over all ensemble members ("nearest" ensures an 'existing' lag is selected)
        AR_order = AR_order.quantile(q=0.5, **{method: "nearest"})
        AR_order_scen.append(AR_order)

    # median over all scenarios
    AR_order_scen = xr.concat(AR_order_scen, dim="scen")
    AR_order_sel = int(AR_order_scen.quantile(q=0.5, **{method: "nearest"}).item())

    # determine the AR params for the selected AR order
    params_scen = list()
    for scen in gv.keys():
        data = gv[scen]

        # create temporary DataArray
        data = xr.DataArray(data, dims=("run", "time"))

        params = _fit_auto_regression_xr(data, dim="time", lags=AR_order_sel)
        # BUG/ TODO: we wrongfully average over the standard deviation
        # see https://github.com/MESMER-group/mesmer/issues/307
        params["standard_deviation"] = np.sqrt(params.variance)
        params = params.mean("run")

        params_scen.append(params)

    params_scen = xr.concat(params_scen, dim="scen")
    params_scen = params_scen.mean("scen")

    # TODO: remove np.float64(...) (only here so the tests pass)
    params_gv["AR_order_sel"] = AR_order_sel
    params_gv["AR_int"] = np.float64(params_scen.intercept.values)
    params_gv["AR_coefs"] = params_scen.coeffs.values.squeeze()
    params_gv["AR_std_innovs"] = np.float64(params_scen.standard_deviation.values)

    # check if fitted AR process is stationary
    # (highly unlikely this test will ever fail but better safe than sorry)
    ar = np.r_[1, -params_gv["AR_coefs"]]  # add zero-lag and negate
    ma = np.r_[1]  # add zero-lag
    arma_process = sm.tsa.ArmaProcess(ar, ma)
    if not arma_process.isstationary:
        raise ValueError(
            "The fitted AR process is not stationary. Another solution is needed."
        )

    return params_gv


import numpy as np
import nibabel as nib
import glob
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
from tifffile import imsave

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

# Training dataset

t1_section = sorted(glob.glob('./BraTS2020_TrainingData/MICCAI_BraTS2020_TrainingData/*/*t1.nii'))
t2_section = sorted(glob.glob('./BraTS2020_TrainingData/MICCAI_BraTS2020_TrainingData/*/*t2.nii'))
t1ce_section = sorted(glob.glob('./BraTS2020_TrainingData/MICCAI_BraTS2020_TrainingData/*/*t1ce.nii'))
flair_section = sorted(glob.glob('./BraTS2020_TrainingData/MICCAI_BraTS2020_TrainingData/*/*flair.nii'))
mask = sorted(glob.glob('./BraTS2020_TrainingData/MICCAI_BraTS2020_TrainingData/*/*seg.nii'))

for i in range(len(t1_section)):

    t1_image=nib.load(t1_section[i]).get_fdata()
    t1_image=scaler.fit_transform(t1_image.reshape(-1, t1_image.shape[-1])).reshape(t1_image.shape)

    t1ce_image=nib.load(t1ce_section[i]).get_fdata()
    t1ce_image=scaler.fit_transform(t1ce_image.reshape(-1, t1ce_image.shape[-1])).reshape(t1ce_image.shape)

    flair_image=nib.load(flair_section[i]).get_fdata()
    flair_image=scaler.fit_transform(flair_image.reshape(-1, flair_image.shape[-1])).reshape(flair_image.shape)

    t2_image=nib.load(t2_section[i]).get_fdata()
    t2_image=scaler.fit_transform(t2_image.reshape(-1, t2_image.shape[-1])).reshape(t2_image.shape)

    Mask=nib.load(mask[i]).get_fdata()
    Mask=Mask.astype(np.uint8)
    Mask[Mask==4] = 3

    combined_images = np.stack([t1_image,t1ce_image,flair_image,t2_image], axis=3)

    #Crop to a size to be divisible by 64 so we can later extract 64x64x64 patches.
    combined_images=combined_images[56:184, 56:184, 13:141]
    Mask = Mask[56:184, 56:184, 13:141]

    val, counts = np.unique(Mask, return_counts=True)

    if (1 - (counts[0]/counts.sum())) > 0.01:  #At least 1% useful volume with labels that are not 0
        print("Save Me")
        Mask= to_categorical(Mask, num_classes=4)
        np.save('./images/image_'+str(i)+'.npy', combined_images)
        np.save('./masks/mask_'+str(i)+'.npy', Mask)

    else:
        print("I am useless")

##########################################################################
import splitfolders

input_folder = './Data/'
output_folder = './Data/split/'

# Split with a ratio.
splitfolders.ratio(input_folder, output=output_folder, seed=42, ratio=(.8, .2), group_prefix=None)


# -*- coding: utf-8 -*-
"""
Created on Tue Apr 27 11:49:19 2021

@author: katrine
"""

import torch
import os
import numpy   as np
import matplotlib.pyplot as plt
from   scipy.ndimage.morphology import distance_transform_edt, binary_erosion
from   torch import Tensor

#%% Specify directory
os.chdir("C:/Users/katrine/Documents/GitHub/Speciale2021")
#os.chdir('/Users/michalablicher/Documents/GitHub/Speciale2021')

# Load data function

user = 'K'
from load_data_gt_im_sub_space import load_data_sub

phase = 'Systole'

data_im_es_DCM,  data_gt_es_DCM  = load_data_sub(user,phase,'DCM')
data_im_es_HCM,  data_gt_es_HCM  = load_data_sub(user,phase,'HCM')
data_im_es_MINF, data_gt_es_MINF = load_data_sub(user,phase,'MINF')
data_im_es_NOR,  data_gt_es_NOR  = load_data_sub(user,phase,'NOR')
data_im_es_RV,   data_gt_es_RV   = load_data_sub(user,phase,'RV')

phase = 'Diastole'

data_im_ed_DCM,  data_gt_ed_DCM  = load_data_sub(user,phase,'DCM')
data_im_ed_HCM,  data_gt_ed_HCM  = load_data_sub(user,phase,'HCM')
data_im_ed_MINF, data_gt_ed_MINF = load_data_sub(user,phase,'MINF')
data_im_ed_NOR,  data_gt_ed_NOR  = load_data_sub(user,phase,'NOR')
data_im_ed_RV,   data_gt_ed_RV   = load_data_sub(user,phase,'RV')

num_train_sub = 12
num_eval_sub = num_train_sub
num_test_sub = num_eval_sub + 8

"""
im_test_ed_sub = np.concatenate((np.concatenate(data_im_ed_DCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_ed_HCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_ed_MINF[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_ed_NOR[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_ed_RV[num_eval_sub:num_test_sub]).astype(None)))
"""
gt_test_ed_sub = np.concatenate((np.concatenate(data_gt_ed_DCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_ed_HCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_ed_MINF[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_ed_NOR[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_ed_RV[num_eval_sub:num_test_sub]).astype(None)))
"""
im_test_es_sub = np.concatenate((np.concatenate(data_im_es_DCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_es_HCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_es_MINF[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_es_NOR[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_im_es_RV[num_eval_sub:num_test_sub]).astype(None)))
"""
gt_test_es_sub = np.concatenate((np.concatenate(data_gt_es_DCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_es_HCM[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_es_MINF[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_es_NOR[num_eval_sub:num_test_sub]).astype(None),
                                  np.concatenate(data_gt_es_RV[num_eval_sub:num_test_sub]).astype(None)))

#%% Load ground truth data

# Onehot encode class channels
gt_es_oh = torch.nn.functional.one_hot(Tensor(gt_test_es_sub).to(torch.int64), num_classes=4).detach().numpy().astype(np.bool)
gt_ed_oh = torch.nn.functional.one_hot(Tensor(gt_test_ed_sub).to(torch.int64), num_classes=4).detach().numpy().astype(np.bool)

# Get rid of unecessary variables
#del gt_ed_flat, gt_es_flat, data_gt_ed, data_gt_es

#%% Compute distance tarnsform maps

# Preallocate
dt_es = np.zeros((gt_es_oh.shape))
dt_ed = np.zeros((gt_ed_oh.shape))

ref_border_es = np.zeros((gt_es_oh.shape))
ref_border_ed = np.zeros((gt_ed_oh.shape))

inside_obj_mask_es = np.zeros_like(gt_es_oh).astype(np.bool)
inside_obj_mask_ed = np.zeros_like(gt_ed_oh).astype(np.bool)

outside_obj_mask_es = np.zeros_like(gt_es_oh).astype(np.bool)
outside_obj_mask_ed = np.zeros_like(gt_ed_oh).astype(np.bool)

# Specify tolerated distances
error_margin_inside  = 2 # VOXELS
error_margin_outside = 3 # VOXELS

for i in range(0, gt_es_oh.shape[0]):
    for j in range(0, gt_es_oh.shape[3]):

        # Find voxels inside object
        inside_voxels_indices_es = binary_erosion(gt_es_oh[i,:,:,j], iterations=1)
        inside_voxels_indices_ed = binary_erosion(gt_ed_oh[i,:,:,j], iterations=1)

        # Find border voxels
        ref_border_es[i,:,:,j]   = np.logical_xor(gt_es_oh[i,:,:,j], inside_voxels_indices_es)
        ref_border_ed[i,:,:,j]   = np.logical_xor(gt_ed_oh[i,:,:,j], inside_voxels_indices_ed)

        ref_border_es  = ref_border_es.astype(bool)
        ref_border_ed  = ref_border_ed.astype(bool)

        # Calculated euclidean distance to object for all voxels
        dt_es[i,:,:,j] = distance_transform_edt(~ref_border_es[i,:,:,j])
        dt_ed[i,:,:,j] = distance_transform_edt(~ref_border_ed[i,:,:,j])

        # save object masks
        inside_obj_mask_es[i,inside_voxels_indices_es,j] = 1
        inside_obj_mask_ed[i,inside_voxels_indices_ed,j] = 1

        outside_obj_mask_es[i,:,:,j] = np.logical_and(~inside_obj_mask_es[i,:,:,j], ~ref_border_es[i,:,:,j])
        outside_obj_mask_ed[i,:,:,j] = np.logical_and(~inside_obj_mask_ed[i,:,:,j], ~ref_border_ed[i,:,:,j])

        # surface border distance is always ZERO
        dt_es[ref_border_es] = 0
        dt_ed[ref_border_ed] = 0

        # inside structure: we subtract a fixed margin
        dt_es[i,inside_obj_mask_es[i,:,:,j],j]  = dt_es[i,inside_obj_mask_es[i,:,:,j],j] - error_margin_inside
        dt_ed[i,inside_obj_mask_ed[i,:,:,j],j]  = dt_ed[i,inside_obj_mask_ed[i,:,:,j],j] - error_margin_inside

        # outside of target: structure we subtract a fixed margin.
        dt_es[i,outside_obj_mask_es[i,:,:,j],j] = dt_es[i, outside_obj_mask_es[i,:,:,j],j] - error_margin_outside
        dt_ed[i,outside_obj_mask_ed[i,:,:,j],j] = dt_ed[i, outside_obj_mask_ed[i,:,:,j],j] - error_margin_outside

        # Transform maps
        dt_es[dt_es < 0] = 0
        dt_ed[dt_ed < 0] = 0

"""
OBS: distance transform maps can't be computed for slices whitout GT annotation. This is the case for some apical and basal slices.
Segmentation errors for these slices should be included no matter of size and location.

"""

#%%
fig = plt.figure()

test_slice = 10

class_title = ['Background','Right Ventricle','Myocardium','Left Ventricle']
plt.figure(dpi=200, figsize=(15,15))
for i in range(0,4):
    plt.suptitle('Shown for slice %i' %test_slice, fontsize=20, y=0.8)
    plt.subplot(2, 4, i+1)
    plt.subplots_adjust(hspace = 0.0, wspace = 0.5)
    plt.imshow(gt_es_oh[test_slice,:,:,i])
    plt.title(class_title[i], fontsize =16)

    plt.subplot(2, 4, i+1+4)
    #plt.subplots_adjust(hspace = 0.0, wspace = 0.5)
    plt.imshow(dt_es[test_slice,:,:,i])
    plt.title(class_title[i], fontsize =16)
plt.show()

#%% Define as function

def dist_trans(gt_oh, error_margin_inside, error_margin_outside):

    # Preallocate
    dt = np.zeros((gt_oh.shape))
    ref_border       = np.zeros((gt_oh.shape))
    inside_obj_mask  = np.zeros_like(gt_oh).astype(np.bool)
    outside_obj_mask = np.zeros_like(gt_oh).astype(np.bool)

    for i in range(0, gt_oh.shape[0]):
        for j in range(0, gt_oh.shape[3]):

            # Find voxels inside object
            inside_voxels_indices = binary_erosion(gt_oh[i,:,:,j], iterations=1)

            # Find border voxels
            ref_border[i,:,:,j]   = np.logical_xor(gt_oh[i,:,:,j], inside_voxels_indices)

            ref_border = ref_border.astype(bool)

            # Calculated euclidean distance to object for all voxels
            dt[i,:,:,j] = distance_transform_edt(~ref_border[i,:,:,j])

            # save object masks
            inside_obj_mask[i, inside_voxels_indices, j] = 1
            outside_obj_mask[i,:,:,j] = np.logical_and(~inside_obj_mask[i,:,:,j], ~ref_border[i,:,:,j])

            # surface border distance is always ZERO
            dt[ref_border] = 0

            # inside structure: we subtract a fixed margin
            dt[i,inside_obj_mask[i,:,:,j],j]  = dt[i, inside_obj_mask[i,:,:,j],j] - error_margin_inside

            # outside of target: structure we subtract a fixed margin.
            dt[i,outside_obj_mask[i,:,:,j],j] = dt[i, outside_obj_mask[i,:,:,j],j] - error_margin_outside

            # Transform maps
            dt[dt < 0] = 0

    return dt

#%% Test of function

dt_es = dist_trans(gt_es_oh, 2,3)


from nuclear import *
from nuclear.types.boolean import boolean
from tests.asserts import MockIO

def test_boolean_type():
    def print_it(param1: bool, param2: bool):
        print(f'{param1} {type(param1).__name__}, {param2} {type(param2).__name__}')

    with MockIO('--param1=true') as mockio:
        CliBuilder(run=print_it).has(
            parameter('param1', type=boolean, default=False),
            parameter('param2', type=boolean, default=True),
        ).run()
        assert mockio.stripped() == 'True bool, True bool'

    with MockIO('--param1=false', '--param2=no') as mockio:
        CliBuilder(run=print_it).has(
            parameter('param1', type=boolean, default=True),
            parameter('param2', type=boolean, default=True),
        ).run()
        assert mockio.stripped() == 'False bool, False bool'


import pytest
from pathlib import Path

from swissknife.utils import gather_files

def test_gathering_files_with_extensions_from_tree(dir_pair):
    """Tests collecting files with provided extensions from the source folder
    without deleting source folder.
    """
    src, dst = dir_pair

    gather_files(src=src, dst=dst, exts='log|txt|out')

    expected = read_all(src)
    actual = read_all(dst)
    assert Path(src).exists()
    assert expected == actual

def test_gathering_files_with_deleting_original_tree(dir_pair):
    """Tests deleting original folder after moving files to another one."""
    src, dst = dir_pair

    gather_files(src=src, dst=dst, exts='log', delete_source=True)

    assert not Path(src).exists()

def test_gathering_files_returns_list_of_copied_paths(dir_pair):
    """Tests returning a list of paths to gathered files."""
    src, dst = dir_pair

    paths = gather_files(src=src, dst=dst, exts='log|txt|out')

    expected = read_all(src)
    assert len(paths) == len(expected)
    assert all(Path(p).exists() for p in paths)

@pytest.fixture
def dir_pair(tmpdir):
    content = 'content'
    src = tmpdir.mkdir('src')
    dst = tmpdir.mkdir('dst')
    files = (
        src.join('results.log'),
        src.join('failure.out'),
        src.mkdir('sub').join('log.txt'))
    for file in files:
        file.write(content)
    return str(src), str(dst)

def read_all(path):
    return [open(file.as_posix()).read() for file in Path(path).glob('**/*.*')]


temp = []
princ = []
mai = men = 0
while True:
    temp.append(str(input('Nome: ')))
    temp.append(float(input('Peso: ')))
    if len(princ) == 0:
        mai = men = temp[1]
    else:
        if temp[1] > mai:
            mai = temp[1]
        if temp[1] < men:
            men = temp[1]
    princ.append(temp[:])
    temp.clear()
    resp = str(input('Quer continuar? [S/N] '))
    if resp in 'Nn':
        break
print('-=' * 30)
print(f'Ao todo, você cadastrou {len(princ)} pessoas.')
print(f'O maior peso foi de {mai}Kg. Peso de ', end='')
for p in princ:
    if p[1] == mai:
        print(f'[{p[0]}] ', end='')
print()
print(f'O menor peso foi de {men}Kg. Peso de ', end='')
for p in princ:
    if p[1] == men:
        print(f'[{p[0]}] ', end='')
print()


import os
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

if __name__ == '__main__':
    loss_list = []
    val_loss_list = []
    acc_list = []
    val_acc_list = []
    sen_list = []

    sen_list = np.load("norm_model.npy")
    batch_list = [16,32,64,128,256,512,1024,2048]
    record = np.load("loss_model.npy")
    for i in record:
        loss_list.append(i[0])
        acc_list.append(i[1])
        val_loss_list.append(i[2])
        val_acc_list.append(i[3])

    fig, ax = plt.subplots(1, 2, figsize=(10, 5))
    ax1 = ax[0]

    ax1.set_xlabel('batch size')
    ax1.set_ylabel('loss', color = 'b')
    ax1.semilogx(batch_list, loss_list, color = 'b', label = 'train loss')
    ax1.semilogx(batch_list, val_loss_list, color = 'b', linestyle = '--', label = 'test loss')
    ax1.tick_params(axis='y', labelcolor= 'b')
    ax2 = ax1.twinx()
    ax2.set_ylabel('sensitivity', color = 'r')
    ax2.semilogx(batch_list, sen_list, color = 'r', label = 'sensitivity')
    ax2.tick_params(axis='y', labelcolor= 'r')
    ax1.legend(loc="best")
    ax2.legend(loc="best")

    ax3 = ax[1]
    ax3.set_title('acc & sensitivity v.s. batch_size')
    ax3.set_xlabel('batch size')
    ax3.set_ylabel('acc', color = 'b')
    ax3.semilogx(batch_list, acc_list, color = 'b', label = 'train acc')
    ax3.semilogx(batch_list, val_acc_list, color = 'b', linestyle = '--', label = 'test acc')
    ax3.tick_params(axis='y', labelcolor= 'b')
    ax4 = ax3.twinx()
    ax4.set_ylabel('sensitivity', color = 'r')
    ax4.semilogx(batch_list, sen_list, color = 'r', label = 'sensitivity')
    ax4.tick_params(axis='y', labelcolor= 'r')
    ax3.legend(loc="upper left")
    ax4.legend(loc="best")

    plt.tight_layout()
    fig.savefig('sensitivity.png')