'''
Create a VCF by reading the variants from an annovar input file (*.avinput ).
This script does not sort the vcf so you should followup by running ``gatk SortVcf --INPUT unsorted.vcf --OUTPUT sorted.vcf``

@author: pleyte
'''
import argparse
import logging.config
import csv
from edu.ohsu.compbio.txeff.util.tfx_log_config import TfxLogConfig

class Variant(object):
    def __init__(self):
        chromosome = None
        startPos = None
        endPos = None
        ref = None
        alt = None
        dbSnpId = None

def _parse_args():
    '''
    Validate and return command line arguments.
    '''
    parser = argparse.ArgumentParser(description='Read an Annovar avinput file and write out a VCF')

    parser.add_argument('-i', '--in_file',
                        help='Annovar avinput file generated by convert2annovar.pl',
                        type=argparse.FileType('r'),
                        required=True)

    parser.add_argument('-o', '--out_file',
                        help='VCF file to create',
                        type=argparse.FileType('w'),
                        required=True)

    args = parser.parse_args()

    return args

def _read_avinput_variants(avinput_file_name: str):
    variants = []

    with open(avinput_file_name) as tsv_file:
        reader = csv.reader(tsv_file, delimiter = '\t')
        for row in reader:
            if row[3] == "-" or row[4] == "-":
                continue
            variant = Variant()
            variant.chromosome = row[0].replace('chr', '', 1)
            variant.startPos = row[1]
            variant.endPos = row[2]
            variant.ref = row[3]
            variant.alt = row[4]
            variant.dbSnpId = row[7]
            variants.append(variant)

    return variants

def _write_vcf(vcf_file_name: str, variants: list):
    '''
    '''
    with open(vcf_file_name, 'w') as vcf_file:
        vcf_file.write('##fileformat=VCFv4.2\n')
        vcf_file.write('##FILTER=<ID=PASS,Description="All filters passed">\n')
        vcf_file.write('##FILTER=<ID=PON,Description="Variant found in panel of normals in 3 or more samples.">\n')
        vcf_file.write('##FILTER=<ID=PON_OV,Description="Variant found in panel of normals at low frequency, but call is at significantly higher frequency.">\n')
        vcf_file.write('##contig=<ID=1,length=249250621>\n')
        vcf_file.write('##contig=<ID=2,length=243199373>\n')
        vcf_file.write('##contig=<ID=3,length=198022430>\n')
        vcf_file.write('##contig=<ID=4,length=191154276>\n')
        vcf_file.write('##contig=<ID=5,length=180915260>\n')
        vcf_file.write('##contig=<ID=6,length=171115067>\n')
        vcf_file.write('##contig=<ID=7,length=159138663>\n')
        vcf_file.write('##contig=<ID=8,length=146364022>\n')
        vcf_file.write('##contig=<ID=9,length=141213431>\n')
        vcf_file.write('##contig=<ID=10,length=135534747>\n')
        vcf_file.write('##contig=<ID=11,length=135006516>\n')
        vcf_file.write('##contig=<ID=12,length=133851895>\n')
        vcf_file.write('##contig=<ID=13,length=115169878>\n')
        vcf_file.write('##contig=<ID=14,length=107349540>\n')
        vcf_file.write('##contig=<ID=15,length=102531392>\n')
        vcf_file.write('##contig=<ID=16,length=90354753>\n')
        vcf_file.write('##contig=<ID=17,length=81195210>\n')
        vcf_file.write('##contig=<ID=18,length=78077248>\n')
        vcf_file.write('##contig=<ID=19,length=59128983>\n')
        vcf_file.write('##contig=<ID=20,length=63025520>\n')
        vcf_file.write('##contig=<ID=21,length=48129895>\n')
        vcf_file.write('##contig=<ID=22,length=51304566>\n')
        vcf_file.write('##contig=<ID=X,length=155270560>\n')
        vcf_file.write('##contig=<ID=Y,length=59373566>\n')
        vcf_file.write('##contig=<ID=MT,length=16569>\n')
        vcf_file.write('##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">\n')
        vcf_file.write('##INFO=<ID=x,Number=1,Type=String,Description="Placeholder">\n')
        vcf_file.write('#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT\tabcd-123\n')

        for variant in variants:
            vcf_file.write(f"{variant.chromosome}\t{variant.startPos}\t{variant.dbSnpId}\t{variant.ref}\t{variant.alt}\t1.0\tPON\tx=y\tGT\t0/0\n")

def _main():
    '''
    main function
    '''
    logging.config.dictConfig(TfxLogConfig().utility_config)

    args = _parse_args()

    variants = _read_avinput_variants(args.in_file.name)

    logging.info(f"Read {len(variants)} variants from {args.in_file.name}")

    _write_vcf(args.out_file.name, variants)

    logging.info(f"Wrote VCF {args.out_file.name}")

if __name__ == '__main__':
    _main()


import picar

class PiDriver:
    def __init__(self):
        picar.setup()

        # Debug mode
        self.debug = False

        # DC Motor setup
        self.back_wheels = picar.back_wheels.Back_Wheels()
        self.front_wheels = picar.front_wheels.Front_Wheels()
        self.front_wheels.offset = 0

        # Servo motor setup
        self.pan_servo = picar.Servo.Servo(1)
        self.pan_servo.offset = -10
        self.tilt_servo = picar.Servo.Servo(2)
        self.tilt_servo.offset = 0

        # Car params
        self.params = { 'speed':0,
	     	            'steer':90 }

    def change_speed(self, speed):
        # Checking max speed
        if -100 <= speed <= 100:
            self.params['speed'] = speed

            # Checking dir
            if self.params['speed'] >= 0:
                self.back_wheels.backward()
            else: self.back_wheels.forward()

            # Changing actual car speed
            self.back_wheels.speed = abs(self.params['speed'])

        if self.debug: print(f"speed: {self.params['speed']}")

    def increment_speed(self, increment):
        self.change_speed(self.params['speed'] + increment)

    def change_steer(self, steer):
        if 50 <= steer <= 140:
            self.params['steer'] = steer

            # Changing actual car steer
            self.front_wheels.turn(self.params['steer'])

        if self.debug: print(f"steer: {self.params['steer']}")

    def increment_steer(self, increment):
        self.change_steer(self.params['steer'] + increment)

    def stop(self):
        self.params['speed'] = 0
        self.back_wheels.stop()


import os, sys, random, time, copy
import numpy as np
import math
import PIL.Image

import blosc, struct

import torch
from torch.utils.data import Dataset, DataLoader
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import torch.nn.functional as F
from torch.autograd import Variable
from torchvision.transforms import InterpolationMode

from torchvision import datasets, models, transforms

IMG_EXTENSIONS = [
    '.jpg', '.JPG', '.jpeg', '.JPEG',
    '.png', '.PNG', '.ppm', '.PPM', '.bmp', '.BMP', '.bin', '.dat'
]

def is_image_file(filename):
    return any(filename.endswith(extension) for extension in IMG_EXTENSIONS)

class Joint_coord_dataLoader(Dataset):
    def __init__(self, real_root_dir, syn_root_dir, img_normalize='pure', paired_data=False, augment=False):
        self.real_root_dir = real_root_dir
        self.syn_root_dir = syn_root_dir
        self.img_normalize = img_normalize
        self.current_set_len = 0
        self.real_path2files = []
        self.syn_path2files = []
        self.paired_data = paired_data # whether 1 to 1 matching
        self.augment = augment # whether to augment each batch data

        self.aug_scale_min = 2/3.0 # defalut range of scaling
        self.aug_scale_max = 3/2.0
        self.aug_rotation = 30.0 # defalut range of rotation
        self.SUBSAMPLE = 8.0 # defalut downsampling factor

        self.set_name = 'train' # Joint_coord_dataLoader is only used in training phase

        real_curfilenamelist = os.listdir(os.path.join(self.real_root_dir, self.set_name, 'rgb'))
        for fname in sorted(real_curfilenamelist):
            if is_image_file(fname):
                path = os.path.join(self.real_root_dir, self.set_name, 'rgb', fname)
                self.real_path2files.append(path)

        self.real_set_len = len(self.real_path2files)

        syn_curfilenamelist = os.listdir(os.path.join(self.syn_root_dir, self.set_name, 'rgb'))
        for fname in sorted(syn_curfilenamelist):
            if is_image_file(fname):
                path = os.path.join(self.syn_root_dir, self.set_name, 'rgb', fname)
                self.syn_path2files.append(path)

        self.syn_set_len = len(self.syn_path2files)

        self.TF2tensor = transforms.ToTensor()
        self.TF2PIL = transforms.ToPILImage()
        if self.augment:
            image_transform = [transforms.ColorJitter(brightness=True, contrast=True)]
        else:
            image_transform = []
        if self.img_normalize == 'pure':
            image_transform.append(transforms.ToTensor())
        elif self.img_normalize == 'urban':
            image_transform.append(transforms.ToTensor())
            image_transform.append(transforms.Normalize(mean=[0.4245, 0.4375, 0.3836],std=[0.1823, 0.1701, 0.1854]))
        elif self.img_normalize == 'nature':
            image_transform.append(transforms.ToTensor())
            image_transform.append(transforms.Normalize(mean=[0.3636, 0.4331, 0.2956],std=[0.1383, 0.1457, 0.1147]))
        else:
            # feel free to add normalize for your own dataset
            raise NotImplementedError('normalization type [%s] is not found' % self.img_normalize)

        self.image_transform = transforms.Compose(image_transform)

    def __len__(self):
        # looping over real dataset
        return self.real_set_len

    def __getitem__(self, idx):
        real_filename = self.real_path2files[idx % self.real_set_len]
        if self.paired_data:
            syn_filename = real_filename.replace(self.real_root_dir,self.syn_root_dir)
        else:
            rand_idx = random.randint(0, self.syn_set_len - 1)
            syn_filename = self.syn_path2files[rand_idx]

        image_real, coord_real, gt_poses_real, focal_length_real = self.fetch_img_coord(real_filename)
        image_syn, coord_syn, gt_poses_syn, focal_length_syn = self.fetch_img_coord(syn_filename)
        return_dict = {'real': [image_real, coord_real, gt_poses_real, focal_length_real],
                       'syn': [image_syn, coord_syn, gt_poses_syn, focal_length_syn]}

        return return_dict

    def fetch_img_coord(self, filename):

        image = PIL.Image.open(filename).convert('RGB')
        image = self.image_transform(image)

        coord = torch.load(filename.replace('rgb','init').replace('png','dat'))
        gt_poses = np.loadtxt(filename.replace('rgb','poses').replace('png','txt')) #camera to world
        gt_poses = torch.from_numpy(gt_poses).float()
        focal_length = float(np.loadtxt(filename.replace('rgb','calibration').replace('png','txt')))

        return image, coord, gt_poses, focal_length

    def batch_resize(self, batch):
        """
        Backbone collate_fn to resize data (images & coords) using a common scale factor.
        Usage: torch.utils.data.DataLoader(..., collate_fn=YOUR_DATASET.batch_resize, ...)
        """

        b_image = [item['real'][0] for item in batch]
        b_geo_labels = [item['real'][1] for item in batch]
        b_pose = [item['real'][2] for item in batch]
        b_focal_length = [item['real'][3] for item in batch]

        b_image_real, b_geo_labels_real, b_pose_real, b_focal_length_real, image_h_real, image_w_real, coords_h_real, coords_w_real = self.data_aug(b_image, b_geo_labels, b_pose, b_focal_length)

        b_image = [item['syn'][0] for item in batch]
        b_geo_labels = [item['syn'][1] for item in batch]
        b_pose = [item['syn'][2] for item in batch]
        b_focal_length = [item['syn'][3] for item in batch]

        b_image_syn, b_geo_labels_syn, b_pose_syn, b_focal_length_syn, image_h_syn, image_w_syn, coords_h_syn, coords_w_syn = self.data_aug(b_image, b_geo_labels, b_pose, b_focal_length)

        return_dict = {'real': [b_image_real, b_geo_labels_real, b_pose_real, b_focal_length_real,image_h_real,image_w_real, coords_h_real, coords_w_real],
                       'syn': [b_image_syn, b_geo_labels_syn, b_pose_syn, b_focal_length_syn, image_h_syn, image_w_syn, coords_h_syn, coords_w_syn]}

        return return_dict

    def data_aug(self, b_image, b_geo_labels, b_pose, b_focal_length):
        scale_factor = random.uniform(self.aug_scale_min, self.aug_scale_max)
        angle = random.uniform(-self.aug_rotation, self.aug_rotation)

        image_h = 4*math.ceil(b_image[0].size(1) * scale_factor/4) #force to be divisible by 4 because two downsample is included before U-net
        image_w = 4*math.ceil(b_image[0].size(2) * scale_factor/4)

        b_image_tensor = torch.stack(b_image, dim=0)
        b_image_tensor = F.interpolate(b_image_tensor, size=(image_h, image_w), mode='bilinear',
                                        align_corners=False)
        b_image_tensor = transforms.functional.rotate(b_image_tensor, angle, fill=-1)

        b_focal_length = [item * scale_factor for item in b_focal_length]

        # scale coordinates
        coords_w = math.ceil(b_image_tensor[0].size(2) / self.SUBSAMPLE)
        coords_h = math.ceil(b_image_tensor[0].size(1) / self.SUBSAMPLE)

        # single 3d geometric label, such as coords/depth/normal
        trim_b_geo_labels = torch.stack(b_geo_labels, dim=0)
        trim_b_geo_labels = F.interpolate(trim_b_geo_labels, size=(coords_h, coords_w), mode='nearest')
        trim_b_geo_labels = transforms.functional.rotate(trim_b_geo_labels, angle, fill=-1.0)

        return b_image_tensor, trim_b_geo_labels, torch.stack(b_pose), \
                torch.tensor(b_focal_length, dtype=torch.float64), image_h, image_w, coords_h, coords_w


# encoding: utf-8
import importlib
import os
import logging
from website import settings

logger = logging.getLogger(__name__)

DEFAULT_REGION_NAME = 'United States'
DEFAULT_REGION_ID = 'us'

WATERBUTLER_CREDENTIALS = {
    'storage': {}
}

WATERBUTLER_SETTINGS = {
    'storage': {
        'provider': 'filesystem',
        'folder': os.path.join(settings.BASE_PATH, 'osfstoragecache'),
    }
}

WATERBUTLER_RESOURCE = 'folder'

DISK_SAVING_MODE = settings.DISK_SAVING_MODE

try:
    mod = importlib.import_module('.{}'.format(settings.MIGRATION_ENV), package='addons.osfstorage.settings')
    globals().update({k: getattr(mod, k) for k in dir(mod)})
except Exception as ex:
    logger.warn('No migration settings loaded for OSFStorage, falling back to local dev. {}'.format(ex))

# Max file size permitted by frontend in megabytes
MAX_UPLOAD_SIZE = 5 * 1024  # 5 GB

# Max file size permitted by frontend in megabytes for verified users
HIGH_MAX_UPLOAD_SIZE = 5 * 1024  # 5 GB


class Solution(object):
    def flipAndInvertImage(self, A):
        """
        :type A: List[List[int]]
        :rtype: List[List[int]]
        """
        R = []
        for row in A:
            for x in range (0,(len(row)+1)/2):
                # if x!=len(row)-1-x:
                tmp = row[x]
                row[x] = 1 - row[len(row)-1-x]
                row[len(row)-1-x]= 1-tmp
                # else:
                #     row[x]=1-row[x]
            R.append(row)
        return R


import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

class PolicyGradient:
	def __init__(self, n_features, n_actions, learning_rate = 0.01, reward_decay = 0.95):
		self.n_actions = n_actions
		self.n_features = n_features
		self.lr = learning_rate
		self.gamma = reward_decay

		self.ep_obs, self.ep_as, self.ep_rs = [], [], []

		self.cost_his = []

		self._build_net()

		self.sess = tf.Session()

		self.sess.run(tf.global_variables_initializer())

	def _build_net(self):
		with tf.variable_scope('inputs'):
			self.tf_obs = tf.placeholder(tf.float32, [None, self.n_features], name='observation')
			self.tf_acts = tf.placeholder(tf.int32, [None, ], name='actions_num')
			self.tf_vt = tf.placeholder(tf.float32, [None, ], name='action_value')

		layer = tf.layers.dense(self.tf_obs,
								32,
								tf.nn.relu,
								kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
								bias_initializer=tf.constant_initializer(0.1),
								name='fc1')
		self.all_act = tf.layers.dense(layer,
								  self.n_actions,
								  tf.nn.softmax,
								  kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
								  bias_initializer=tf.constant_initializer(0.1),
								  name='fc2')

		with tf.variable_scope('loss'):
			log_prob = tf.reduce_sum(-tf.log(self.all_act) * tf.one_hot(self.tf_acts, self.n_actions), axis=1)
			self.loss = tf.reduce_mean(log_prob * self.tf_vt)

		with tf.variable_scope('train'):
			self.train_op = tf.train.AdamOptimizer(self.lr).minimize(self.loss)

	def choose_action(self, observation):
		prob_weights = self.sess.run(self.all_act, feed_dict={self.tf_obs: observation[np.newaxis, :]})
		action = np.random.choice(range(prob_weights.shape[1]), p=prob_weights.ravel())
		return action

	def store_transition(self, s, a, r):
		self.ep_obs.append(s)
		self.ep_as.append(a)
		self.ep_rs.append(r)

	def learn(self):
		# discount and normalize episode reward
		discounted_ep_rs_norm = self._discount_and_norm_rewards()

		# train on episode
		_, cost = self.sess.run([self.train_op, self.loss], feed_dict={
			self.tf_obs: np.vstack(self.ep_obs),  # shape=[None, n_obs]
			self.tf_acts: np.array(self.ep_as),  # shape=[None, ]
			self.tf_vt: discounted_ep_rs_norm,  # shape=[None, ]
		})

		self.ep_obs, self.ep_as, self.ep_rs = [], [], []  # empty episode data
		self.cost_his.append(cost)
		return discounted_ep_rs_norm

	def _discount_and_norm_rewards(self):
		# discount episode rewards
		discounted_ep_rs = np.zeros_like(self.ep_rs)
		running_add = 0
		for t in reversed(range(0, len(self.ep_rs))):
			running_add = running_add * self.gamma + self.ep_rs[t]
			discounted_ep_rs[t] = running_add

		# normalize episode rewards
		discounted_ep_rs -= np.mean(discounted_ep_rs)
		discounted_ep_rs /= np.std(discounted_ep_rs)
		return discounted_ep_rs

	def plot_cost(self):
		plt.plot(np.arange(len(self.cost_his)), self.cost_his)
		plt.ylabel('Cost')
		plt.xlabel('training steps')
		plt.show()


def main():
    from sys import stdin
    input = stdin.readline

    # 入力を受け取る
    a, b = map(int, input().split())
    ab = int(str(a) + str(b))

    # 処理
    # abが平方数であるか判別
    for i in range(100101):
        if i*i > ab:
            break

        if ab == i*i:
            print("Yes")
            exit()

    print("No")

if __name__ == '__main__':
    main()


try :
    import pygame
except ImportError :
    print("Erreur : le module pygame est requis pour le bon fonctionnement de ce jeu")
    print("Voulez-vous que nous installions automatiquement ce module (Y/n)", end = " ")
    if input("") != "n" :
        print("Installation de pygame en cours...")
        import os
        command = ("python" if os.name == "nt" else "python3") + " -m pip install pygame"
        if not os.system(command) :
            print("Succès ! pygame a bien été installé")
            import pygame
        else :
            print("Une erreur est survenue veuillez réessayer")
            exit()
    else : exit()

from random import choice
from joueur import Joueur
from ennemi import BigBoss, Ennemi

#init de pygame et chargement en mémoire des sons, du background...
pygame.init()
background = pygame.image.load("images/background.jpg")

#audio
pygame.mixer.init()
firePioupiou = pygame.mixer.Sound("audio/shoot.wav")
ennemiKilled = pygame.mixer.Sound("audio/invaderkilled.wav")
mainMusic = pygame.mixer.music.load("audio/spaceinvaders1.wav")
playerDeath = pygame.mixer.Sound("audio/explosion.wav")
pygame.mixer.music.set_volume(0.5)

clock = pygame.time.Clock()
pygame.display.set_caption("Space Invadors")
from pygamelabel import Label                     #on importe ici car pour initialiser des fonts, pygame.init() doit avoir tourné
labelFont = pygame.font.SysFont('Comic Sans MS', 26) #taille + style police du texte

class Party :
    lexit = Label("Exit", 350, 600) #création bouton exit
    lplay = Label("Play", 350, 500) #création bouton play

    def __init__(self) -> None:
        self._screen = pygame.display.set_mode([700, 700])
        self._level = 0
        self._joueur = Joueur()
        self._allSprites = pygame.sprite.Group()
        self._listEnnemiPioupiou = pygame.sprite.Group()
        self._joueurPioupiou = pygame.sprite.Group()
        self.ENNEMIPIOUPIOU = pygame.USEREVENT + 1
        self.ENNEMIDIRECTION = pygame.USEREVENT + 2
        self._score = 0
        pygame.mixer.music.play(loops=-1)                  #joue la musique de fond en boucle

        #récupération s'il existe d'un high score
        try :
            with open("data", "r") as file :
                fileData = file.readline()
            highscore = fileData.split("=")[1]
            self._highscore = int(highscore)
        except (FileNotFoundError, IOError, ValueError, IndexError) :
            self._highscore = 0
            with open("data", "w") as file :
                file.write("highscore=0")

    def playRound(self) :
        self._allSprites.add(self._joueur)
        self._listEnnemis = pygame.sprite.Group()

        #init et création des ennemis
        #si on atteint le niveau 10, big boss
        if self._level == 9 :
            boss = BigBoss((250, 250))
            self._listEnnemis.add(boss)
            self._allSprites.add(boss)
            bigboss = True
        else :
            bigboss = False
            for y in range(4) :
                for x in range(6) :
                    newEnnemy = Ennemi((50 + 100 * x, 100 + y * 100), "blue_space_invader.jpg" if y < 2 else "space_invader.jpg")        #on met des invaders bleus sur les 2 premières lignes
                    self._listEnnemis.add(newEnnemy)
                    self._allSprites.add(newEnnemy)
        self.update()

        #Déclaration des events custom
        pygame.time.set_timer(self.ENNEMIPIOUPIOU, 4000 - 400 * self._level)
        pygame.time.set_timer(self.ENNEMIDIRECTION, 1000 + 40 * self._level)                       #permet de faire le va et vient des ennemis ; toutes les secondes : changement de direction

        ennemiMoveDirection = 0                        #compteur utilisé pour faire bouger 5 fois les ennemis vers la droite de 4 pixels, puis la même chose vers la gauche et ainsi de suite

        #labels pour pouvoir afficher le score, les points de vie du joueur et le niveau de la partie durant le jeu
        Levellabel = Label('Level:', 610, 17, (53, 196, 38), labelFont)
        Scorelabel = Label('Score:', 330, 17, (248, 233, 0), labelFont)
        Lifelabel = Label('Life:', 70, 17, (241, 57, 57), labelFont)

        #BOUCLE DE JEU
        running = True
        while running :
            #GESTION DES EVENTS
            for event in pygame.event.get():
                if event.type == pygame.QUIT:             #-> l'utilisateur a demandé à fermer la fenêtre
                    return "quit"

                if event.type == self.ENNEMIPIOUPIOU :
                    newPioupiou = choice(self._listEnnemis.sprites()).emitPioupiou()      #on choisit un ennemi au hasard et on lui fait tirer un missile qu'on ajoute à la liste des sprites
                    self._allSprites.add(newPioupiou)
                    self._listEnnemiPioupiou.add(newPioupiou)

                if event.type == self.ENNEMIDIRECTION :
                    ennemiMoveDirection += 1

            #GESTION DES INPUTS
            pressed_keys = pygame.key.get_pressed()
            if self._joueur.update(pressed_keys) :                #la fonction retourne True si la barre espace est appuyée -> on veut tirer un missile
                if len(self._joueurPioupiou.sprites()) == 0 :                   #on vérifie que aucun missile n'est "en cours"
                    newPioupiou = self._joueur.instantiatePioupiou()
                    self._allSprites.add(newPioupiou)
                    self._joueurPioupiou.add(newPioupiou)
                    firePioupiou.play()

            #MISE A JOUR DES POSITIONS
            self._listEnnemis.update("right" if ennemiMoveDirection % 2 == 0 else "left")       #nombre pair -> les ennemis vont vers la droite sinon ils vont à gauche
            for pioupiou in self._listEnnemiPioupiou :
                pioupiou.update()
            for pioupiou in self._joueurPioupiou.sprites() :
                pioupiou.update()

            #GESTION DES COLLISIONS
            collideJoueurPioupiouE = pygame.sprite.spritecollideany(self._joueur, self._listEnnemiPioupiou)   #=sprite d'un pioupiou ennemi s'il touche le joueur
            if collideJoueurPioupiouE :
                self._joueur.diminuerVie(1)
                collideJoueurPioupiouE.kill()
                running = False
                playerDeath.play()

            ennemiCollideDict = pygame.sprite.groupcollide(self._listEnnemis, self._joueurPioupiou, False, False)   #on récupère l'ennemi qui a été touché par le missile du joueur
            if ennemiCollideDict :
                for ennemi in ennemiCollideDict.keys() :
                    if not bigboss :               #si pas en mode bigboss -> le missile du joueur tue l'ennemi instantanément
                        ennemi.kill()
                        ennemiCollideDict[ennemi][0].kill()
                    else :
                        ennemi.retirerVie(1)                               #sinon on retire une vie au bigboss (il faut 10 missiles pour le tuer)
                        ennemiCollideDict[ennemi][0].kill()
                        if not ennemi.isAlive() : ennemi.kill()
                    self._score += 10
                    ennemiKilled.play()
                if len(self._listEnnemis.sprites()) == 0 :
                    self._level += 1
                    running = False

            self._screen.blit(background, (0, 0))
            ScoreNumberig = Label(str(self._score), 385, 17, (255, 255, 255), labelFont)
            LifeNumber = Label(str(self._joueur.getVie()), 110, 17, (255, 255, 255), labelFont)
            LevelNumber = Label(str(self._level + 1), 654, 17, (255, 255, 255), labelFont)
            Lifelabel.blit(self._screen)
            LifeNumber.blit(self._screen)
            Scorelabel.blit(self._screen)
            ScoreNumberig.blit(self._screen)
            Levellabel.blit(self._screen)
            LevelNumber.blit(self._screen)
            self.update()

        #Sortie de boucle -> suppression des sprites, mises a jour de qq variables et vérification des vies du joueur
        for sprite in self._allSprites :
            sprite.kill()
        self.update()
        joueurOK = self._joueur.isAlive()
        if not bigboss :
            if joueurOK : return "continue" #pas de bigboss -> on continue la partie et on passe au niveau suivant
            else : return "over"
        else :
            if joueurOK and boss.isAlive() : return "continue"
            if joueurOK and not boss.isAlive() : return "win"
            else : return "over"

    def update(self) :
        #actualisation de l'affichage graphique
        for sprite in self._allSprites :
            self._screen.blit(sprite.surf, sprite.rect)
        pygame.display.flip()
        clock.tick(25)           #permet de maintenir 25fps

    def terminate(self) :
        pygame.mixer.music.stop()
        pygame.mixer.quit()
        pygame.quit()

    #ECRANS
    def Victory(self): #écran victoire
        self.endScreen('YOU WON', (231, 193, 0))

    def GameOver(self): #écran défaite
        self.endScreen("GAME OVER", (255, 0, 0))

    def endScreen(self, text: str, textcolor: tuple) :
        if self._highscore != None :
            if self._score > self._highscore :
                with open("data", "w") as file :
                    file.write("highscore=" + str(self._score))
                highscore = Label("New highscore ! " + str(self._score), 350, 500)
            else :
                highscore = Label("Highscore : " + str(self._highscore), 350, 500)

        myfont = pygame.font.SysFont('Comic Sans MS', 100) #taille + style police du texte
        textsurface = Label(text, 350, 100, textcolor, myfont)
        textscore = Label('Score:', 350, 225, (255, 255, 255), myfont)
        scoreNumber = Label(str(self._score), 350, 375, (255, 255, 255), myfont)

        running = True
        while running :
            for event in pygame.event.get() :
                if event.type == pygame.MOUSEBUTTONDOWN and self.__class__.lexit.CliqueSourisLabel() :
                    return
            self._screen.blit(background, (0, 0))
            textsurface.blit(self._screen)
            textscore.blit(self._screen)
            scoreNumber.blit(self._screen)
            self.__class__.lexit.blit(self._screen)
            if self._highscore != None : highscore.blit(self._screen)
            pygame.display.flip()
            clock.tick(25)

    def Welcome(self): #Ecran de démarrage
        myfont = pygame.font.SysFont('Comic Sans MS', 40)
        myfont2 = pygame.font.SysFont('Comic Sans MS', 75) #police + taille
        textWelcome = Label('Welcome to', 350, 250, (255, 255, 255), myfont)
        textgame = Label('SPACE INVADERS', 350, 350, (255, 255, 255), myfont2) #texte + antialiasing + couleur
        self._screen.blit(background, (0, 0))
        textWelcome.blit(self._screen)
        textgame.blit(self._screen)
        self.__class__.lexit.blit(self._screen)
        self.__class__.lplay.blit(self._screen)
        pygame.display.flip()
        running = True
        while running :
            for event in pygame.event.get() :
                if event.type == pygame.MOUSEBUTTONDOWN: #faire réagir quand la souris clique
                    if self.__class__.lplay.CliqueSourisLabel() : return True
                    if self.__class__.lexit.CliqueSourisLabel() : return False


from bhp_sep import dataset_processor as dp
from bhp_sep.dataset_processor import DataProcessor

DP=DataProcessor()

def get_headings_by_text(text=None):
    return [heading for heading in dp.headings if text in heading]

# from bhp_sep.dataset_processor import DataProcessor
#
# flow_rate = [dp.COL_21_FQI_10518_01_NetRate_PV,
#              dp.COL_21_FT_40518_03_Gross_Volume_Flow_Rate,
#              dp.COL_30_FT_69521_01_PV_Flotation_Cell_Prod_Wtr_To_Ovbrd,
#              dp.COL_30_FT_19107_01_PV_2nd_Stg_Hydrocyclone_Inlet]
#
# psi = [heading for heading in dp.headings if 'Psi' in heading]
# temperature = [heading for heading in dp.headings if 'DegF' in heading]

HD_Temperature = '(DegF)'
HD_PSIG = 'PSIG'
HD_PSID = 'PSID'
HD_PERCENTAGE = '(%)'

plt = DP.visualizer(*get_headings_by_text(HD_Temperature))
plt.tight_layout()
plt.savefig('temp.png')
plt.show()


import random as rand

from PySide2 import QtWidgets, QtCore
from shiboken2 import wrapInstance
import maya.OpenMayaUI as omui
import maya.cmds as cmds
import random as rand

def maya_main_window():
    main_window = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window), QtWidgets.QWidget)

class ScatterUI(QtWidgets.QDialog):
    """Scatter Tool UI Class"""

    def __init__(self):
        super(ScatterUI, self).__init__(parent=maya_main_window())
        self.setWindowTitle("Scatter Object Tool")
        self.setMinimumWidth(500)
        self.setMaximumWidth(500)
        self.setMaximumHeight(400)
        self.setWindowFlags(self.windowFlags() ^
                            QtCore.Qt.WindowContextHelpButtonHint)
        self.title_lbl = QtWidgets.QLabel("Scatter Object Tool")
        self.title_lbl.setStyleSheet("font: bold 20px")
        self.scale_lay = self._create_random_scale_ui()
        self.rotation_lay = self._create_random_rotation_ui()
        self.button_lay = self._create_button_ui()
        self.slider_lay = self._create_slider_ui()
        self.main_lay = QtWidgets.QVBoxLayout()
        self.main_lay.addWidget(self.title_lbl)
        self.main_lay.addLayout(self.scale_lay)
        self.main_lay.addLayout(self.rotation_lay)
        self.main_lay.addLayout(self.slider_lay)
        self.main_lay.addStretch()
        self.main_lay.addLayout(self.button_lay)
        self.setLayout(self.main_lay)
        self._create_connections()

    def _create_slider_ui(self):
        layout = QtWidgets.QHBoxLayout()
        self.slider_lbl = QtWidgets.QLabel("Percentage of Scatter:")
        self.slider_sld = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.slider_sld.setRange(0, 100)
        self.perc_lbl = QtWidgets.QLabel('0')
        self.perc_lbl.setMinimumWidth(30)

        layout.addWidget(self.slider_lbl)
        layout.addWidget(self.slider_sld)
        layout.addSpacing(15)
        layout.addWidget(self.perc_lbl)
        return layout

    def _create_random_scale_ui(self):
        layout = QtWidgets.QGridLayout()
        self.scale_check_btn = QtWidgets.QCheckBox()
        self.scale_lbl = QtWidgets.QLabel("Randomize Scale:")
        self.options_lay = self._min_max_scale_options_ui()
        #self.scale_le.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.scale_lbl, 0, 0)
        layout.addWidget(self.scale_check_btn, 0, 1)
        layout.addLayout(self.options_lay, 1, 2)
        return layout

    def _min_max_scale_options_ui(self):
        layout = QtWidgets.QGridLayout()
        self.scale_min_lbl = QtWidgets.QLabel("min")
        self.scale_min_lbl.hide()
        self.scale_min_le = QtWidgets.QLineEdit("1.0")
        self.scale_min_le.setFixedWidth(40)
        self.scale_min_le.hide()
        self.scale_max_lbl = QtWidgets.QLabel("max")
        self.scale_max_lbl.hide()
        self.scale_max_le = QtWidgets.QLineEdit("10.0")
        self.scale_max_le.setFixedWidth(40)
        self.scale_max_le.hide()
        layout.addWidget(self.scale_min_lbl, 1, 2)
        layout.addWidget(self.scale_min_le, 1, 3)
        layout.addWidget(self.scale_max_lbl, 1, 4)
        layout.addWidget(self.scale_max_le, 1, 5)
        return layout

    def _create_random_rotation_ui(self):
        layout = QtWidgets.QGridLayout()
        self.rotate_lbl = QtWidgets.QLabel("Randomize Rotation:")
        self.rotate_check_btn = QtWidgets.QCheckBox()
        self.x_min_le = QtWidgets.QLineEdit("0.0")
        self.x_min_le.setFixedWidth(40)
        self.x_min_le.hide()
        self.x_max_le = QtWidgets.QLineEdit("360.0")
        self.x_max_le.setFixedWidth(40)
        self.x_max_le.hide()
        self.y_min_le = QtWidgets.QLineEdit("0.0")
        self.y_min_le.setFixedWidth(40)
        self.y_min_le.hide()
        self.y_max_le = QtWidgets.QLineEdit("360.0")
        self.y_max_le.setFixedWidth(40)
        self.y_max_le.hide()
        self.z_min_le = QtWidgets.QLineEdit("0.0")
        self.z_min_le.setFixedWidth(40)
        self.z_min_le.hide()
        self.z_max_le = QtWidgets.QLineEdit("360.0")
        self.z_max_le.setFixedWidth(40)
        self.z_max_le.hide()
        layout.addWidget(self.rotate_lbl, 2, 0)
        layout.addWidget(self.rotate_check_btn, 2, 1)
        layout.addWidget(self.x_min_le, 3, 2)
        layout.addWidget(self.x_max_le, 3, 3)
        layout.addWidget(self.y_min_le, 3, 5)
        layout.addWidget(self.y_max_le, 3, 6)
        layout.addWidget(self.z_min_le, 3, 8)
        layout.addWidget(self.z_max_le, 3, 9)
        return layout

    def _create_button_ui(self):
        self.scatter_btn = QtWidgets.QPushButton("Apply")
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.scatter_btn)
        return layout

    def _create_connections(self):
        self.scale_check_btn.stateChanged.connect(self._show_scale_options)
        self.rotate_check_btn.stateChanged.connect(self._show_rotate_options)
        self.scatter_btn.clicked.connect(self._create_scatter_effect)
        self.slider_sld.valueChanged.connect(self._update_perc_label)

    def _update_perc_label(self, value):
        self.perc_lbl.setText(str(value))

    @QtCore.Slot()
    def _show_rotate_options(self):
        if self.rotate_check_btn.isChecked():
            self.x_min_le.show()
            self.x_max_le.show()
            self.y_min_le.show()
            self.y_max_le.show()
            self.z_min_le.show()
            self.z_max_le.show()
        else:
            self.x_min_le.hide()
            self.x_max_le.hide()
            self.y_min_le.hide()
            self.y_max_le.hide()
            self.z_min_le.hide()
            self.z_max_le.hide()

    @QtCore.Slot()
    def _show_scale_options(self):
        if self.scale_check_btn.isChecked():
            self.scale_min_lbl.show()
            self.scale_min_le.show()
            self.scale_max_lbl.show()
            self.scale_max_le.show()
        else:
            self.scale_min_lbl.hide()
            self.scale_min_le.hide()
            self.scale_max_lbl.hide()
            self.scale_max_le.hide()

    def _create_scatter_effect(self):
        selection = cmds.ls(sl=True, fl=True)
        vertices = cmds.filterExpand(selection, selectionMask=31,
                                        expand=True)

        object_to_instance = selection[0]

        if not vertices:
            object_to_convert = selection[1]
            vertices = cmds.ls('%s.vtx[*]' % object_to_convert, flatten=True)

        if cmds.objectType(object_to_instance) == 'transform':
            self._create_percentage_scatter(vertices)

            for vertex in vertices:
                new_instance = cmds.instance(object_to_instance)[0]
                position = cmds.pointPosition(vertex, w=1)
                cmds.move(position[0], position[1], position[2], new_instance, a=1, ws=1)
                if self.scale_check_btn.isChecked():
                    scale_min = round(float(self.scale_min_le.text()), 1)
                    scale_max = round(float(self.scale_max_le.text()), 1)

                    inst_scale = round(rand.uniform(scale_min, scale_max), 1)
                    cmds.scale(inst_scale, inst_scale, inst_scale, new_instance, a=1, ws=1)

                if self.rotate_check_btn.isChecked():
                    rot_x_min = round(float(self.x_min_le.text()), 1)
                    rot_x_max = round(float(self.x_max_le.text()), 1)
                    rot_y_min = round(float(self.y_min_le.text()), 1)
                    rot_y_max = round(float(self.y_max_le.text()), 1)
                    rot_z_min = round(float(self.z_min_le.text()), 1)
                    rot_z_max = round(float(self.z_max_le.text()), 1)

                    inst_rotation = [
                        round(rand.uniform(rot_x_min, rot_x_max), 1),
                        round(rand.uniform(rot_y_min, rot_y_max), 1),
                        round(rand.uniform(rot_z_min, rot_z_max), 1)]
                    cmds.rotate(inst_rotation[0], inst_rotation[1],
                                inst_rotation[2], new_instance, a=1, ws=1)

    def _create_percentage_scatter(self, vertices):
        ver_val = len(vertices)
        per_val = float(self.slider_sld.value())
        per_vert = per_val / 100
        numb_vert = int(ver_val * per_vert)
        to_remove = numb_vert - ver_val
        high_bound = ver_val - 1
        for i in range(0, (to_remove * -1)):
            temp_vert = rand.randint(0, high_bound)
            del vertices[temp_vert]
            high_bound = high_bound - 1


def readfile(fileName):
	f = open(fileName, "r")
	myList = []
	for line in f:
		myList.append(line)
	print(myList, 3*3)
	f.close()
	return

def main():
	fileName = raw_input("enter filename you like to read:")
	print(fileName)
	readfile(fileName)

main()


import logging

from pushsource import ModuleMdPushItem
from threading import Event

try:
    from time import monotonic
except ImportError:  # pragma: no cover
    from monotonic import monotonic
import concurrent.futures
from collections import defaultdict
from queue import Queue, Full, Empty

from .errors import PhaseInterrupted

LOG = logging.getLogger("pubtools.pulp")

class ContextQueue(object):
    """A Queue wrapper integrating with some Context features:

    - makes get() and put() interruptible if context has failed
    - can have callbacks installed to monitor put & get
      (e.g. for progress tracking)
    """

    def __init__(self, context, **kwargs):
        self._delegate = Queue(**kwargs)
        self.qsize = self._delegate.qsize

        self.before_put = []
        """Callbacks invoked prior to any put()."""

        self.after_put = []
        """Callbacks invoked after a successful put()."""

        self.after_get = []
        """Callbacks invoked after a successful get()."""

        self.__interruptible_put = context.interruptible(
            self._delegate.put, msg="writing to queue"
        )
        self.__interruptible_get = context.interruptible(
            self._delegate.get, msg="reading from queue"
        )

    def put(self, item, block=True, timeout=None):
        for cb in self.before_put:
            cb(item)
        self.__interruptible_put(item, block=block, timeout=timeout)
        for cb in self.after_put:
            cb(item)

    def get(self, block=True, timeout=None):
        out = self.__interruptible_get(block=block, timeout=timeout)
        for cb in self.after_get:
            cb(out)
        return out

class ItemInfo(object):
    """Holds aggregate info on all push items involved in the context.

    This object is used to make out-of-band info available across phases
    beyond just the items passed via queues.
    """

    def __init__(self):
        self.items_known = Event()
        """An event which becomes True during push only after all push
        items have been encountered. Other attributes on this object may
        represent incomplete information until this event becomes True.
        """

        self.items_count = 0
        """How many items are in the push, in total."""

        self.modulemd_count_per_dest = defaultdict(int)
        """How many modulemd items exist per destination in the push."""

    def add_item(self, item):
        """Record an item on this object.

        This should be done only once per item (i.e. do not re-add items
        as state is updated).
        """
        self.items_count += 1

        if isinstance(item.pushsource_item, ModuleMdPushItem):
            for dest in item.pushsource_item.dest:
                self.modulemd_count_per_dest[dest] += 1

class Context(object):
    """A context object shared across all phases.

    The main purpose of the context object is to group all phases
    under a single execution context which can be stopped on demand
    (i.e. if an error occurs). It may also be used to share a small
    amount of out-of-band mutable state between phases.
    """

    def __init__(self):
        self._error = Event()

        self.error_phase = None
        """Name of phase which encountered a fatal error, if one has occurred."""

        self.error_exception = None
        """The exception causing a fatal error, if one has occurred."""

        self.item_info = ItemInfo()
        """Records aggregate info on items in the push."""

        self.interrupt_interval = 5.0
        """Default value of 'interval' for interruptible method.

        This exists only so that it can be overridden from tests.
        """

        self.progress_infos = []
        """All ProgressInfo objects participating in progress tracking for this
        context.

        These should be arranged in display order.
        """

    @property
    def has_error(self):
        """True if and only if the context is in the error state.

        If `has_error` is true, phases should stop processing ASAP.
        """
        return self._error.is_set()

    def set_error(
        self, phase="<unknown phase>", exception=RuntimeError("unknown error")
    ):
        """Set the context into the error state, indicating that a fatal
        error has occurred.
        """
        if not self.has_error:
            self.error_phase = phase
            self.error_exception = exception
            self._error.set()

    def raise_if_interrupted(self, msg):
        """A convenience method to raise an exception if the context has an error.

        'msg' should mention the operation currently being attempted.
        """
        if self.has_error:
            raise PhaseInterrupted("Interrupted while %s" % msg)

    def new_queue(self, **kwargs):
        """Create and return a new Queue.

        The Queue is associated with this context such that, if the context
        enters the error state, any queue operations will be interrupted.
        """
        return ContextQueue(context=self, **kwargs)

    def interruptible(
        self,
        fn,
        msg="performing a blocking operation",
        interval=None,
        timeout_exceptions=(Full, Empty, concurrent.futures.TimeoutError),
    ):
        """Wraps a blocking timeout-accepting function to be interruptible.

        Given a blocking function with a timeout (e.g. queue.put, future.result),
        this method will return a new function with the added behavior that the
        operation can be interrupted if this context enters the error state.

        Under the hood, this works by calling the given function in a loop with
        a smaller timeout than that provided by the caller. This is not ideal
        for efficiency or latency, but is a necessary workaround for the lack of
        an API for a python thread to wait on multiple locks at once.

        Arguments:

            fn (callable)
                Any callable which accepts a 'timeout' argument.

            msg (str)
                Optional message to be included in any raised exceptions on interrupt.
                Use this to provide a bit of context on what the callable is doing.

            interval (float)
                How much time between checks for interruption.

            timeout_exceptions (tuple)
                Exception class(es) to be interpreted as a timeout from fn().
        """
        interval = interval or self.interrupt_interval

        def out(*args, **kwargs):
            self.raise_if_interrupted(msg)

            timeout = kwargs.get("timeout")
            inner_interval = interval
            if timeout is not None:
                inner_interval = min(interval, timeout)

            start_oper = monotonic()

            kwargs["timeout"] = inner_interval

            while True:
                try:
                    # Try the operation for a few seconds.
                    return fn(*args, **kwargs)
                except timeout_exceptions:
                    # interrupted => give up
                    self.raise_if_interrupted(msg)

                    # past the deadline => give up
                    if timeout is not None and monotonic() - start_oper > timeout:
                        # re-raise whatever exception we already got.
                        raise

                    # In any other case we spin and try again soon.

        return out


def solution(lottos, win_nums):
    rank_book = {
        6 : 1,
        5 : 2,
        4 : 3,
        3 : 4,
        2 : 5,
        1 : 6,
        0 : 6,
    }
    win_cnt = 0
    max_cnt = 0
    for l in lottos:
        if l == 0:
            max_cnt += 1
            continue
        for w in win_nums:
            if l == w:
                win_cnt += 1
    max_cnt += win_cnt
    answer = [rank_book.get(max_cnt), rank_book.get(win_cnt)]
    return answer

if __name__ == '__main__':
    lottos = [44, 1, 0, 0, 31, 25]
    win_nums = [31, 10, 45, 1, 6, 19]
    # exptected : [3, 5]
    print(solution(lottos, win_nums))

    lottos_1 = [0, 0, 0, 0, 0, 0]
    win_nums_1 = [38, 19, 20, 40, 15, 25]
    # exptected : [1, 6]
    print(solution(lottos_1, win_nums_1))

    lottos_2 = [45, 4, 35, 20, 3, 9]
    win_nums_2 = [20, 9, 3, 45, 4, 35]
    # exptected : [1, 1]
    print(solution(lottos_2, win_nums_2))


import time

directory = 'C:/users/hai/my projects/google code jam/2012/qualification/D/'

from math import sqrt

def solve (f_in, f_out):
    T = int(f_in.readline())
    for i in range(1,T+1):
        print ('Test Case : ',i)
        H, W, D = [int(x) for x in f_in.readline().split()]
        mat = []
        for line in range(H):
            mat.append(list(f_in.readline().replace('\n','')))
        res = solve_for_one_matrix(mat, D)
        f_out.write('Case #' + str(i) + ': ' + str(res) + '\n')

def gcd (v_speed, h_speed):
    assert v_speed != 0
    assert h_speed != 0
    a = abs(v_speed)
    b = abs(h_speed)
    while a != 0:
        a,b = b%a,a
    return b

def enlarge_matrix (mat, scale):
    assert scale %2 == 0
    height = len(mat)
    width = len(mat[0])
    #mat2 = [['.'] * (width*scale) for x in range(height*scale)]
    for i in range(height):
        for j in range(width):
            p = mat[i][j]
            if p == 'X':
                location_y = i*scale+scale//2
                location_x = j*scale+scale//2
            #elif p == '#':
            #    for t in range(scale):
            #        for s in range(scale):
            #            mat2[i*scale+t][j*scale+s] = '#'
    return len(mat[0])*scale, len(mat)*scale, location_x, location_y

def make_n_moves (n, width, height, scale, location_x, location_y, x_speed, y_speed):
    for i in range(n):
        assert x_speed !=0
        assert location_x >=scale
        assert location_x <=width-scale

        if x_speed < 0 and location_x == scale:
            x_speed = -x_speed
        elif location_x == width-scale and x_speed > 0:
            x_speed = -x_speed

        location_x += x_speed

    for i in range(n):
        assert y_speed != 0
        assert location_y >=scale
        assert location_y <=height-scale

        if location_y == scale and y_speed < 0:
            y_speed = -y_speed
        elif location_y == height-scale and y_speed > 0:
            y_speed = -y_speed

        location_y += y_speed

    return location_x, location_y, x_speed, y_speed

def make_one_move (width, height, scale, location_x, location_y, x_speed, y_speed):
    assert x_speed !=0 and y_speed != 0
    assert location_x >=scale
    assert location_y >=scale
    assert location_x <=width-scale
    assert location_y <=height-scale

    if x_speed < 0 and location_x == scale:
        x_speed = -x_speed
    elif location_x == width-scale and x_speed > 0:
        x_speed = -x_speed
    if location_y == scale and y_speed < 0:
        y_speed = -y_speed
    elif location_y == height-scale and y_speed > 0:
        y_speed = -y_speed

    return location_x+x_speed, location_y+y_speed, x_speed, y_speed

def solve_for_one_matrix (mat, D):
    print (time.ctime())
    count = 0
    print_matrix(mat)
    print ('D = ', D)
    print ('Rays : ')

    good_directions = []
    width, height, location_x, location_y = enlarge_matrix(mat,2)

    # direction down
    if (height-2) - location_y <= D:
        good_directions.append ((0,1))

    # direction up
    if location_y-2 <=D:
        good_directions.append ((0,-1))

    #direction right
    if (width-2) - location_x <= D:
        good_directions.append((1,0))

    #direction left
    if location_x-2 <=D:
        good_directions.append((-1,0))

    print (good_directions)

    # diagonal directions
    for p in range(1, D*2+1):
        for q in range(1, p+1):
            if gcd (p,q) !=1:
                continue
            scale = p*q*2

            move_distance = sqrt(p**2 + q**2)
            if move_distance == round(move_distance):
                allowed_moves = D*scale // int(move_distance)
            else:
                allowed_moves = int(D*scale / move_distance)

            if allowed_moves < scale:
                continue

            width, height, original_location_x, original_location_y = enlarge_matrix(mat,scale)

            #print ('DEBUG: ',p,q,D,allowed_moves)

            arr = [(p,q),(-p,q),(p,-q),(-p,-q),(q,p),(-q,p),(q,-p),(-q,-p)]
            arr = unique(arr)
            for direction in arr:

                #print ('DEBUG:',direction)
                count_moves = 0
                x_speed, y_speed = direction
                continue_in_this_direction = True
                location_x = original_location_x
                location_y = original_location_y
                for i in range(allowed_moves//(scale//2)):
                    retval = make_n_moves(scale//2, width, height, scale, location_x, location_y, x_speed, y_speed)
                    count_moves += scale//2
                    location_x, location_y, x_speed, y_speed = retval
                    if location_x == original_location_x and location_y == original_location_y:
                        good_directions.append((direction[0],direction[1], count_moves, allowed_moves, allowed_moves//(scale//2)*(scale//2)))
                        #print (good_directions[-1], end= ', ')
                        break

    print()
    #print(good_directions)
    count = len(good_directions)
    print (count)
    return count

def unique(arr):
    arr2 = []
    for i in arr:
        if i not in arr2:
            arr2.append(i)
    return arr2

def print_matrix (mat):
    for line in mat:
        print (''.join(line))

def main_run():
    import os
    filenames = [x for x in os.listdir (directory)]
    filenames = [x for x in filenames if x.endswith('.in')]
    l1 = [(os.stat(directory+x).st_mtime, x) for x in filenames]
    chosen_filename =  sorted(l1)[-1][1][:-3]

    print ('Directory : ', directory)
    print ('Chosen Filename : ',chosen_filename)
    print()
    print ('Start : ', time.ctime())
    print()

    f_in = open(directory+chosen_filename+'.in')
    f_out = open(directory+chosen_filename+'.out', 'w')
    solve(f_in,f_out)
    f_in.close()
    f_out.close()

    print ()
    print ('End : ', time.ctime())

main_run()

#test_loop_speed()


from pythonforandroid.toolchain import PythonRecipe
import os
import shutil

class DjangoforandroidRecipe(PythonRecipe):

    version = 'tip'
    #url = 'https://bitbucket.org/yeisoneng/django-for-android/get/{version}.tar.gz'
    url = 'https://bitbucket.org/djangoforandroid/django-for-android/get/{version}.tar.gz'
    depends = ['python3crystax']

    def build_arch(self, arch):
        '''Install the Python module by calling setup.py install with
        the target Python dir.'''
        super(DjangoforandroidRecipe, self).build_arch(arch)

        shutil.rmtree(os.path.join(self.get_build_dir(arch.arch), 'djangoforandroid', 'builder'))
        #shutil.rmtree(os.path.join(self.get_build_dir(arch.arch), 'djangoforandroid', 'd4a'))
        #shutil.rmtree(os.path.join(self.get_build_dir(arch.arch), 'djangoforandroid', 'mdl'))
        shutil.rmtree(os.path.join(self.get_build_dir(arch.arch), 'djangoforandroid', 'recipes'))
        shutil.rmtree(os.path.join(self.get_build_dir(arch.arch), 'djangoforandroid', 'src'))

        self.install_python_package(arch)
        #source, cwd

recipe = DjangoforandroidRecipe()


import json

socketio = wiz.server.wsgi.socketio
branch = wiz.branch()
basenamespace = f"/wiz/app/{branch}"

server = wiz.request.query("server", True)
logs = wiz.request.query("logs", True)
logs = json.loads(logs)

for log in logs:
    mode = log['mode']
    wpid = log['workflow_id']
    to = server + "-" + wpid
    socketio.emit(mode, log, to=to, namespace=f"{basenamespace}/dizest.workflow.editor", broadcast=True)

wiz.response.status(200)


# ready to run example: PythonClient/multirotor/hello_drone.py
import airsim
import os
import cv2
import numpy as np

def parse_camera(in_image):
    img1d = np.fromstring(in_image.image_data_uint8, dtype=np.uint8) # get numpy array
    image = img1d.reshape(in_image.height, in_image.width, 3) # reshape array to 3 channel image array H X W X 3
    # print(img1d.shape, image.shape, end='\r')
    cv2.imshow('image', image)
    cv2.waitKey()

# connect to the AirSim simulator
client = airsim.MultirotorClient()
client.confirmConnection()
client.enableApiControl(True)
client.armDisarm(True)

# take images
responses = client.simGetImages([airsim.ImageRequest("0", airsim.ImageType.Scene, False, False)])
print('Retrieved images: %d', len(responses))

parse_camera(responses[0])


from collections import Counter
groups = []
nums = []
with open("input.txt") as inp:
    group = 0
    num_in_group = 0
    groups.append(Counter())
    nums.append(0)
    for line in inp.readlines():
        line = line.strip()
        if line == "":
            nums.append(0)
            group += 1
            groups.append(Counter())
            continue
        nums[group] += 1
        for char in line:
            groups[group][char] += 1

ans = 0
for i in range(len(groups)):
    for q in groups[i]:
        if groups[i][q] == nums[i]:
            ans += 1
print(ans)


import math
from sys import stdin, setrecursionlimit

setrecursionlimit(10**6)

def calc_dist(X_i, Y_i, X_j, Y_j):
    return math.sqrt((X_i-X_j)**2 + (Y_i-Y_j)**2)

def main():
    N = int(stdin.readline())
    citise = [list(map(int, stdin.readline().split())) for _ in range(N)]
    dist_matrix = [[0]*N for _ in range(N)]
    for i in range(N):
        for j in range(N):
            if i == j:
                dist_matrix[i][j] = 0
            else:
                X_i, Y_i = citise[i]
                X_j, Y_j = citise[j]
                dist = calc_dist(X_i, Y_i, X_j, Y_j)
                dist_matrix[i][j] = dist
                dist_matrix[j][i] = dist
    # for row in dist_matrix:
    #     print(row)

    # dp[i][j] => 既に訪問した都市の集合 i 、現在位置 j である時のその時点での最小移動距離
    # ただし、既に訪問した都市 i には、j を含まない。
    dp = [[math.inf]*N for _ in range(2**N)]

    # 初期化(i = 0、つまり、空集合なので、スタート地点)
    for i in range(N):
        dp[0][i] = 0

    for i in range(1, 2**N):
        for j in range(N):
            # 訪問済み都市集合 i に j 番目の都市が含まれている場合
            # if (i >> j & 1):
            # 訪問済み都市集合 i から、j 番目の都市を抜いた集合 rest_cities
            # rest_cities = i - 2**j

            # # rest_citiesが空集合の時
            # if rest_cities == 0:
            #     for k in range(N):
            #         if k != j:
            #             dp[i][j] = min(dp[i][j], dist_matrix[k][j])
            # else:
            #     for k in range(N):
            #         # rest_citiesの中に、k 番目の都市が含まれている場合、kからjに来た可能性が考えられる
            #         if (rest_cities >> k) & 1 and k != j:
            #             dp[i][j] = min(dp[i][j], dp[rest_cities]
            #    [k] + dist_matrix[j][k])

            # 訪問済み都市集合 i に j 番目の都市が含まれていない場合
            # else:
            for k in range(N):
                # 訪問済み都市集合に k が含まれており、k から j へと来た可能性
                if (i >> k) & 1 and k != j:
                    # print(i, j, k, bin(i), bin(j), bin(k), i >> k)
                    dp[i][j] = min(dp[i][j], dp[i-2**k]
                                   [k] + dist_matrix[k][j])
    for row in dp:
        print(row)
    print(min(dp[-1]))

if __name__ == '__main__':
    main()


from setuptools import setup
REQUIRES = [
    'records',
    'structlog',
    'allure-pytest'
]

setup(
    name='orm_client',
    version='0.1',
    packages=['orm_client'],
    url='https://github.com/DiLysenk/restclient_dl',
    license='MIT',
    author='lysenkodmitry',
    author_email='-',
    install_requires=REQUIRES,
    description='orm_client ohh'
)


from idaapi import PluginForm
from PyQt5 import QtCore,QtWidgets

class ResultClass(PluginForm):
    def OnCreate(self, form):
        self.parent = self.FormToPyQtWidget(form)
        self.items = []
        self.PopulateForm()

    def PopulateForm(self):
        layout = QtWidgets.QVBoxLayout()

        self.table = QtWidgets.QTableWidget()
        self.table.setRowCount(0)
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(["Library Name", "Function Imported Affected", "Exploit address"])
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        layout.addWidget(self.table)
        self.parent.setLayout(layout)

    def add_row(self, data):
        rowPosition = self.table.rowCount()
        self.table.insertRow(rowPosition)
        for col, item in enumerate(data):
            item = QtWidgets.QTableWidgetItem(item)
            item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
            self.table.setItem(rowPosition, col, QtWidgets.QTableWidgetItem(item))

    def OnClose(self, form):
        pass


#Runtime ~0.125s. (Using Binet's formula would be faster.)
import mpmath

#Define recursive Fibonacci function for postive integer n. Use a dictionary to avoid recalculation of results.
def Fibonacci(n, Fibonacci_dict):
    if "{}".format(n) in Fibonacci_dict:
        return Fibonacci_dict["{}".format(n)]
    else:
        new_number = Fibonacci(n-1, Fibonacci_dict) + Fibonacci(n-2, Fibonacci_dict)
        Fibonacci_dict["{}".format(n)] = new_number
        return new_number

Fibonacci_numbers = {"1" : 1, "2" : 1}

#Note that the ratio between two Fibonacci numbers F_n and F_{n+1} approaches the golden ratio "phi" as n tends to infinity. Hence for F_x >= 10^999, a lower bound on x is derived from \phi^x = 10^999.
phi = (1 + mpmath.sqrt(5))/2
x=int(mpmath.ceil(999 * mpmath.log(10) / mpmath.log(phi)))
print("Lower bound of first Fibonacci index to contain one-thousand digits is", x)

#Increment Fibonacci numbers until one with a thousand digits is found. This will occur for n>=4781.
for n in range(1, 5000):
    Fibonacci(n, Fibonacci_numbers)
    if n >= x and Fibonacci(n, Fibonacci_numbers) >= mpmath.mpf(10**999):
        print("First Fibonacci index to contain one-thousand digits is", n)
        break


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

import os
from keras.models import Sequential # Initialise our neural network model as a sequential network
from keras.layers import Conv2D # Convolution operation
from keras.layers import MaxPooling2D # Maxpooling function
from keras.layers import Flatten # Converting 2D arrays into a 1D linear vector.
from keras.layers import Dense # Perform the full connection of the neural network
from keras.preprocessing.image import ImageDataGenerator
from IPython.display import display
from PIL import Image
import cv2
import numpy as np
from sklearn.metrics import accuracy_score
from skimage import io, transform
def cnn_classifier():
    cnn = Sequential()
    cnn.add(Conv2D(32,(3,3),input_shape=(50,50,3), padding='same', activation = 'relu'))
    cnn.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
    cnn.add(Conv2D(64, (3,3), padding='same', activation = 'relu'))
    cnn.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
    cnn.add(Flatten())
    cnn.add(Dense(500, activation = 'relu'))
    cnn.add(Dense(2, activation = 'sigmoid'))
    cnn.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    print("cnn.summary()")
    return cnn
def reshaped_image(image):
    return transform.resize(image,(50, 50, 3))
def load_images_from_folder():
    Images = os.listdir("C:\wasteseg")
    train_images = []
    train_labels = []
    for image in Images:
            l = [0,0]
            if image.find('Bio') != -1:
                path = os.path.join("C:\wasteseg\train", image)
                img = cv2.imread(path)
                train_images.append(reshaped_image(img))
                l = [1,0]
                train_labels.append(l)
            if image.find('non_bio') != -1:
                path = os.path.join("C:\wasteseg\train", image)
                img = cv2.imread(path)
                       # print img_src
                train_images.append(reshaped_image(img))
                l = [0,1]
                train_labels.append(l)
    return np.array(train_images), np.array(train_labels)
def train_test_split(train_images, train_labels, fraction):
    index = int(len(train_images)*fraction)
    return train_images[:index], train_labels[:index],train_images[index:],train_labels[index:]

train_images, train_labels = load_images_from_folder()
test_data, test_labels = load_images_from_folder()
fraction = 0.8
train_data = train_test_split(train_images,train_labels,fraction)
train_labels = train_test_split(train_images, train_labels, fraction)
print ("Train data size: ", len(train_images.shape))
print ("Test data size: ", len(test_data.shape))

cnn = cnn_classifier()
print("train data shape:",train_images.shape)
print("test data shape:",test_data.shape)
idx = np.random.permutation(train_images.shape[0])
print(idx,"67")
cnn.fit(train_images[idx], train_labels[idx], batch_size = 64, epochs = 10)
predicted_test_labels = np.argmax(cnn.predict(test_data), axis=1)
test_labels = np.argmax(test_labels, axis=1)

print ("Actual test labels:", test_labels)
print ("Predicted test labels:", predicted_test_labels)
print ("Accuracy score:", accuracy_score(test_labels, predicted_test_labels))


import os
import cv2
import numpy as np
import argparse

import presenteragent
from acllite_image import AclLiteImage
from acllite_resource import AclLiteReso

PRESENTER_CONF="presenter.conf"

def main(video_path):
    cap = cv2.VideoCapture(frames_input_src)
    chan = presenteragent.presenter_channel.open_channel(BODYPOSE_CONF)
    if chan is None:
        print("Open presenter channel failed")
        return

    while(cap.isOpened()):
        ## Read one frame of the input video ##
        ret, img_original = cap.read()

        if not ret:
            print('Cannot read more, Reach the end of video')
            break

        ## Present Result ##
        if is_presenter_server:
            # convert to jpeg image for presenter server display
            _, jpeg_image = cv2.imencode('.jpg', img_original)
            # construct AclLiteImage object for presenter server
            jpeg_image = AclLiteImage(jpeg_image, img_original.shape[0], img_original.shape[1], jpeg_image.size)
            # send to presenter server
            chan.send_detection_data(img_original.shape[0], img_original.shape[1], jpeg_image, [])

    cap.release()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--input_video_path', type=str, default=None, help="Directory path for video.")
    args = parser.parse_args()

main(args.input_video_path)


import csv
import requests
# Web-scraping of:
# https://drug-interactions.medicine.iu.edu/MainTable.aspx
# Ouverture du fichier CSV en mode lecture
ddi_cyp = []
with open('cyp_ddi_scrap.csv', newline='') as csvfile:
    # Création d'un objet lecteur CSV
    csv_reader = csv.reader(csvfile, delimiter=',', quotechar='"')

    # Parcours des lignes du fichier CSV
    for row in csv_reader:
        # Nettoyage des noms de médicaments
        cleaned_row = [name.strip().lower() for name in row]

        # Ajout de la ligne à la liste ddi_cyp
        ddi_cyp.append(tuple(cleaned_row))

# Liste de noms de médicaments en minuscules
ls_pa = ["citalopram", "amlodipine", "atorvastatin", "pantoprazole", "clopidogrel"]
print(len(ddi_cyp))

my_drugs = []
drugs = []
n = 0
for ddi in ddi_cyp:
    if(ddi[0] not in drugs):
        n += 1
        drugs.append(ddi[0])
        my_drugs.append((n, ddi[0]))

print("nb drugs  in db :", len(my_drugs))

substrates_ddi = []
not_sub_ddi = []
for ddi in ddi_cyp:
    if(ddi[2] == "substrates"):
        substrates_ddi.append(ddi)
    else:
        not_sub_ddi.append(ddi)

ddi_for_fhir = []
for victim in substrates_ddi:
    for perpet in not_sub_ddi:
        if(perpet[3] == "inhebitors"):
            effet = "Augmentation de la Bio disponibilité de %s"%(victim[0])
        else:
            effet = "Diminution de la Bio disponibilité de %s"%(victim[0])
        if(victim[1]==perpet[1]):

            ddi_for_fhir.append({"d1":victim[0],
                "d2":perpet[0],
                "type": "%s_%s_%s"%(perpet[3], perpet[1], perpet[2]),
                "incidence": effet,
            })

print("len sub :", len(substrates_ddi))
print("len non sub :", len(not_sub_ddi))

print("len FHIR DDI :", len(ddi_for_fhir))

print(ddi_for_fhir[2:6])

def get_cyp_fhir_ressource(inter):
    my_resource = """"{
  "resourceType" : "MedicinalProductInteraction",

  "subject" : [{ Reference(Medication/%s) }],
  "description" : "Description clear",
  "interactant" : [{
    "itemReference" : { Reference(Medication/%s) }
    "itemCodeableConcept" : { "text": "No more information" }
  }],
  "type" : { "text": "%s" },
  "effect" : { "text": "Interaction between two drugs" },
  "incidence" : { "text": "%s" },
  "management" : { "text" : "Adapatation posologique ou gestion du plan de prise sinon alternative therapeutique" } // Actions for managing the interaction
}"""%(inter["d1"], inter["d2"], inter["type"], inter["incidence"])

    return my_resource

print(get_cyp_fhir_ressource(ddi_for_fhir[89]))

host = 'https://fhir.st2c88fqxgfh.workload-nonprod-fhiraas.isccloud.io'
api_key = 'ton token'

def create_medication(my_drug):
    my_resource = """{
  "resourceType" : "Medication",
  "id" : "%s",
  "code" : {
    "coding" : [{
      "system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
      "code" : "%s",
      "display" : "%s"
    }]
  }
}"""%(my_drug[0], my_drug[1], my_drug[1])
    return my_resource, my_drug[0]

for drug in my_drugs:
    json_drug,id = create_medication(drug)
    # put the medication in the FHIR server
    url = host + '/Medication'
    # create the headers

    headers = {
        'Content-Type': 'application/json+fhir',
        'x-api-key': api_key
    }

    # make the request
    response = requests.put(url+'/'+str(id), headers=headers, data=json_drug)
    # raise an exception in case of http errors
    response.raise_for_status()


#!/bin/env python3

# Python 2.7 compatibility
from __future__ import division

# GTK and GObject bindings
from gi.repository import Gtk, GObject, Gdk, GdkPixbuf

# Cairo
import cairo

# Numpy
import numpy as np

# Delaunay triangulation
from scipy.spatial import Delaunay

# Various maths functions and constants
from math import pi, cos, sin, tan, exp, asin, acos, atan, log

# Path handling
import os.path

# Enable or disable debugging
DEBUG = False

# IPython for debugging
if DEBUG:
    import IPython

# Class for the fish
class Fish(object):
    radius, nearest, voronoi = range(0, 3)

    default_dt = 1/20

    default_pars = {"mu_u": 10, "sigma_u": 4.2,
                    "theta_u": 0.52, "theta_omega": 4.21,
                    "K_s": 2.5, "K_p": 3, "K_v": 12, "r_u": 4.2,
                    "r_omega": 2.4, "d_c": 30, "delta": 30,
                    "f_W_a": 5.26, "f_W_b": 0.13,
                    "f_c_a": 5, "f_c_b": 0.2,
                    "U_min": 1e-4, "U_max": 30, "Omega_max": 10}

    def __init__(self):
        self.ndim = 5
        self.nfish = 0
        # Initialise the state with no fish
        self.state = np.zeros((0, self.ndim))
        # Parameters for the simulation
        self.tank_radius = 50
        self.dt =  Fish.default_dt # Time step
        self.pars = dict(Fish.default_pars)
        self.grab_strong_multiplier = 10

    @property
    def X(self):
        return self.state[:, :2]

    @property
    def x(self):
        return self.state[:, 0, None] # Avoid squeezing with None

    @property
    def y(self):
        return self.state[:, 1, None]

    @property
    def heading(self):
        return self.state[:, 2, None]

    @property
    def Omega(self):
        return self.state[:, 3, None]

    @property
    def U(self):
        return self.state[:, 4, None]

    def num_fish_update(self, fish_wanted):
        # Change the number of fish in the simulation
        if self.nfish > fish_wanted:
            self.state = np.delete(self.state, np.s_[fish_wanted:], 0)
        elif self.nfish < fish_wanted:
            self.state = np.append(self.state, np.zeros((fish_wanted - self.nfish, self.ndim)), 0)
            for i in range(self.nfish, fish_wanted):
                while True:
                    # Get x and y values within a circular tank
                    x = np.random.uniform(low=-self.tank_radius, high=self.tank_radius)
                    y = np.random.uniform(low=-self.tank_radius, high=self.tank_radius)
                    if (x**2 + y**2) < self.tank_radius**2:
                        break
                # Get a random heading direction
                heading = np.random.uniform(low=0, high=2*pi)
                # Add a fish with zero speed/turning speed
                self.state[i, :] = [x, y, heading, 0, self.pars["U_min"]]
        self.nfish = fish_wanted

    def update(self, method, radius, nearest, debug=False, grab=None, grab_repel=False, grab_strong=False):
        # Extract state variables (Nones are required to prevent dimension squeezing)
        X = self.state[:, :2] # cartesian position
        x = self.state[:, 0, None] # cartesian position x
        y = self.state[:, 1, None] # cartesian position y
        heading = self.state[:, 2, None] # heading angle
        Omega = self.state[:, 3, None] # turning speed
        U = self.state[:, 4, None] # forward speed

        # Easier access to the parameters
        p = self.pars

        # Calculate all-to-all distances
        x_dist = (x.T - x)
        y_dist = (y.T - y)
        self.dist = np.sqrt(x_dist**2 + y_dist**2)

        # Calculate adjacency matrices for all the different methods

        # Get everything with a certain radius
        self.radius_adj = self.dist < radius
        self.radius_adj[np.diag_indices(self.nfish)] = False
        # Get the nearest n neighbours
        idx = np.argsort(self.dist)[:, 1:nearest+1]
        self.nearest_adj = np.zeros((self.nfish, self.nfish), dtype=np.bool)
        self.nearest_adj[np.arange(0, self.nfish).reshape((self.nfish, 1)), idx] = True
        # Calculate the Voronoi tessellation
        if self.nfish > 3:
            # Construct the Delaunay triangulation
            tri = Delaunay(X) # , qhull_options="Qbb Qc Qz Qt") # options needed to make sure all vertices are left in
            # Construct an adjacency matrix from the triangulation
            self.voronoi_adj = np.zeros((self.nfish, self.nfish), dtype=np.bool)
            for simplex in tri.simplices:
                self.voronoi_adj[simplex[0], simplex[1]] = True
                self.voronoi_adj[simplex[0], simplex[2]] = True
                self.voronoi_adj[simplex[1], simplex[0]] = True
                self.voronoi_adj[simplex[1], simplex[2]] = True
                self.voronoi_adj[simplex[2], simplex[0]] = True
                self.voronoi_adj[simplex[2], simplex[1]] = True
        else:
            # All to all coupling if there aren't enough fish
            self.voronoi_adj = np.ones((self.nfish, self.nfish), dtype=np.bool)
        # Choose the correct adjacency matrix
        if method == Fish.radius:
            self.adj = self.radius_adj
        elif method == Fish.nearest:
            self.adj = self.nearest_adj
        else:
            self.adj = self.voronoi_adj

        # Some trig
        sin_heading = np.sin(heading)
        cos_heading = np.cos(heading)

        # Calculate the wall distance for each fish
        x_hx = x*cos_heading
        y_hy = y*sin_heading
        r2_xy = x**2 + y**2
        self.wall_dist = -(x_hx + y_hy) + np.sqrt((x_hx + y_hy)**2 - (r2_xy - self.tank_radius**2))
        self.wall_angle = np.arctan2(y + self.wall_dist*sin_heading,
                                     x + self.wall_dist*cos_heading) - heading
        self.wall_angle[self.wall_angle < -pi] += 2*pi

        # Mask adjacency matrix for distance
        adj = self.adj & (self.dist < p["d_c"])

        # Calculate the number of neighbours
        N_i = adj.sum(axis=1)
        N_i_idx = N_i != 0

        # Calculate the position angle of adjacent fish relative to the heading angle
        self.theta_ij = np.arctan2(y_dist[adj], x_dist[adj]) - np.repeat(heading, N_i) # only bother calculating for adjacent fish for speed

        # Helpers
        cos_theta = np.cos(self.theta_ij)
        sin_theta = np.sin(self.theta_ij)
        phi = heading.T - heading
        if grab is not None:
            phi[:, grab] = 0 # grabbed fish don't interact via alignment
        sin_phi = np.sin(phi[adj])

        # Calculate distance cut off function for adjacent fish
        f_d = 1 - np.exp((self.dist[adj] - p["d_c"])/p["delta"])
        f_d[f_d < 0] = 0

        # Calculate U_i_star
        U_star = np.zeros((self.nfish, self.nfish))
        U_star[adj] = f_d*p["K_s"]*(self.dist[adj] - p["r_u"])*cos_theta
        if grab is not None:
            if grab_repel:
                U_star[:, grab] *= -1
            if grab_strong:
                U_star[:, grab] *= self.grab_strong_multiplier
        U_i_star = U_star.sum(axis=1)
        U_i_star[N_i_idx] /= (N_i[N_i_idx]*p["theta_u"])

        # Calculate Omega_i_star
        U_rep = np.repeat(U, N_i)
        Omega_star = np.zeros((self.nfish, self.nfish))
        Omega_star[adj] = f_d*(1 + cos_theta)*(p["K_p"]*(self.dist[adj] - p["r_omega"])*sin_theta/U_rep
                                                    + U_rep/p["mu_u"]*p["K_v"]*sin_phi/p["theta_omega"])
        if grab is not None:
            if grab_repel:
                Omega_star[:, grab] *= -1
            if grab_strong:
                Omega_star[:, grab] *= self.grab_strong_multiplier
        Omega_i_star = Omega_star.sum(axis=1)
        Omega_i_star[N_i_idx] /= N_i[N_i_idx]

        # Calculate wall avoidance
        f_W = np.sign(self.wall_angle)*p["f_W_a"]*np.exp(-p["f_W_b"]*self.wall_dist)

        # Equations of motion
        dU_dt = -p["theta_u"]*(U - p["mu_u"] - U_i_star.reshape((self.nfish, 1)))
        dOmega_dt = -p["theta_omega"]*(Omega + f_W - Omega_i_star.reshape((self.nfish, 1)))

        # Coupling of the stochastic terms
        f_c = p["f_c_a"]*np.exp(-p["f_c_b"]*U);

        # Euler-Maruyama
        U_new = U + dU_dt*self.dt + np.random.randn(self.nfish, 1)*p["sigma_u"]*np.sqrt(self.dt)
        Omega_new = Omega + dOmega_dt*self.dt + np.random.randn(self.nfish, 1)*f_c*np.sqrt(self.dt)
        Omega_new = Omega_new

        # Check for bounds on speeds/turning speeds
        U_new[U_new < p["U_min"]] = p["U_min"]
        U_new[U_new > p["U_max"]] = p["U_max"]
        Omega_new[Omega_new < -p["Omega_max"]] = -p["Omega_max"]
        Omega_new[Omega_new > p["Omega_max"]] = p["Omega_max"]

        # Plain Euler
        heading_new = np.mod(heading + Omega*self.dt, 2*pi)
        x_new = x + U*cos_heading*self.dt
        y_new = y + U*sin_heading*self.dt

        # Check if any outside the tank
        r2_new = x_new**2 + y_new**2
        idx = r2_new > self.tank_radius**2
        x_new[idx] = x[idx]
        y_new[idx] = y[idx]
        U_new[idx] = p["U_min"]

        # Apply any grabs
        if grab is not None:
            x_new[grab, 0] = x[grab, 0]
            y_new[grab, 0] = y[grab, 0]
            heading_new[grab, 0] = heading[grab, 0]
            Omega_new[grab, 0] = Omega[grab, 0]
            U_new[grab, 0] = U[grab, 0]

        if debug:
            IPython.embed()

        # Update the state
        self.state[:, 0] = x_new[:, 0]
        self.state[:, 1] = y_new[:, 0]
        self.state[:, 2] = heading_new[:, 0]
        self.state[:, 3] = Omega_new[:, 0]
        self.state[:, 4] = U_new[:, 0]

# Handler for the different GUI events
class GUIHandler(object):
    def __init__(self, builder, py_path):
        # Initialise and store any information needed
        self.builder = builder
        for widget in ["zebrafish_demo_window",
                       "talking_points_window",
                       "num_fish_range",
                       "radius_rad", "radius_range",
                       "nearest_rad", "nearest_range",
                       "voronoi_rad",
                       "interaction_area",
                       "show_interactions_chk",
                       "show_voronoi_chk",
                       "grab_strong_chk",
                       "grab_repel_chk",
                       "debug_update_chk",
                       "fish_area",
                       "speed_range",
                       "speed_interaction_range",
                       "speed_rand_range",
                       "turning_interaction_pos_range",
                       "turning_interaction_align_range",
                       "turning_rand_range",
                       "debug_btn"]:
            setattr(self, widget, builder.get_object(widget))

        # Timers to maintain interactivity
        self.pars_update_time = 100 # milliseconds
        self.pars_update_timer = None
        self.draw_time = 50 # milliseconds
        self.draw_timer = GObject.timeout_add(self.draw_time, self.update_fish)

        # Create some fish
        self.fish = Fish()

        # Update the parameters shown in the GUI
        self.on_reset_parameters_btn_clicked(None)

        # Scaling for plotting
        self.fish_plotting_scale = 1

        # For grabbing a fish
        self.grab = None
        self.cr_matrix = None

        # For the talking points
        self.talking_points_pages = {}

        # Attach the signals to this object
        builder.connect_signals(self)

        # Show the main window
        self.zebrafish_demo_window.show_all()
        self.zebrafish_demo_window.maximize()

        # Remove debugging buttons if necessary
        if not DEBUG:
            self.debug_btn.set_visible(False)
            self.debug_update_chk.set_visible(False)

    def update_fish(self):
        # Check that the number of fish hasn't changed
        nfish = int(self.num_fish_range.get_value())
        if self.fish.nfish != nfish:
            self.fish.num_fish_update(nfish)
        # Update the fish simulation
        if self.radius_rad.get_active():
            method = Fish.radius
        elif self.nearest_rad.get_active():
            method = Fish.nearest
        else:
            method = Fish.voronoi
        self.fish.update(method,
                         radius=self.radius_range.get_value(),
                         nearest=round(self.nearest_range.get_value()),
                         debug=self.debug_update_chk.get_active(),
                         grab=self.grab,
                         grab_strong=self.grab_strong_chk.get_active(),
                         grab_repel=self.grab_repel_chk.get_active())
        if self.debug_update_chk.get_active():
            self.debug_update_chk.set_active(False)
        # Draw the fish
        self.fish_area.queue_draw()
        return True

    def on_fish_area_draw(self, drawingarea, cr):
        if not hasattr(self.fish, "adj"):
            # The Fish.update function hasn't been run yet
            return

        # Whether to show interactions
        interactions = self.show_interactions_chk.get_active()

        # The fish
        fish_pos = self.fish.X
        fish_heading = self.fish.heading
        nfish = self.fish.nfish

        # Set up the transformations from tank space to visual space
        width = drawingarea.get_allocated_width()
        height = drawingarea.get_allocated_height()
        scale = 0.5*(min(width, height) - 30)/self.fish.tank_radius
        cr.set_source_rgb(0.4, 0.4, 0.4)
        cr.translate(width/2, height/2)
        cr.scale(scale, -scale)
        self.cr_matrix = cr.get_matrix()
        self.cr_matrix.invert()

        # Draw the tank
        cr.arc(0, 0, self.fish.tank_radius + 12/scale, 0, 2*pi)
        cr.set_line_width(1/scale) # Make sure that the line widths are in pixels
        cr.stroke()

        # Draw the Voronoi tessellation
        if self.show_voronoi_chk.get_active():
            cr.set_line_width(1/scale)
            cr.set_source_rgb(0, 0.6, 0)
            for i in range(0, nfish):
                for j in range(i + 1, nfish):
                    if self.fish.voronoi_adj[i, j]:
                        cr.move_to(fish_pos[i, 0], fish_pos[i, 1])
                        cr.line_to(fish_pos[j, 0], fish_pos[j, 1])
                        cr.stroke()

        # Draw the interaction radius if appropriate
        if self.radius_rad.get_active() and interactions:
            cr.arc(fish_pos[0, 0], fish_pos[0, 1], self.radius_range.get_value(), 0, 2*pi)
            cr.set_line_width(1/scale)
            cr.set_source_rgb(1, 0, 0)
            cr.stroke()

        # Draw the fish
        sc = self.fish_plotting_scale
        for i in range(0, nfish):
            X = fish_pos[i, :]
            heading = fish_heading[i, 0]
            # Save the current transformation matrix
            cr.save()
            # Move from tank space to fish space
            cr.translate(X[0], X[1])
            cr.rotate(heading)
            # Scale to visual sizes
            cr.scale(1/scale, 1/scale)
            # Draw the fish
            cr.move_to(7*sc, 0)
            cr.line_to(0, 4*sc)
            cr.line_to(-12*sc, -1.5*sc)
            cr.line_to(-12*sc, 1.5*sc)
            cr.line_to(0, -4*sc)
            cr.close_path()
            cr.set_line_width(1)
            cr.set_source_rgb(200/255, 207/255, 229/255) # A nice light blue
            cr.fill_preserve()
            if i == 0:
                # Fish zero
                cr.set_source_rgb(0, 0, 1)
            elif self.fish.adj[0, i] and interactions:
                # Adjacent to fish zero
                cr.set_source_rgb(1, 0, 0)
            else:
                # Random fish
                cr.set_source_rgb(0, 0, 0)
            cr.stroke()
            # Restore the transformation matrix
            cr.restore()

    def on_zebrafish_demo_window_delete_event(self, *args):
        # Window has been closed - follow suit
        Gtk.main_quit(*args)

    def on_debug_btn_clicked(self, button):
        IPython.embed()

    def on_par_value_changed(self, range):
        # Put updates on a timer to avoid changing them thousands of times a second
        if self.pars_update_timer is None:
            self.pars_update_timer = GObject.timeout_add(self.pars_update_time, self.update_pars)

    def update_pars(self):
        self.pars_update_timer = None
        self.fish.pars["mu_u"] = self.speed_range.get_value()
        self.fish.pars["K_s"] = self.speed_interaction_range.get_value()
        self.fish.pars["sigma_u"] = self.speed_rand_range.get_value()
        self.fish.pars["K_p"] = self.turning_interaction_pos_range.get_value()
        self.fish.pars["K_v"] = self.turning_interaction_align_range.get_value()
        self.fish.pars["f_c_a"] = self.turning_rand_range.get_value()
        return False

    def on_reset_positions_btn_clicked(self, button):
        # Reset the fish positions
        nfish = self.fish.nfish
        self.fish.num_fish_update(0)
        self.fish.num_fish_update(nfish)

    def on_reset_parameters_btn_clicked(self, button):
        # Set the default parameters in the GUI
        self.speed_range.set_value(Fish.default_pars["mu_u"])
        self.speed_interaction_range.set_value(Fish.default_pars["K_s"])
        self.speed_rand_range.set_value(Fish.default_pars["sigma_u"])
        self.turning_interaction_pos_range.set_value(Fish.default_pars["K_p"])
        self.turning_interaction_align_range.set_value(Fish.default_pars["K_v"])
        self.turning_rand_range.set_value(Fish.default_pars["f_c_a"])
        self.fish.pars = dict(Fish.default_pars)

    def on_fish_area_button_press_event(self, widget, event):
        if self.cr_matrix is not None:
            pt = self.cr_matrix.transform_point(event.x, event.y)
            self.grab = np.argmin((self.fish.x - pt[0])**2 + (self.fish.y - pt[1])**2)

    def on_fish_area_button_release_event(self, widget, event):
        self.grab = None

    def on_fish_area_motion_notify_event(self, widget, event):
        if self.grab is not None:
            if self.cr_matrix is not None:
                pt = self.cr_matrix.transform_point(event.x, event.y)
                dist = np.sqrt(pt[0]**2 + pt[1]**2)
                if dist > (self.fish.tank_radius - 0.1):
                    angle = np.arctan2(pt[1], pt[0])
                    dist = self.fish.tank_radius - 0.1
                    pt = (dist*cos(angle), dist*sin(angle))
                self.fish.state[self.grab, 0] = pt[0]
                self.fish.state[self.grab, 1] = pt[1]

    def on_talking_points_btn_clicked(self, button):
        # Bring the talking points window to the front (and show if not already showing)
        self.talking_points_window.present()

    def on_talking_points_area_realize(self, widget):
        # Load the talking points text (SVG images)
        sc = widget.get_scale_factor()
        page = widget.get_name()
        width = sc*widget.get_allocated_width()
        height = sc*widget.get_allocated_height()
        svg = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(py_path, page), width, height, True)
        surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        cr = cairo.Context(surf)
        Gdk.cairo_set_source_pixbuf(cr, svg, 0, 0)
        cr.paint()
        self.talking_points_pages[page] = surf

    def on_close_btn_clicked(self, button):
        # Hide the talking points window
        self.talking_points_window.hide()

    def on_talking_points_area_draw(self, drawing_area, cr):
        # This is basically a fudge to make it look good on HiDPI screens (like mine...)
        sc = 1/drawing_area.get_scale_factor()
        cr.scale(sc, sc)
        cr.set_source_surface(self.talking_points_pages[drawing_area.get_name()])
        cr.paint()

# Work out where the Python file is
py_path = os.path.dirname(os.path.realpath(__file__))

# Build the GUI
builder = Gtk.Builder()
builder.add_from_file(os.path.join(py_path, "zebrafish_demo.glade"))
gui = GUIHandler(builder, py_path)

# Start the main loop
Gtk.main()