import io
import os
import shutil
import warnings
from collections import OrderedDict

import six

from dagster import check, utils
from dagster.core.definitions import RepositoryDefinition
from dagster.core.errors import DagsterInvariantViolationError
from dagster.core.scheduler import Schedule
from dagster.core.serdes import (
    ConfigurableClass,
    deserialize_json_to_dagster_namedtuple,
    serialize_dagster_namedtuple,
)

from .base import ScheduleStorage

class FilesystemScheduleStorage(ScheduleStorage, ConfigurableClass):
    def __init__(self, base_dir, inst_data=None):
        self._base_dir = check.str_param(base_dir, 'base_dir')
        self._inst_data = inst_data
        self._schedules = OrderedDict()
        self._load_schedules()

    @property
    def inst_data(self):
        return self._inst_data

    @classmethod
    def config_type(cls):
        return {'base_dir': str}

    @staticmethod
    def from_config_value(inst_data, config_value):
        return FilesystemScheduleStorage.from_local(inst_data=inst_data, **config_value)

    @staticmethod
    def from_local(base_dir, inst_data=None):
        return FilesystemScheduleStorage(base_dir, inst_data)

    def all_schedules(self, repository=None):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        # TODO: Check for repository=None

        if repository.name not in self._schedules:
            return []

        return [s for s in self._schedules[repository.name].values()]

    def get_schedule_by_name(self, repository, schedule_name):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.str_param(schedule_name, 'schedule_name')

        if repository.name not in self._schedules:
            return None

        return self._schedules[repository.name].get(schedule_name)

    def add_schedule(self, repository, schedule):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.inst_param(schedule, 'schedule', Schedule)

        if not repository.name in self._schedules:
            self._schedules[repository.name] = OrderedDict()

        self._schedules[repository.name][schedule.name] = schedule
        self._write_schedule_to_file(repository, schedule)

    def update_schedule(self, repository, schedule):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.inst_param(schedule, 'schedule', Schedule)

        if repository.name not in self._schedules:
            raise DagsterInvariantViolationError(
                'Repository {repository_name} is not present in storage'.format(
                    repository_name=repository.name
                )
            )

        if schedule.name not in self._schedules[repository.name]:
            raise DagsterInvariantViolationError(
                'Schedule {name} is not present in storage'.format(name=schedule.name)
            )

        self.add_schedule(repository, schedule)

    def delete_schedule(self, repository, schedule):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.inst_param(schedule, 'schedule', Schedule)

        if repository.name not in self._schedules:
            raise DagsterInvariantViolationError(
                'Repository {repository_name} is not present in storage'.format(
                    repository_name=repository.name
                )
            )

        if schedule.name not in self._schedules[repository.name]:
            raise DagsterInvariantViolationError(
                'Schedule {name} is not present in storage'.format(name=schedule.name)
            )

        self._schedules[repository.name].pop(schedule.name)
        self._delete_schedule_file(repository, schedule)

    def wipe(self):
        self._schedules = OrderedDict()
        for repository_name in self._schedules.keys():
            shutil.rmtree(os.path.join(self._base_dir, repository_name))

    def _write_schedule_to_file(self, repository, schedule):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.inst_param(schedule, 'schedule', Schedule)

        repository_folder = os.path.join(self._base_dir, repository.name)
        utils.mkdir_p(repository_folder)

        metadata_file = os.path.join(repository_folder, '{}.json'.format(schedule.name),)

        with io.open(metadata_file, 'w+', encoding='utf-8') as f:
            f.write(six.text_type(serialize_dagster_namedtuple(schedule)))

        return metadata_file

    def _delete_schedule_file(self, repository, schedule):
        check.inst_param(repository, 'repository', RepositoryDefinition)
        check.inst_param(schedule, 'schedule', Schedule)

        metadata_file = os.path.join(
            self._base_dir, repository.name, '{}.json'.format(schedule.name),
        )

        os.remove(metadata_file)

    def _load_schedules(self):
        schedules_dir = os.path.join(self._base_dir)
        utils.mkdir_p(schedules_dir)

        for repository_name in os.listdir(schedules_dir):
            if not os.path.isdir(os.path.join(schedules_dir, repository_name)):
                continue

            self._schedules[repository_name] = {}
            for file in os.listdir(os.path.join(schedules_dir, repository_name)):
                if not file.endswith('.json'):
                    continue
                file_path = os.path.join(schedules_dir, repository_name, file)
                with open(file_path) as data:
                    try:
                        schedule = deserialize_json_to_dagster_namedtuple(data.read())
                        self._schedules[repository_name][schedule.name] = schedule

                    except Exception as ex:  # pylint: disable=broad-except
                        warnings.warn(
                            'Could not parse dagster schedule from {file_name} in {dir_name}. '
                            '{ex}: {msg}'.format(
                                file_name=file,
                                dir_name=self._base_dir,
                                ex=type(ex).__name__,
                                msg=ex,
                            )
                        )
                        continue


import numpy as np
import cv2
import os
import sys
import time
import picamera
import picamera.array
import argparse
import RPi.GPIO as GPIO
import asyncio
import concurrent.futures
import firebase_admin
from firebase_admin import db
from firebase_admin import credentials

#GPIO INIT
servoPIN = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(servoPIN, GPIO.OUT)

p = GPIO.PWM(servoPIN, 50) # GPIO 17 for PWM with 50H
p.start(7.5) # Initialization

#CONSTANT
COLOR_TEXT={'R':0,'O':1,'Y':2,'G':3,'B':4}
COLORS=[[[120,160,0],[140,255,255]], [[101,170,0],[116,255,255]], [[85,150,0],[95,255,255]], [[50,180,50],[75,255,255]], [[10,190,90],[19,255,255]]]

#COMAND LINE ARGUMENTS
ap = argparse.ArgumentParser()

ap.add_argument("-s", "--showcamera", type=int, default=0,
	help="whether or not the Raspberry Pi camera should be displayed")
ap.add_argument("-f", "--framerate", type=int, default=30,
        help="the framerate that the camera gets updated")
ap.add_argument("-r", "--resolution", type=int, default=480,
        help="resolution of camera")
ap.add_argument("-c", "--colour", type=int, default=0,
        help="color to sort out (R, O, Y, G, B)")
args = vars(ap.parse_args())

#Globals
showcamera = args["showcamera"]
framerate = args["framerate"]
resolution = [int(args["resolution"]/3*4), int(args["resolution"])]
range = COLORS[args["colour"]]

cred = credentials.Certificate('firebase-adminsdk.json')
# Initialize the app with a service account, granting admin privileges
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://lego-sorter.firebaseio.com/'
})
executor = concurrent.futures.ThreadPoolExecutor(max_workers=20)

db_data = {'motor':0,'color':'R'}

#FUNCTIONS
async def get_data():
    while True:
        ref = db.reference('sorter')
        global db_data
        global range
        db_data = await asyncio.get_event_loop().run_in_executor(executor, ref.get)
        range = COLORS[db_data['color']]
        await asyncio.sleep(0.1)

def moveServo():
    p.ChangeDutyCycle(2) # turn towards 180 degree
    time.sleep(0.6) # sleep 1 second
    p.ChangeDutyCycle(5) # turn towards 0 degree

def region_of_interest(img, vertices):
    mask = np.zeros_like(img)

    if len(img.shape) > 2:
        channel_count = img.shape[2]
        ignore_mask_color = (255,) * channel_count
    else:
        ignore_mask_color = 255

    cv2.fillPoly(mask, vertices, ignore_mask_color)

    masked_image = cv2.bitwise_and(img, mask)
    return masked_image

def objectFound():
    moveServo()
    print("Found Object")

def mask_image_from_colour(image, lower, upper):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.GaussianBlur(hsv, (11, 11), 0)
    mask = cv2.inRange(mask, lower, upper)
    res = cv2.bitwise_and(hsv, hsv, mask=mask)
    res = cv2.cvtColor(cv2.cvtColor(res, cv2.COLOR_HSV2BGR), cv2.COLOR_BGR2GRAY)
    res = cv2.erode(res, None, iterations=2)
    res = cv2.dilate(res, None, iterations=5)
    return res

def draw_contours(image, masked):
    newImage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    _ , contours, _ = cv2.findContours(masked, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(newImage, contours, -1, (255, 255, 0), 1)
    for cnt in contours:
        M = cv2.moments(cnt)
        (x,y),radius = cv2.minEnclosingCircle(cnt)
        if(radius > 10):
            #cv2.circle(newImage,center,radius,(0,255,0),2)
            objectFound()
            return newImage
    return newImage

def processed_image(image):
    global range
    lower_colour = np.array(range[0])
    upper_colour = np.array(range[1])
    masked = mask_image_from_colour(image, lower_colour, upper_colour)
    return draw_contours(image, masked)

async def main():
    print('Starting')
    future = asyncio.ensure_future(get_data())
    with picamera.PiCamera() as camera:
        with picamera.array.PiRGBArray(camera) as output:
            global resolution
            global framerate
            camera.resolution = (resolution[0], resolution[1]) #(192, 144)
            camera.framerate = framerate
            while(1):
                camera.capture(output, 'rgb')
                try:
                    global db_data
                    global showcamera
                    global img
                    print(db_data)
                    img = output.array
                    output.truncate(0)
                    result = processed_image(img)
                    await asyncio.sleep(0.05)
                    if (showcamera == True):
                        cv2.imshow('img',result)
                    if 0xFF & cv2.waitKey(5) == 27:
                        break
                except KeyboardInterrupt:
                    pass
                    print ('KB interrupted')
                    print ('Process Aborted!')
                    break
                except Exception as e:
                    exc_type, exc_obj, tb = sys.exc_info()
                    lineno = tb.tb_lineno
                    print ('Error : ' + str(e) + " @ line " + str(lineno))
                finally:
                    pass
    p.stop()
    GPIO.cleanup()
    cv2.destroyAllWindows()
    print ('Aborted')
    future.cancel()
if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())


import pygame
import math
import time
import random

SCREEN_LENGTH = 1200
SCREEN_WIDTH = 800

BALL_LENGTH = 50
BALL_WIDTH = 50
BALL_MAX_Y = 728

COIN_LENGTH = 75
COIN_WIDTH = 75

LINE_WIDTH = 3

GRAVITY = 9
FRICTION = 0.9

# Colors
BLUE = (0, 62, 81)
WHITE_GREY = (250, 250, 250)

# Initialize the pygame
pygame.init()
pygame.font.init()
pygame.mixer.pre_init(44100, -16, 1, 512)

# Fonts
B_FONT = pygame.font.SysFont('Comic Sans MS', 45)

# Create the screen
screen = pygame.display.set_mode((SCREEN_LENGTH, SCREEN_WIDTH))

# Icon and title
pygame.display.set_caption("Gravity Ball")
programIcon = pygame.image.load('images/ball.png')
pygame.display.set_icon(programIcon)

# Player
class Player:
    def __init__(self):
        self.img = pygame.transform.scale(
            pygame.image.load('images/ball.png').convert_alpha(), (BALL_LENGTH, BALL_WIDTH))
        self.x = 600
        self.y = BALL_MAX_Y
        self.is_ready = True
        self.mass = 1
        self.velX = 0
        self.velY = 0
        self.last = pygame.time.get_ticks()
        self.cool_down = 1000
        self.is_set_timer = False
        self.coins = 0
        self.high_score = 0

    def movement(self):
        mouse_pos = pygame.mouse.get_pos()
        mouse_pos_x = mouse_pos[0]
        mouse_pos_y = mouse_pos[1]
        hit_sound = pygame.mixer.Sound('sounds/select.ogg')
        hit_sound.set_volume(0.1)

        distance = math.sqrt((mouse_pos_x - self.x) ** 2 +
                             (self.y - mouse_pos_y) ** 2)  # Distance between the ball and the mouse

        if mouse_pos_x < self.x:
            distance = -distance

        # Draw a line from the ball to the mouse
        lineX_start = self.x + 25
        lineY_start = self.y + 25
        lineX_end = mouse_pos_x
        lineY_end = mouse_pos_y

        # Stop the line when hitting the ground
        if lineY_end >= BALL_MAX_Y + 25:
            lineY_end = BALL_MAX_Y + 25

        # When the ball is stopped and ready for the next move, draw a line
        if self.is_ready:
            pygame.draw.line(screen, WHITE_GREY, (lineX_start, lineY_start), (lineX_end, lineY_end), LINE_WIDTH)

        # Move the ball to the destination
        if pygame.mouse.get_pressed(3)[0] is True and self.is_ready is True:
            self.is_ready = False
            srcX = lineX_start
            srcY = lineY_start
            dstX = lineX_end
            dstY = lineY_end
            self.velX = (dstX - srcX) / 5
            self.velY = (srcY - dstY) / 5

        # While the ball is moving
        if self.is_ready is False:
            self.x += self.velX
            self.y -= self.velY

            # Lower the x speed
            if self.velX > 1:
                self.velX -= FRICTION * self.mass
            elif self.velX < -1:
                self.velX += FRICTION * self.mass
            elif 1 > self.velX > -1:
                self.velX = 0

            # If the ball touches the ground
            if self.y < BALL_MAX_Y:
                self.velY -= self.mass * GRAVITY
            if self.y > BALL_MAX_Y:
                hit_sound.play()
                self.velY = -self.velY - self.mass * GRAVITY
                self.y = BALL_MAX_Y

            # If the ball touches one of the x borders
            if self.x <= 20 or self.x >= 1150:  # Borders of the x board
                hit_sound.play()
                self.velX = -self.velX

            # Check if the ball stopped in the ground
            if self.y == BALL_MAX_Y and self.velX == 0 and self.velY < 1:
                if self.is_set_timer is False:
                    self.last = pygame.time.get_ticks()
                    self.cool_down = 1000  # 1 Second timer
                self.is_set_timer = True
                if self.is_set_timer is True:
                    now = pygame.time.get_ticks()
                    if now - self.last >= self.cool_down:
                        self.last = now
                        self.is_ready = True
                        self.is_set_timer = False
                        hit_sound.stop()

    def update_score(self):
        score_txt = B_FONT.render('Score is: ' + str(self.coins), False, WHITE_GREY)
        high_score_txt = B_FONT.render('High score is: ' + str(self.high_score), False, WHITE_GREY)
        screen.blit(score_txt, (5, 5))
        screen.blit(high_score_txt, (300, 5))
        if self.coins > int(self.high_score):
            self.set_high_score(self.coins)

    def get_high_score(self):
        high_score_file = open("Score.txt", "r")
        high_score = high_score_file.read()
        self.high_score = int(str(high_score))
        high_score_file.close()

    def set_high_score(self, new_score):
        high_score_file = open("Score.txt", "w")
        high_score_file.write(str(new_score))
        high_score_file.close()
        self.high_score = new_score

class Coin:
    def __init__(self):
        self.img = pygame.transform.scale(
            pygame.image.load('images/coin.png').convert_alpha(), (COIN_LENGTH, COIN_WIDTH))
        self.x = random.randrange(100, 1100)
        self.y = random.randrange(100, BALL_MAX_Y - 100)
        self.is_taken = False

    def coin_master(self, player):
        # Draw a box collider on the player sprite
        player_col = pygame.Rect(player.x, player.y, BALL_LENGTH, BALL_WIDTH)
        pygame.draw.rect(screen, [0, 0, 0, 255], player_col, 1)
        # Draw a box collider on the coin sprite
        coin_col = pygame.Rect(self.x, self.y, COIN_LENGTH, COIN_WIDTH)
        pygame.draw.rect(screen, [0, 0, 0, 255], coin_col, 1)

        if self.is_taken and player.is_ready:
            self.x = random.randrange(100, 1100)
            self.y = random.randrange(100, BALL_MAX_Y - 100)
            self.is_taken = False

        elif player_col.colliderect(coin_col):
            player.coins += 1
            self.is_taken = True
            self.x = -1000

        screen.blit(self.img, (self.x, self.y))

def init_background():
    screen.fill(BLUE)  # Set the background color to blue
    ground = pygame.transform.scale(pygame.image.load('images/ground.png').convert_alpha(), (1200, 600))
    screen.blit(ground, (0, 200))  # Make the ground visible in the display

def main_menu():
    result = 2
    select_sound = pygame.mixer.Sound('sounds/got_coin.wav')
    select_sound.set_volume(0.1)

    main_menu_start_button = pygame.Rect(400, 200, 400, 75)
    main_menu_quit_button = pygame.Rect(400, 300, 400, 75)

    start_txt = B_FONT.render('Start', False, WHITE_GREY)
    quit_txt = B_FONT.render('Quit', False, WHITE_GREY)

    # Start button
    if main_menu_start_button.collidepoint(pygame.mouse.get_pos()):
        pygame.draw.rect(screen, [70, 101, 99], main_menu_start_button)
        if pygame.mouse.get_pressed(3)[0]:
            select_sound.play()
            result = 1
    else:
        pygame.draw.rect(screen, [60, 91, 89], main_menu_start_button)

    if main_menu_quit_button.collidepoint(pygame.mouse.get_pos()):
        pygame.draw.rect(screen, [70, 101, 99], main_menu_quit_button)
        if pygame.mouse.get_pressed(3)[0]:
            select_sound.play()
            result = 0
    else:
        pygame.draw.rect(screen, [60, 91, 89], main_menu_quit_button)

    screen.blit(start_txt, (550, 200))
    screen.blit(quit_txt, (555, 300))

    return result

def main():
    is_running = True
    is_menu = True
    player = Player()
    coin = Coin()

    player.get_high_score()

    # Game loop
    while is_running is True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                is_running = False

        # Basic initializing to the world
        init_background()  # Draw the background
        screen.blit(player.img, (player.x, player.y))  # Make the player visible in the display

        if is_menu:  # Main menu
            if main_menu() == 1:  # Start
                is_menu = False
                time.sleep(0.2)  # little delay before we start the game
            elif main_menu() == 2:  # None
                is_menu = True
            else:  # Quit
                is_running = False

        else:  # Game
            player.movement()  # Movement
            player.update_score()  # Update the score
            coin.coin_master(player)  # Coin

        pygame.display.update()  # updates the display

if __name__ == "__main__":
    main()


#  This file is part of Boatswain.
#
#      Boatswain<https://github.com/theboatswain> 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.
#
#      Boatswain 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 Boatswain.  If not, see <https://www.gnu.org/licenses/>.
#
#

import os
import subprocess
from contextlib import closing

from PyQt5.QtCore import QFile

from boatswain_updater.utils import sys_utils
from docker.types import CancellableStream

total_mem = None

class EmptyStream(CancellableStream):

    def __init__(self):
        super().__init__(None, None)

    def __iter__(self):
        return self

    def __next__(self):
        raise StopIteration

    next = __next__

    def close(self):
        pass

def splitAll(path):
    all_parts = []
    while 1:
        parts = os.path.split(path)
        if parts[0] == path:  # sentinel for absolute paths
            all_parts.insert(0, parts[0])
            break
        elif parts[1] == path:  # sentinel for relative paths
            all_parts.insert(0, parts[1])
            break
        else:
            path = parts[0]
            all_parts.insert(0, parts[1])
    return all_parts

def disconnectAllSignals(widget):
    try:
        widget.disconnect()
    except TypeError:
        return

def getPhysicalMemory():
    global total_mem
    if total_mem:
        return total_mem / (1024. ** 2)
    if sys_utils.isWin():
        res = subprocess.run(['wmic', 'ComputerSystem', 'get', 'TotalPhysicalMemory'], stdout=subprocess.PIPE)
        output = res.stdout.decode('utf-8')
        total = int(output.replace('TotalPhysicalMemory', '').strip())
    elif sys_utils.isLinux():
        mem_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')  # e.g. 4015976448
        total = mem_bytes
    else:
        res = subprocess.run(['sysctl', '-n', 'hw.memsize'], stdout=subprocess.PIPE)
        output = res.stdout.decode('utf-8')
        total = int(output.strip())
    total_mem = total
    return total / (1024. ** 2)

def isFrost():
    with closing(QFile(':/certifi/cacert.pem')) as frozen_file:
        if frozen_file.open(QFile.ReadOnly):
            return True
    return False


from pyItunes import Song
from typing import List, Dict
from path import Path
import lxml.etree
from migrate_itunes_to_rhythmbox import common
from time import struct_time
import calendar

# different rating scales. itunes: 0 (no star) - 100 (5 stars). rhythmbox: 0-5.
ITUNES_TO_RHYTHMBOX_RATINGS_MAP = {0: 0, 20: 1, 40: 2, 60: 3, 80: 4, 100: 5, None: None}

class SongStatistic:
    def __init__(self, play_count: int, rating: int, last_played_timestamp: str):
        self.play_count = play_count
        self.rating = rating
        self.last_played_timestamp = last_played_timestamp

class IntegrationLog:
    def __init__(self):
        self.rhythmbox_song_entries_changed = 0

    def increment_changed_song_counter(self):
        self.rhythmbox_song_entries_changed += 1

    def something_was_changed(self) -> bool:
        return self.rhythmbox_song_entries_changed != 0

def set_values(itunes_songs: Dict[int, Song], target_rhythmdb: Path, itunes_library_root: str, rhythmbox_library_root: str) -> IntegrationLog:
    itunes_statistics_dict = create_itunes_statistic_dict(itunes_songs, itunes_library_root)

    rhythmdb = lxml.etree.parse(target_rhythmdb)
    root = rhythmdb.getroot()
    log = integrate_statistics_into_rhythmdb(root, itunes_statistics_dict, rhythmbox_library_root)

    if log.something_was_changed():
        common.write_to_file(root, target_rhythmdb, add_standalone_to_xml_declaration=True)
    return log

def integrate_statistics_into_rhythmdb(root, itunes_statistics_dict: Dict[str, SongStatistic], rhythmbox_library_root: str) -> IntegrationLog:
    log = IntegrationLog()
    rhythmdb_song_entries = root.getchildren()
    for rhythmdb_song_entry in rhythmdb_song_entries:
        location = rhythmdb_song_entry.find("location").text
        canonical_location = create_canonical_location_for_rhythmbox(location, rhythmbox_library_root)
        if canonical_location in itunes_statistics_dict:
            itunes_statistics = itunes_statistics_dict[canonical_location]
            integrate_statistics_into_entry(itunes_statistics, rhythmdb_song_entry)
            log.increment_changed_song_counter()
    return log

def integrate_statistics_into_entry(itunes_statistics, rhythmdb_song_entry):
    integrate_value_to_rhythmdb_song_entry(rhythmdb_song_entry, "play-count", itunes_statistics.play_count)
    integrate_value_to_rhythmdb_song_entry(rhythmdb_song_entry, "rating", itunes_statistics.rating)
    integrate_value_to_rhythmdb_song_entry(rhythmdb_song_entry, "last-played", itunes_statistics.last_played_timestamp)

def integrate_value_to_rhythmdb_song_entry(rhythmdb_song_entry, rhythmdb_node_name, itunes_value):
    rhythmdb_value_node = rhythmdb_song_entry.find(rhythmdb_node_name)
    if itunes_value is None and rhythmdb_value_node is not None:
        rhythmdb_song_entry.remove(rhythmdb_value_node)
    elif itunes_value is not None and rhythmdb_value_node is None:
        rhythmdb_value_node = lxml.etree.SubElement(rhythmdb_song_entry, rhythmdb_node_name)
        rhythmdb_value_node.text = str(itunes_value)
    elif itunes_value is not None and rhythmdb_value_node is not None:
        rhythmdb_value_node.text = str(itunes_value)

def create_itunes_statistic_dict(itunes_songs: Dict[int, Song], itunes_library_root: str) -> Dict[str, SongStatistic]:
    """use canonical location as a common identifier. returns dict[canonical_location -> SongStatistic(play_count, rating)]"""
    dict = {}
    for itunes_song in itunes_songs.values():
        if itunes_song.location_escaped is not None:
            count = itunes_song.play_count
            last_played = itunes_song.lastplayed
            last_played_timestamp = calendar.timegm(last_played) if last_played is not None else None
            itunes_rating = itunes_song.rating
            mapped_rating = ITUNES_TO_RHYTHMBOX_RATINGS_MAP[itunes_rating]
            location = itunes_song.location_escaped
            canonical_location = create_canonical_location_for_itunes_location(location, itunes_library_root)
            dict[canonical_location] = SongStatistic(count, mapped_rating, last_played_timestamp)
        else:
            print("   Can't assign the track [{} - {}] because there is no file location defined. It's probably a remote file."
                  .format(itunes_song.artist, itunes_song.name))
    return dict

PREFIX_ITUNES_ON_WINDOWS = "file://localhost/"
PREFIX_ITUNES_ON_MAC = "file://"
PREFIX_RHYTHMBOX = "file://"

def create_canonical_location_for_itunes_location(itunes_location: str, itunes_library_root: str):
    # don't mix up order
    if itunes_location.startswith(PREFIX_ITUNES_ON_WINDOWS):
        return itunes_location.replace(PREFIX_ITUNES_ON_WINDOWS + itunes_library_root, "")
    if itunes_location.startswith(PREFIX_ITUNES_ON_MAC):
        return itunes_location.replace(PREFIX_ITUNES_ON_MAC + itunes_library_root, "")
    print("""   The itunes location {} doesn't start with a known prefix.
    It's likely that we can't match it later to a rhythmbox path.""".format(itunes_location))
    return itunes_location

def create_canonical_location_for_rhythmbox(rhythmbox_location: str, rhythmbox_library_root: str):
    if rhythmbox_location.startswith(PREFIX_RHYTHMBOX):
        return rhythmbox_location.replace(PREFIX_RHYTHMBOX + rhythmbox_library_root, "")
    print("""   The rhythmbox location {} doesn't start with a known prefix.
    It's likely that we can't match it later to a itunes path.""".format(rhythmbox_location))
    return rhythmbox_location


from typing import NamedTuple, Optional, List, Set

from etcd3 import Etcd3Client

from tfci.dsl.ast import Identifier, Constant
from tfci.dsl.struct import OpcodeArgs
from tfci.dsm.struct import StackFrame, ThreadContext

class ExecutionError(Exception):
    pass

class ExecutionSingleton:
    # a singleton is essentially an interface to the world for all of the opcodes.
    def __init__(self, db: Etcd3Client):
        self._db = db  # type: Optional[Etcd3Client]

    @property
    def db(self) -> Etcd3Client:
        return self._db

class ExecutionContext(NamedTuple):
    singleton: ExecutionSingleton

    args: OpcodeArgs
    nip: Optional[str]
    thread: ThreadContext
    stack: List[StackFrame]
    stacks_updated: Set[int]

    @classmethod
    def new(
        self,
        singleton: ExecutionSingleton,

        args: OpcodeArgs,
        nip: Optional[str],
        thread: ThreadContext,
        stack: List[StackFrame]
    ):
        return ExecutionContext(singleton, args, nip, thread, stack, set())

    def resolve_item(self, arg):
        if isinstance(arg, Identifier):
            return self.stack_get(arg.name, arg.level)
        elif isinstance(arg, Constant):
            return arg.value
        else:
            raise NotImplementedError(f'{arg}')

    @classmethod
    def stack_idx(cls, level):
        return level

    def stack_load(self, level=0):
        r = self.stack[self.stack_idx(level)]

        if r is None:
            raise ExecutionError(
                f'(stack_load) `{self.thread.id}:{self.thread.ip}` stack at level=`{level}` is NULL') from None
        return r

    def stack_get(self, name, level=0):
        try:
            return self.stack_load(level).get(name)
        except IndexError:
            raise ExecutionError(
                f'(stack_get) `{self.thread.id}:{self.thread.ip}` references `{name}:{level}` but Levels=`{len(self.stack)}`') from None
        except KeyError:
            raise ExecutionError(
                f'(stack_get) `{self.thread.id}:{self.thread.ip}` references `{name}:{level}` but name does not exist') from None

    def stack_set(self, val, name, level=0):
        try:
            stack_idx = self.stack_idx(level)
            self.stack_load(level).set(name, val)
            self.stacks_updated.add(stack_idx)
        except IndexError:
            raise ExecutionError(
                f'(stack_set) `{self.thread.id}:{self.thread.ip}` references `{name}:{level}` but Levels=`{len(self.stack)}`')
        except KeyError:
            raise ExecutionError(
                f'(stack_set) `{self.thread.id}:{self.thread.ip}` references `{name}:{level}` but name does not exist')

    def resolve_arg(self, idx):
        if len(self.args) <= idx:
            raise ExecutionError(f'`{self.thread.id}:{self.thread.ip}` cannot resolve arg at index {idx}: too few args')

        jmp = self.args[idx]

        if isinstance(jmp, Identifier):
            jmp = self.stack_get(jmp.name, jmp.level)
        elif isinstance(jmp, Constant):
            jmp = jmp.value
        else:
            raise ExecutionError(f'(resolve_arg) `{self.thread.id}:{self.thread.ip}` Incorrect arg: {repr(jmp)}')

        return jmp


import cv2
import numpy as np

def get_neighbors_pixel(
    image: np.ndarray, x_coordinate: int, y_coordinate: int, center: int
) -> int:
    """
    Comparing local neighborhood pixel value with threshold value of centre pixel.
    Exception is required when neighborhood value of a center pixel value is null.
    i.e. values present at boundaries.

    :param image: The image we're working with
    :param x_coordinate: x-coordinate of the  pixel
    :param y_coordinate: The y coordinate of the pixel
    :param center: center pixel value
    :return: The value of the pixel is being returned.
    """

    try:
        return int(image[x_coordinate][y_coordinate] >= center)
    except (IndexError, TypeError):
        return 0

def local_binary_value(image: np.ndarray, x_coordinate: int, y_coordinate: int) -> int:
    """
    It takes an image, an x and y coordinate, and returns the
    decimal value of the local binary patternof the pixel
    at that coordinate

    :param image: the image to be processed
    :param x_coordinate: x coordinate of the pixel
    :param y_coordinate: the y coordinate of the pixel
    :return: The decimal value of the binary value of the pixels
    around the center pixel.
    """
    center = image[x_coordinate][y_coordinate]
    powers = [1, 2, 4, 8, 16, 32, 64, 128]

    # skip get_neighbors_pixel if center is null
    if center is None:
        return 0

    # Starting from the top right, assigning value to pixels clockwise
    binary_values = [
        get_neighbors_pixel(image, x_coordinate - 1, y_coordinate + 1, center),
        get_neighbors_pixel(image, x_coordinate, y_coordinate + 1, center),
        get_neighbors_pixel(image, x_coordinate - 1, y_coordinate, center),
        get_neighbors_pixel(image, x_coordinate + 1, y_coordinate + 1, center),
        get_neighbors_pixel(image, x_coordinate + 1, y_coordinate, center),
        get_neighbors_pixel(image, x_coordinate + 1, y_coordinate - 1, center),
        get_neighbors_pixel(image, x_coordinate, y_coordinate - 1, center),
        get_neighbors_pixel(image, x_coordinate - 1, y_coordinate - 1, center),
    ]

    # Converting the binary value to decimal.
    return sum(
        binary_value * power for binary_value, power in zip(binary_values, powers)
    )

if __name__ == "__main__":
    # Reading the image and converting it to grayscale.
    image = cv2.imread(
        "digital_image_processing/image_data/lena.jpg", cv2.IMREAD_GRAYSCALE
    )

    # Create a numpy array as the same height and width of read image
    lbp_image = np.zeros((image.shape[0], image.shape[1]))

    # Iterating through the image and calculating the
    # local binary pattern value for each pixel.
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            lbp_image[i][j] = local_binary_value(image, i, j)

    cv2.imshow("local binary pattern", lbp_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


import math
import torch.nn as nn
import torch

class SPADE(nn.Module):
	def __init__(self, input_channels, kernel_size = 3, padding=1):
		super().__init__()

		self.conv_gamma = nn.Conv2d(input_channels, input_channels, kernel_size=(kernel_size, kernel_size), stride = 1, padding=padding)
		self.conv_beta = nn.Conv2d(input_channels, input_channels, kernel_size=(kernel_size, kernel_size), stride = 1, padding=padding)

		torch.nn.init.normal_(self.conv_gamma.weight, mean=0.0, std=0.01)
		torch.nn.init.normal_(self.conv_beta.weight, mean=0.0, std=0.01)

	def forward(self, x):

		gamma = self.conv_gamma(x)
		beta = self.conv_beta(x)

		return gamma, beta

class Reenactment_module(nn.Module):
	def __init__(self, input_channels, kernel_size = 3, padding=1):
		super(Reenactment_module, self).__init__()

		self.spade_pose = SPADE(input_channels, kernel_size = kernel_size, padding = padding)
		self.spade_app = SPADE(input_channels, kernel_size = kernel_size, padding = padding)

	def forward(self, f_p, f_app):
		"""
			Input:
				f_a: appearance feature maps
				f_p: pose feature maps
		"""

		gamma_p, beta_p = self.spade_pose(f_p)
		gamma_a, beta_a = self.spade_app(f_app)

		f_combined = torch.matmul(gamma_p, f_p) + torch.matmul(gamma_a, f_app) + beta_p + beta_a

		return f_combined


import os
import pathlib
import shutil
from lib import libgit

def loadList(silent=False):
    directory=".openpackage/packages"
    homedir = str(pathlib.Path.home())
    cloneMethod = "console"
    if silent:
        cloneMethod = "gitpython"
    else:
        cloneMethod = "gitpython"
    if not homedir[-1:] == "/":
        homedir = homedir + "/"
    clonedir = homedir + directory
    if not silent:
        print("--Home directory =", homedir)
        print("--Cloning packages")
        print("--Cloning into", clonedir)
    libgit.clone("https://github.com/openpackage/packages.git", clonedir, log = not silent, use_console_or_gitpython = cloneMethod)
    if not silent:
        print("--Downloaded packages")


'''
Locus.sh Assignment
Diffusion Limited Aggregation (DLA)

- Matrix M X M where M is an odd integer
- Image is toroidally bound

------>(For present configuration it takes approx 10 mins for 20,000 particles in 501 X 501 matrix)

-Nishchay Suri
155120029
Department of Physics
IIT Bombay
'''
from timeit import default_timer as timer
import numpy as np
import random as rnd
import matplotlib.pyplot as plt

class DLA():

	'''
	DLA Class : Diffusion Limited Aggregation

	INPUT:
	1st Parameter : Dimention M (odd) of  M X M Matrix

					This is the input number M for M X M pixels/cells for an image/matrix.

	2nd Parameter : Number of Particles

					This is the number of particles for building the structure.

	3rd Parameter : Stickiness from [0,1]

					Stickiness is a parameter depending on the interaction of particles amoung each other.

																					   ####################################################
	4th Parameter : Measure of distance of innter matrix from the structure (dist)  <- # Responsible for efficiency and quality of figure #
																					   ####################################################

					We take an inner matrix within the bigger M X M matrix. We introduce particles along it's border as it is closer to the structure.
					After every few iterations we calculate the farthest point of the structure and introduce this border at a (dist) distance away.

					This inner matrix is torroidally bound as there is a much higher chance of particles sticking if they return closer to the structure.
					Appropriately large the (dist) parameter better 'Random Walks' we get as the particles introduced along the border have more space
					to move freely.

	#################			Intro_New_Particle = Introduces new particle along the border of inner matrix (dim_temp X dim_temp)
	#				#								 The particle random walks inside this inner matrix and is torroidally bound inside it
	#				#								 to achieve greater efficiency.
	#				#								 The size of the inner matrix is increased as the structure grows.
	#	 #######	#
	#	 #	   #	#
	#	 #  1  #    #    		Intro_New_Particle_anywhere = Introduces new particle inside the inner matrix (for the sake of increasing efficiency)
	#	 #     #	#
	#	 #######	#
	#				#
	#				#
	#				#
	#################
					 M X M

	'''

	def __init__(self,dim,num,stickiness,dist):
		self.M = dim	            # Matrix is of the dimention : M X M (Assuming M is odd)
		self.num = num				# num is the number of Particles
		self.max_dimention = dim
		self.dist = dist
		# Centre of the Large M X M matrix
		self.row_centre = (dim-1)/2
		self.col_centre = (dim-1)/2

		self.stickiness = stickiness
		self.Matrix = self.Initialize_Matrix()
		self.stuck = False      	# Turns True when a particle gets stuck

		# Location of new Particle Introduced along the border
		self.row=0
		self.col=0

		# Max row and Max col
		self.max_row = (self.max_dimention-1)/2
		self.max_col = (self.max_dimention-1)/2

		# Array of Adjacent indices in the Matrix
		self.adj = np.array([[self.row-1,self.col-1], [self.row-1,self.col], [self.row-1,self.col+1],
							 [self.row,self.col-1]  ,						 [self.row,self.col+1],
							 [self.row+1,self.col-1], [self.row+1,self.col], [self.row+1,self.col+1]])

	def Initialize_Matrix(self): # Set the middle element of the Matrix as 1
		self.Matrix = np.zeros((self.M,self.M))
		self.Matrix[(self.M-1)/2,(self.M-1)/2] = 1
		return(self.Matrix)

	# Plots the pixels on image using Matrix
	def plot(self):
		plt.imshow(self.Matrix,cmap='gray')
		plt.show()

	def Intro_New_Particle(self,dim_temp): # Randomly introduces a new particle along the border of dim_temp around the bigger matrix
		flag = True
		self.M = dim_temp
		row_diff = self.row_centre - (dim_temp-1)/2
		col_diff = self.col_centre - (dim_temp-1)/2

		while flag:
			num = rnd.randint(0, 4*(self.M-1) -1) # There are ( 4 * (M-1) ) elements along the border. We select a random number from 0 to ( 4* (M -1) )
			quotient = int(num/(self.M-1))
			remainder = num%(self.M-1)

			if quotient == 0:
				self.row = row_diff + quotient
				self.col = col_diff + remainder
				element = self.Matrix[row_diff + self.row,col_diff + self.col]

			elif quotient == 1:
				self.row = row_diff + remainder
				self.col = col_diff + self.M-1
				element = self.Matrix[row_diff + self.row,col_diff + self.col]

			elif quotient == 2:
				self.row = row_diff + self.M-1
				self.col = col_diff + self.M-1-remainder
				element = self.Matrix[row_diff + self.row,col_diff + self.col]

			elif quotient == 3:
				self.row = row_diff + self.M-1-remainder
				self.col = col_diff + 0
				element = self.Matrix[row_diff + self.row,col_diff + self.col]

			if(element == 0):
				self.Matrix[self.row,self.col] = 1
				flag = False
				break

	# Randomly introduces a new particle anywhere in the matrix (To increase efficiency)
	def Intro_New_Particle_anywhere(self,dim):
		flag = True
		self.M = dim
		r_offset = self.row_centre - (dim-1)/2
		c_offset = self.col_centre - (dim-1)/2
		while(flag):
			rnd_row = rnd.randint(0,self.M-1)
			rnd_col = rnd.randint(0,self.M-1)
			if(self.Matrix[r_offset + rnd_row, c_offset + rnd_col] == 0):
				self.Matrix[r_offset+ rnd_row, c_offset + rnd_col] = 1
				self.row =  r_offset + rnd_row
				self.col =  c_offset + rnd_col
				flag = False

	# Gets adjacent elements from (row,col)  (Matrix is toroidally bound)
	def get_adjacent(self,row,col,dim_temp):
		self.adj = np.array([  [row-1,col-1], [row-1,col], [row-1,col+1],
							   [row,col-1]  ,			   [row,col+1],
							   [row+1,col-1], [row+1,col], [row+1,col+1]])

		#For wrapping
		for r in range(0,8):
			for c in range(0,2):
				if(self.adj[r,c] == self.row_centre - (dim_temp-1)/2 -1):
					self.adj[r,c] = self.row_centre + (dim_temp-1)/2

				elif(self.adj[r,c] == self.row_centre + (dim_temp-1)/2 +1):
					self.adj[r,c] = self.row_centre - (dim_temp-1)/2

		return(self.adj)

	# Takes a random step from the element (row,col) by checking all adjacent cells and updates (self.row,self.col)
	def random_step(self,row,col,dim_temp):
		flag = False							# Flag turns True when a neighbouring cell has element 1
		self.adj = self.get_adjacent(row,col,dim_temp)

		# If a neighbouring cell has element 1
		for elem in self.adj:
			if(self.Matrix[elem[0],elem[1]] == 1):
				flag = True
				break

		# If no neighbouring element is 1
		if(flag == False):
			self.Matrix[row,col] = 0
			num = rnd.randint(0,7)
			self.row , self.col = self.adj[num]
			self.Matrix[self.row,self.col] = 1

		# If a neighbouring element is 1 and particle does not stick probabilistically
		elif(flag == True and rnd.random() > self.stickiness):
			l=[]
			for eme in self.adj:
				if(self.Matrix[elem[0],elem[1]] == 0):
					l.append([elem[0],elem[1]])
			if len(l) != 0:
				num = rnd.randint(0,len(l))
				self.Matrix[row,col] = 0
				self.row , self.col = l[num]
				self.Matrix[self.row,self.col] = 1

		else:
			self.stuck = True
			self.Matrix[row,col] = 1
			if(  (row-self.row_centre)**2 + (col-self.col_centre)**2 > (self.max_row-self.row_centre)**2 + (self.max_col-self.col_centre)**2 ) :
				self.max_row , self.max_col = row , col

	# Run for N particles
	def Run_simulation(self):
		dim_temp = 51
		for i in range(0,self.num):
			if(i%100 == 0):
				if dim_temp < d.max_dimention:
					dim_temp = max(dim_temp, self.dist + 2* np.abs((max(self.max_row,self.max_col) - self.row_centre)))
				else:
					dim_temp = d.max_dimention

			self.Intro_New_Particle_anywhere(dim_temp)
			self.stuck = False
			while(self.stuck == False):
				self.random_step(self.row,self.col,dim_temp)

'''
FOR DLA
INPUT:
1st Parameter : Dimention M (odd) of  M X M Matrix
2nd Parameter : Number of Particles
3rd Parameter : Stickiness from [0,1]
4th Parameter : Measure of distance of innter matrix from the structure
'''

if __name__=='__main__':
	d = DLA(501,20000,1,41)

	start = timer()
	d.Run_simulation()
	end = timer()

	np.savetxt('matrix.txt',d.Matrix,fmt='%d')
	print("Time elapsed {}".format(end-start))
	d.plot()


import os
import xml.etree.ElementTree as ET

from django.core.files.base import ContentFile

from mock import patch, call, Mock

from ..management.commands.merge_coverage_files import (
    CLASSES_LIST, CLASSES_ROOT, LINES_LIST, LINES_ROOT, METHODS_LIST,
    METHODS_ROOT, Command, merge, merge_classes, merge_lines, merge_methods,
    merge_packages,
)
from .helper_methods import (
    get_class_tree, get_method_tree, get_package_tree, get_sources_tree
)
from cobertura_report_merger.management.commands.merge_coverage_files import merge_sources

def test_merging_lines_combines_hits_for_equivalent_lines():
    line1 = ET.Element('line', {'hits':'1', 'number':'1'})
    line2 = ET.Element('line', {'hits':'3', 'number':'1'})

    merged_line = merge_lines(line1, line2)

    assert '4' == merged_line.attrib['hits']

def test_merging_lines_takes_largest_condition_coverage_for_equivalent_lines():
    line1 = ET.Element('line', {'hits': '1', 'condition-coverage': '25% 1/4', 'number': '1'})
    line2 = ET.Element('line', {'hits': '3', 'condition-coverage': '50% 1/2', 'number': '1'})

    # The line merge method needs both lines to have children in order to work
    line1.append(ET.Element('line1child'))
    line2.append(ET.Element('line2child'))

    merged_line = merge_lines(line1, line2)

    assert '50% 1/2' == merged_line.attrib['condition-coverage']

def test_merging_lines_takes_children_of_line_with_largest_condition_coverage_for_equivalent_lines():
    line1 = ET.Element('line', {'hits': '1', 'condition-coverage': '25% 1/4', 'number': '1'})
    line2 = ET.Element('line', {'hits': '3', 'condition-coverage': '50% 1/2', 'number': '1'})

    line1.append(ET.Element('line1child'))
    line2.append(ET.Element('line2child'))

    merged_line = merge_lines(line1, line2)

    assert line2[0].tag == merged_line[0].tag

@patch('cobertura_report_merger.management.commands.merge_coverage_files.merge')
def test_merge_method_merges_lines_from_methods(merge_command):
    method1 = get_method_tree('method1')
    method2 = get_method_tree('method2')

    merge_methods(method1, method2)

    merge_command.assert_called_with(method1.find(LINES_ROOT), method1.findall(LINES_LIST), method2.findall(LINES_LIST), 'number', merge_lines)

@patch('cobertura_report_merger.management.commands.merge_coverage_files.merge')
def test_merge_classes_merges_methods_and_lines_from_classes(merge_command):
    class1 = get_class_tree('test/classname1.py', 'classname1')
    class2 = get_class_tree('test/classname2.py', 'classname2')

    merge_classes(class1, class2)

    merge_calls = [
        call(class1.find(LINES_ROOT), class1.findall(LINES_LIST), class2.findall(LINES_LIST), 'number', merge_lines),
        call(class1.find(METHODS_ROOT), class1.findall(METHODS_LIST), class2.findall(METHODS_LIST), 'name', merge_methods),
    ]

    merge_command.assert_has_calls(merge_calls)

@patch('cobertura_report_merger.management.commands.merge_coverage_files.merge')
def test_merge_packages_merges_packages(merge_command):
    package1 = get_package_tree()
    package2 = get_package_tree()

    merge_packages(package1, package2)

    merge_command.assert_called_with(
        package1.find(CLASSES_ROOT), package1.findall(CLASSES_LIST), package2.findall(CLASSES_LIST), ['filename', 'name'], merge_classes
    )

def test_merge_method_calls_provided_function_for_merging_identical_items():
    package1 = get_package_tree()
    package2 = get_package_tree()

    package_1_classes_list = package1.findall(CLASSES_LIST)
    package_2_classes_list = package2.findall(CLASSES_LIST)

    mock_merge_function = Mock()

    expected_calls = [
        call(package_1_classes_list[0], package_2_classes_list[0]),
        call(package_1_classes_list[1], package_2_classes_list[1])
    ]

    merge([], package_1_classes_list, package_2_classes_list, ['filename', 'name'], mock_merge_function)

    mock_merge_function.assert_has_calls(expected_calls)

def test_merge_appends_missing_items_to_bottom_of_file():
    package1 = get_package_tree()
    package2 = get_package_tree()

    extra_class = get_class_tree('tests/class3.py', 'class3')

    # The root for the package tree is element 0
    package2_root = package2[0]
    package2_root.append(extra_class)

    package_1_classes_list = package1.findall(CLASSES_LIST)
    package_2_classes_list = package2.findall(CLASSES_LIST)

    dummy_root_node = []
    merge(dummy_root_node, package_1_classes_list, package_2_classes_list, ['filename', 'name'], Mock())

    assert [extra_class] == dummy_root_node

def test_merge_xml_calls_filter_xml_twice():
    merge_coverage_files_command = Command()

    merge_coverage_files_command.filter_xml = Mock(return_value=[get_package_tree(), get_package_tree()])

    coverage_path = os.path.join(os.path.dirname(__file__), 'sample_coverage_reports')

    merge_coverage_files_command.path = coverage_path
    report1_path = os.path.join(coverage_path, 'cobertura-coverage.xml')
    report2_path = os.path.join(coverage_path, 'coverage.xml')

    merge_coverage_files_command.merge_xml(report1_path, report2_path, ContentFile(''))
    assert 2 == merge_coverage_files_command.filter_xml.call_count

@patch('cobertura_report_merger.management.commands.merge_coverage_files.merge')
def test_merge_xml_calls_merge_once(merge_command):
    merge_coverage_files_command = Command()

    coverage_path = os.path.join(os.path.dirname(__file__), 'sample_coverage_reports')

    merge_coverage_files_command.path = coverage_path
    report1_path = os.path.join(coverage_path, 'cobertura-coverage.xml')
    report2_path = os.path.join(coverage_path, 'coverage.xml')

    merge_coverage_files_command.merge_xml(report1_path, report2_path, ContentFile(''))
    assert 1 == merge_command.call_count

def test_merge_sources_merges_sources():
    sources_tree_1 = get_sources_tree('/test/directory/1/')
    sources_tree_2 = get_sources_tree('/test/directory/2/')

    expected_sources = list(sources_tree_1.findall('source') + sources_tree_2.findall('source'))

    merge_sources(sources_tree_1, sources_tree_2)

    assert expected_sources == list(sources_tree_1)

@patch('cobertura_report_merger.management.commands.merge_coverage_files.merge_sources')
def test_merge_xml_calls_merge_sources(merge_command):
    merge_coverage_files_command = Command()

    coverage_path = os.path.join(os.path.dirname(__file__), 'sample_coverage_reports')

    merge_coverage_files_command.path = coverage_path
    report1_path = os.path.join(coverage_path, 'cobertura-coverage.xml')
    report2_path = os.path.join(coverage_path, 'coverage.xml')

    merge_coverage_files_command.merge_xml(report1_path, report2_path, ContentFile(''))
    assert 1 == merge_command.call_count


import numpy as np
import pandas as pd
import seaborn as sns
from datetime import datetime
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.cluster import KMeans, DBSCAN
from sklearn.neighbors import NearestNeighbors
import networkx as nx
import os
import json

def str_agg(x):
    return ' '.join(x)

def prepare_dataset(df, target_event, event_filter=None, n_start_events=None):
    if event_filter is not None:
        df = df[~df.event_name.isin(event_filter)]
    df = df.sort_values('event_timestamp')
    train = df.groupby('user_pseudo_id').event_name.agg(str_agg)
    train = train.reset_index(None)
    train.event_name = train.event_name.apply(lambda x: x.split())
    train['target'] = train.event_name.apply(lambda x: x[-1] == target_event)
    train.event_name = train.event_name.apply(lambda x: x[:-1])
    if n_start_events:
        train.event_name = train.event_name.apply(lambda x: ' '.join(x[:n_start_events]))
    else:
        train.event_name = train.event_name.apply(lambda x: ' '.join(x))
        return train

def get_agg(df, agg_type):
    agg = df.groupby(['event_name', 'next_event'], as_index=False)
    agg = agg['time_to_next_event'].agg(agg_type.split('_')[1])
    agg.columns = ['event_name', 'next_event', agg_type]
    return agg

def get_shift(df):
    df = df.sort_values(['user_pseudo_id', 'event_timestamp']) \
        .reset_index(drop=True)

    shift = df.groupby('user_pseudo_id').shift(-1)
    df['next_event'] = shift.event_name
    df['time_to_next_event'] = (shift.event_timestamp - df.event_timestamp)
    df = df[df.next_event.notnull()]
    return df

def get_all_agg(df, agg_list):
    if 'next_event' not in df.columns:
        df = get_shift(df)

    df_result = get_agg(df, agg_list[0])
    for agg in agg_list[1:]:
        df_result[agg] = get_agg(df, agg)[agg]
    return df_result

def get_adjacency(df, adj_type):
    df = df.copy()
    event_set = set(df.event_name.unique())
    event_set.update(df.next_event.unique())
    event_num = len(event_set)
    event_to_id = dict(zip(event_set, np.arange(event_num)))
    df.event_name = df.event_name.apply(event_to_id.get)
    df.next_event = df.next_event.apply(event_to_id.get)
    if 'count' in adj_type:
        adj = np.zeros((event_num, event_num))
    else:
        adj = -np.ones((event_num, event_num))

    for i in df.iterrows():
        adj[int(i[1].event_name), int(i[1].next_event)] = i[1][adj_type]

    names = sorted(event_to_id, key=event_to_id.get)
    adj = pd.DataFrame(adj, columns=names, index=names)
    adj = adj.round(2)
    return adj

def get_accums(agg, name, max_rank):
    """
    Creates Accumulator Variable
    :param agg: Counts of events by step
    :param name: Name of Accumulator
    :param max_rank: Number of steps in pivot
    :return: Accumulator Variable
    """
    lost = pd.DataFrame([[0, 0]], columns=['event_rank', 'freq']) \
        .append(agg.loc[agg.event_name == name, ['event_rank', 'freq']])

    lost['event_rank'] += 1
    lost = lost.sort_values('event_rank')

    missed_rows = []
    k = 0
    for i, row in enumerate(lost.itertuples()):
        for j in range(row.event_rank - (i + 1) - k):
            missed_rows.append([i + k + 1, 0])
            k += 1
    lost = lost.append(pd.DataFrame(missed_rows, columns=['event_rank', 'freq']))
    lost = lost.sort_values('event_rank')
    lost.freq = lost.freq.cumsum()
    while lost['event_rank'].max() < max_rank:
        lost = lost.append(
            pd.DataFrame([[lost['event_rank'].iloc[-1] + 1, lost.freq.iloc[-1]]], columns=['event_rank', 'freq']),
            sort=True
        )
    lost['event_name'] = 'Accumulated ' + name.capitalize()
    return lost

def check_folder(settings):
    if settings.get('export_folder'):
        return settings
    else:
        if not os.path.isdir('./experiments/'):
            os.mkdir('./experiments/')
        settings['export_folder'] = './experiments/{}'.format(datetime.now())
        os.mkdir(settings['export_folder'])
        with open(os.path.join(settings['export_folder'], 'settings_{}.json'.format(datetime.now())), 'w') as f:
            json.dump(settings, f)
    return settings

def get_desc_table(df, settings, target_event_list=list(['lost', 'passed']), max_steps=None, plot=True, plot_name=None):
    """
    Builds distribution of events over steps
    :param df: Clickstream
    :param plot: if True: plot heatmap
    :return: Pivot table with distribution of events over steps
    """
    # create ranks and count
    df = df.sort_values(['user_pseudo_id', 'event_timestamp']).copy()
    df['event_rank'] = 1
    df['event_rank'] = df.groupby('user_pseudo_id')['event_rank'].cumsum()
    if max_steps:
        df = df.loc[df['event_rank'] <= max_steps, :]

    agg = df.groupby(['event_rank', 'event_name'], as_index=False)['user_pseudo_id'].count()
    agg.columns = ['event_rank', 'event_name', 'freq']
    tot_cnt = agg[agg['event_rank'] == 1].freq.sum()

    # add accumulated rows
    max_rank = agg['event_rank'].max() + 1
    for i in target_event_list:
        agg = agg.append(get_accums(agg, i, max_rank), sort=True)

    # build pivot
    agg['freq'] = agg['freq'] / tot_cnt
    piv = agg.pivot(index='event_name', columns='event_rank', values='freq').fillna(0)
    piv.columns.name = None
    piv.index.name = None
    piv = piv.round(2)

    if max_steps:
        piv = piv.T[piv.columns <= max_steps].T

    if plot:
        # create folder for experiment if doesn't exists
        settings = check_folder(settings)
        export_folder = settings['export_folder']
        sns.mpl.pyplot.figure(figsize=(20, 10))
        heatmap = sns.heatmap(piv, annot=True, cmap="YlGnBu")
        if plot_name:
            filename = os.path.join(export_folder, 'desc_table_{}.png'.format(plot_name))
        else:
            filename = os.path.join(export_folder, 'desc_table_{}.png'.format(datetime.now()))
        heatmap.get_figure().savefig(filename)

    return piv

def get_diff(df_old, df_new, settings, precalc=False, plot=True, plot_name=None):
    """
    Gets difference between two groups
    :param df_old: Raw clickstream or calculated desc table of last version
    :param df_new:  Raw clickstream or calculated desc table of new version
    :param precalc: If True: use precalculated desc tables
    :param plot: If False: plot heatmap
    :return: Table of differences between two versions
    """
    if precalc:
        desc_new = df_new
        desc_old = df_old
    else:
        desc_old = get_desc_table(df_old, False)
        desc_new = get_desc_table(df_new, False)

    old_id = set(desc_old.index)
    new_id = set(desc_new.index)

    if old_id != new_id:
        for idx in new_id - old_id:
            row = pd.Series([0] * desc_old.shape[1], name=idx)
            row.index += 1
            desc_old = desc_old.append(row, sort=True)
        for idx in old_id - new_id:
            row = pd.Series([0] * desc_new.shape[1], name=idx)
            row.index += 1
            desc_new = desc_new.append(row, sort=True)

    max_old = desc_old.shape[1]
    max_new = desc_new.shape[1]
    if max_old < max_new:
        for i in range(max_old, max_new + 1):
            desc_old[i] = desc_old[i - 1]
    elif max_old > max_new:
        for i in range(max_new, max_old + 1):
            desc_new[i] = desc_new[i - 1]

    diff = desc_new - desc_old
    diff = diff.sort_index(axis=1)
    if plot:
        settings = check_folder(settings)
        export_folder = settings['export_folder']

        sns.mpl.pyplot.figure(figsize=(20, 10))
        heatmap = sns.heatmap(diff, annot=True, cmap="YlGnBu")
        if plot_name:
            filename = os.path.join(export_folder, 'desc_table_{}.png'.format(plot_name))
        else:
            filename = os.path.join(export_folder, 'desc_table_{}.png'.format(datetime.now()))
        heatmap.get_figure().savefig(filename)
    return diff

def plot_graph_python(df_agg, agg_type, settings, plot_name=None):
    edges = df_agg.loc[:, ['event_name', 'next_event', agg_type]]
    G = nx.DiGraph()
    G.add_weighted_edges_from(edges.values)
    width = [G.get_edge_data(i, j)['weight'] for i, j in G.edges()]
    width = np.array(width)
    width = (width - width.min()) / (np.mean(width) - width.min())
    width *= 2
    width = np.where(width > 20, 20, width)
    width = np.where(width < 2, 2, width)

    pos = nx.random_layout(G, seed=2)
    f = sns.mpl.pyplot.figure(figsize=(20, 10))
    nx.draw_networkx_edges(G, pos, edge_color='b', alpha=0.2, width=width);
    nx.draw_networkx_nodes(G, pos, node_color='b', alpha=0.3)
    pos = {k:[pos[k][0], pos[k][1] + 0.03] for k in pos.keys()}
    nx.draw_networkx_labels(G, pos, node_color='b', font_size=16);
    sns.mpl.pyplot.axis('off')

    settings = check_folder(settings)
    export_folder = settings['export_folder']
    if plot_name:
        filename = os.path.join(export_folder, 'graphvis_{}.png'.format(plot_name))
    else:
        filename = os.path.join(export_folder, 'graphvis_{}.png'.format(datetime.now()))
    f.savefig(filename)

def plot_frequency_map(df, settings, target_events=['lost', 'passed'], plot_name=None):
    users = df.user_pseudo_id[df.event_name.isin(target_events)].unique()
    df = df[df.user_pseudo_id.isin(users)]
    data = prepare_dataset(df, '')
    cv = CountVectorizer()
    x = cv.fit_transform(data.event_name.values).todense()
    cols = cv.inverse_transform(np.ones(df.event_name.nunique() - len(target_events)))[0]
    x = pd.DataFrame(x, columns=cols, index=data.user_pseudo_id)
    nodes_hist = df.groupby('event_name',
                            as_index=False).event_timestamp.count().sort_values('event_timestamp',
                                                                                ascending=False)
    nodes_hist.event_name = nodes_hist.event_name.apply(lambda x: x.lower())
    sorted_cols = nodes_hist.event_name[~nodes_hist.event_name.isin(target_events)].values
    x = x.loc[:, sorted_cols]
    sns.mpl.pyplot.figure(figsize=[8, 5])
    bar = sns.barplot(nodes_hist.event_name.values, nodes_hist.event_timestamp.values, palette='YlGnBu')
    bar.set_xticklabels(bar.get_xticklabels(), rotation=90);

    settings = check_folder(settings)
    export_folder = settings['export_folder']
    if plot_name:
        barname = os.path.join(export_folder, 'bar_{}.png'.format(plot_name))
        heatname = os.path.join(export_folder, 'countmap_{}.png'.format(plot_name))
    else:
        barname = os.path.join(export_folder, 'bar_{}.png'.format(datetime.now()))
        heatname = os.path.join(export_folder, 'countmap_{}.png'.format(datetime.now()))
    bar.get_figure().savefig(barname)
    sns.mpl.pyplot.figure(figsize=[10, 15])
    heatmap = sns.heatmap(x.values, cmap="YlGnBu")
    heatmap.get_figure().savefig(heatname)
    return x

def plot_clusters(data, countmap, target_events=['lost', 'passed'], n_clusters=None, plot_cnt=2, width=10, height=5):
    if n_clusters:
        clusterer = KMeans(n_clusters=n_clusters)
    else:
        nn = NearestNeighbors(metric='cosine')
        nn.fit(countmap.values)
        dists = nn.kneighbors(countmap.values, 2)[0][:, 1]
        eps = np.percentile(dists, 99)
        clusterer = DBSCAN(eps=eps, metric='cosine')
    clusters = clusterer.fit_predict(countmap)
    cl = pd.DataFrame(clusters, columns=['cluster'])
    cl['c'] = 1
    main_classes = cl.groupby('cluster',
                              as_index=False).count().sort_values('c',
                                                                  ascending=False).cluster.iloc[:plot_cnt].values
    groups = []
    for i in main_classes:
        groups.append(countmap.index[clusters == i].values)
    sizes = []
    for group in groups:
        tmp = data[data.user_pseudo_id.isin(group)]
        sz = []
        for event in target_events:
            sz.append(tmp[tmp.event_name == event].user_pseudo_id.nunique())
        sizes.append(sz)

    fig, ax = sns.mpl.pyplot.subplots(1 if plot_cnt <= 2 else (plot_cnt // 2 + 1), 2)
    fig.set_size_inches(width, height)
    for i, j in enumerate(sizes):
        if plot_cnt <= 2:
            ax[i].pie(j, labels=['lost', 'passed'], autopct='%1.1f%%')
            ax[i].set_title('Class {}'.format(i))
        else:
            ax[i // 2][i % 2].pie(j, labels=['lost', 'passed'], autopct='%1.1f%%')
            ax[i // 2][i % 2].set_title('Class {}'.format(i))

def filter_welcome(df):
    passed = df[df.event_name.apply(lambda x: str(x).split('_')[0] in [u'newFlight', u'feed', u'tabbar', u'myFlights'])]
    myfligts = df[(df.event_name == 'screen_view') & (df.event_params_value_string_value == 'myFlights')]
    myfligts = myfligts.append(passed, ignore_index=False, sort=False)
    myfligts = myfligts.sort_values(['user_pseudo_id', 'event_timestamp'])
    passed = myfligts.groupby('user_pseudo_id').head(1)
    passed.event_name = 'passed'

    lost = df[~df.user_pseudo_id.isin(passed.user_pseudo_id)].groupby('user_pseudo_id').tail(1)
    lost.event_name = 'lost'
    lost.event_timestamp -= 1
    df = df.append(lost.append(passed, sort=False), sort=False)
    return prepare_prunned(df)

def prepare_prunned(df):
    welcome2event = {
        '1': "wel",
        '2': "push",
        '3': "sub",
        '4': "wallet",
        '5': "import",
        '6': "cal"
    }
    rename_dict = {
        'inactive_users': 'inactive',
        'new_users': 'newUsers',
        'lost': 'lostUser'
    }
    wel = df[df['event_name'] == 'welcome_see_screen'].copy()
    wel.event_name = wel.event_params_value_string_value.apply(welcome2event.get)
    wel = wel[wel.event_name.notnull()]
    wel = wel.append(df[df.event_name.isin(['lost', 'passed'])], ignore_index=True, sort=False)
    wel = wel.sort_values(['user_pseudo_id', 'event_timestamp']).reset_index(drop=True)
    first = wel.drop_duplicates('user_pseudo_id', keep='first')
    users = first.user_pseudo_id[first.event_name.isin(['wel', 'passed'])].values
    first = first[first.user_pseudo_id.isin(users)]
    wel = wel[wel.user_pseudo_id.isin(users)]
    first.event_name = 'new_users'
    first.event_timestamp -= 1
    wel = wel.append(first, ignore_index=True, sort=False)
    for i in set(wel.event_name.unique()):
        if i not in rename_dict:
            rename_dict.update({i: i})
    wel.event_name = wel.event_name.apply(rename_dict.get)
    return wel


import os
from typing import Tuple

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

from HW1.knn import KNN
from HW1.nb import NB
from HW1.util import mpl_default_setting, split_nan, split_xy

def impute_datasets(train_path: str, test_path: str,
                    train_imputed_path: str, test_imputed_path: str,
                    k: int = 10):
    # Load datasets
    dset_train = pd.read_csv(train_path)
    dset_test = pd.read_csv(test_path)
    # Concatenate training and test set
    dset = pd.concat([dset_train, dset_test], ignore_index=True)
    dset_train_idx = dset_train.index
    dset_test_idx = dset.index.drop(dset_train_idx)
    # Split dataset with and without missing values
    dset_clean, dset_nan = split_nan(dset)
    dset_clean_X, dset_clean_y = dset_clean.drop(columns=target), dset_clean[target]
    dset_nan_X, dset_nan_y = dset_nan.drop(columns=target), dset_nan[target]
    # Train KNN
    knn = KNN(k)
    knn.train(X=dset_clean_X, y=dset_clean_y)
    # Impute missing values
    dset_nan_X_imputed = knn.impute(X=dset_nan_X)
    # Concatenate imputed features with labels
    dset_nan_imputed = pd.concat([dset_nan_X_imputed, dset_nan_y], axis=1)
    dset_nan_imputed.set_index(dset_nan.index)
    # Concatenate clean and imputed datasets
    dset_imputed = pd.concat([dset_clean, dset_nan_imputed])
    # Split imputed dataset into training and test sets
    dset_train_imputed = dset_imputed.loc[dset_train_idx]
    dset_test_imputed = dset_imputed.loc[dset_test_idx]
    # Save imputed datasets to files
    dset_train_imputed.to_csv(train_imputed_path, index=False)
    dset_test_imputed.to_csv(test_imputed_path, index=False)

# 5.1
def report_parameters(X: pd.DataFrame, y: pd.Series):
    nb = NB()
    nb.train(X, y)

    print('py'.center(50, '='))
    print(nb.py)

    print('px'.center(50, '='))
    for y_val, px in nb.px.items():
        print(str(y_val).center(50, '='))

        print('education-num'.center(50, '-'))
        print('mean', px['numerical'].loc['mean', 'education-num'])
        print('var', px['numerical'].loc['std', 'education-num'] ** 2)

        print('marital-status'.center(50, '-'))
        print(px['categorical']['marital-status'])

        print('race'.center(50, '-'))
        print(px['categorical']['race'])

        print('capital-gain'.center(50, '-'))
        print('mean', px['numerical'].loc['mean', 'capital-gain'])
        print('var', px['numerical'].loc['std', 'capital-gain'] ** 2)

    print('Log-posterior'.center(50, '-'))
    y_pred, LL = nb.predict(X=X_test_imputed[:10], return_LL=True)
    print(LL)

# 5.2.1 ~ 5.2.4
def evaluation(X_train: pd.DataFrame, y_train: pd.Series,
               X_train_imputed: pd.DataFrame, y_train_imputed: pd.Series) -> Tuple[NB, NB]:
    nb = NB()
    nb_imputed = NB()
    nb.train(X_train, y_train)
    nb_imputed.train(X_train_imputed, y_train_imputed)
    print(np.mean(y_train == nb.predict(X_train)))
    print(np.mean(y_train == nb_imputed.predict(X_train)))
    print(np.mean(y_test == nb.predict(X_test)))
    print(np.mean(y_test == nb_imputed.predict(X_test)))
    return nb, nb_imputed

# 5.2.5
def generate_learning_curves(dset_train: pd.DataFrame,
                             dset_test: pd.DataFrame,
                             dset_train_imputed: pd.DataFrame,
                             dset_test_imputed: pd.DataFrame,
                             target: str,
                             res_path: str, res_imputed_path: str) -> Tuple[pd.DataFrame, pd.DataFrame]:
    res = {'n_data': [], 'train_acc': [], 'test_acc': []}
    res_imputed = {'n_data': [], 'train_acc': [], 'test_acc': []}

    for i in range(5, 14, 1):
        m = int(2 ** i)
        # Data without imputation
        train = dset_train[:m].dropna()
        X_train, y_train = split_xy(train, target)
        # Data with imputation
        train_imputed = dset_train_imputed[:m].dropna()
        X_train_imputed, y_train_imputed = split_xy(train_imputed, target)

        nb = NB()
        nb_imputed = NB()
        nb.train(X_train, y_train)
        nb_imputed.train(X_train_imputed, y_train_imputed)

        res['n_data'].append(len(train))
        res['train_acc'].append(np.mean(y_train == nb.predict(X_train)))
        res['test_acc'].append(np.mean(y_test == nb.predict(X_test)))
        res_imputed['n_data'].append(len(train_imputed))
        res_imputed['train_acc'].append(np.mean(y_train_imputed == nb.predict(X_train_imputed)))
        res_imputed['test_acc'].append(np.mean(y_test_imputed == nb.predict(X_test_imputed)))

    res = pd.DataFrame(res)
    res_imputed = pd.DataFrame(res_imputed)
    res.to_csv(res_path, index=False)
    res_imputed.to_csv(res_imputed_path, index=False)

    return res, res_imputed

# 5.2.5
def plot_learning_curves(res_path: str, res_imputed_path: str):
    res = pd.read_csv(res_path)
    res_imputed = pd.read_csv(res_imputed_path)

    mpl_default_setting()

    plt.title('Accuracy vs data (without imputation)')
    plt.xlabel(r"# data ($m - m'$)")
    plt.ylabel("Accuracy")
    plt.xlim(0, 8500)
    plt.plot(res['n_data'], res['train_acc'], '-r', label='train')
    plt.plot(res['n_data'], res['test_acc'], '-b', label='test')
    plt.legend(loc='upper right')
    plt.show()

    plt.title('Accuracy vs data (with imputation)')
    plt.xlabel(r"# data ($m$)")
    plt.ylabel("Accuracy")
    plt.xlim(0, 8500)
    plt.plot(res_imputed['n_data'], res['train_acc'], '-r', label='train')
    plt.plot(res_imputed['n_data'], res['test_acc'], '-b', label='test')
    plt.legend(loc='upper right')
    plt.show()

if __name__ == '__main__':
    dset_dirpath = './data/'
    train_filename = 'census.csv'
    test_filename = 'adult.test.csv'
    train_imputed_filename = 'census_imputed.csv'
    test_imputed_filename = 'adult.test_imputed.csv'
    res_filename = 'res.csv'
    res_imputed_filename = 'res_imputed.csv'

    target = 'income'

    # Paths
    train_path = os.path.join(dset_dirpath, train_filename)
    test_path = os.path.join(dset_dirpath, test_filename)
    train_imputed_path = os.path.join(dset_dirpath, train_imputed_filename)
    test_imputed_path = os.path.join(dset_dirpath, test_imputed_filename)
    res_path = os.path.join(dset_dirpath, res_filename)
    res_imputed_path = os.path.join(dset_dirpath, res_imputed_filename)

    # Train a KNN to impute the missing values in the datasets
    # and save the imputed data to files
    impute_datasets(train_path, test_path,
                    train_imputed_path, test_imputed_path,
                    k=10)

    # Load datasets
    dset_train = pd.read_csv(train_path)
    dset_test = pd.read_csv(test_path)
    dset_train_imputed = pd.read_csv(train_imputed_path)
    dset_test_imputed = pd.read_csv(test_imputed_path)
    # Split datasets into features and labels
    X_train, y_train = split_xy(dset_train, target)
    X_test, y_test = split_xy(dset_test, target)
    X_train_imputed, y_train_imputed = split_xy(dset_train_imputed, target)
    X_test_imputed, y_test_imputed = split_xy(dset_test_imputed, target)

    # 5.1
    report_parameters(X_train_imputed, y_train_imputed)

    # 5.2.1 ~ 5.2.4
    evaluation(X_train, y_train, X_train_imputed, y_train_imputed)

    # 5.2.5
    generate_learning_curves(dset_train, dset_test,
                             dset_train_imputed, dset_test_imputed,
                             target, res_path, res_imputed_path)
    plot_learning_curves(res_path, res_imputed_path)


from math import sqrt, gcd; from itertools import count, islice
def snt(n):
    return n > 1 and all(n%i for i in islice(count(2), int(sqrt(n)-1)))
n = int(input())
for i in range(n):
    s = input().split(' ')
    a = str(gcd(int(s[0]), int(s[1])))
    t = 0
    for i in a:
        t += int(i)
    if(snt(t)):
        print("YES")
    else:
        print("NO")


from functools import lru_cache

n = int(input())
@lru_cache(maxsize=None)
def rec(s):
    if s == 1: return 1
    if s == 2: return 2
    if s == 3: return 4
    return (rec(s-3) + rec(s-2) + rec(s-1))%1000000007

print(rec(n))


from ctypes import c_uint8

import pytest

from chip8.cpu import (
    Registers,
    CPU,
)
from chip8.memory import Memory
from chip8.interpreter import Interpreter
from chip8.backends.pygame import PyGameBackend

@pytest.fixture
def memory(request):
    memory = Memory()

    # Optionally run this fixture with a rom to load into memory.
    # https://docs.pytest.org/en/6.2.x/parametrize.html
    try:
        rom = request.param
    except AttributeError:
        rom = []

    for instruction, location in zip(rom, range(0x200, 0xFFF)):
        memory[location] = instruction

    return memory

@pytest.fixture
def registers(request):
    registers = Registers()
    try:
        for key, value in request.param:
            registers[key] = c_uint8(value)
    except TypeError:
        raise pytest.UsageError("Make sure fixture data for registers is iterable.")
    except AttributeError:
        # No params on request object, skip
        ...
    return registers

@pytest.fixture
def cpu(memory, display, registers):
    return CPU(memory, display, registers)

@pytest.fixture
def display():
    class Display:
        def __init__(self, *args, **kwargs):
            pass

        def draw_sprite(self, *args, **kwargs):
            self.draw_sprite_called = True
            # Always return False to report no collision
            return False

        draw_sprite_called = False

        def clear(self, *args, **kwargs):
            self.clear_called = True

        clear_called = False

    return Display(width=64, height=45, scale=4)

@pytest.fixture
def interpreter(cpu):
    return Interpreter(PyGameBackend(), cpu)


#Python file for working functions.

#Necessary modules
from scipy import spatial
from scipy import ndimage
from scipy import stats
from math import *
import numpy as np
import copy
import os
import cv2
import operator
import numpy.ma as ma
import time
import pickle as pkl

##Classes
class fly_data(object):
    """fly_data gathers the position and orientation of a given fly all along the video."""
    def __init__(self, data_dict, identity):
        self.length = data_dict['orientations'][0]
        self.positions = data_dict['trajectories'][:,identity] #The position of the fly for each frame in pixels of the video.
        self.identity = identity
        self.directions = data_dict['directions'][:,identity]
        self.orientations = data_dict['orientations'][:,identity]

    def __str__(self):
        print(self, 'is a fly_data object')
        print('Number of frames : ', self.length)
        print('Identity in the video : ',self.identity)

    def ori_correc(self, overwrite=False): #Outputs corrected orientations based on inputted directions.
        #Should be given two arrays of numbers

        correc = convert180to360(self.orientations) #Put orientations in a 360 degrees format
        flipped = flip(correc) #Flips orientations
        minus = flip(correc, -90)
        plus = flip(correc, 90)

        #Calculate correlation for the 4 possibilities
        correl = dict()
        correl['flipped'] = ma.corrcoef(ma.masked_invalid(flipped), ma.masked_invalid(self.directions))[1,0]
        correl['minus'] = ma.corrcoef(ma.masked_invalid(minus), ma.masked_invalid(self.directions))[1,0]
        correl['plus'] = ma.corrcoef(ma.masked_invalid(plus), ma.masked_invalid(self.directions))[1,0]
        correl['correc'] = ma.corrcoef(ma.masked_invalid(correc), ma.masked_invalid(self.directions))[1,0]

        #get optimum
        opti = max(correl.items(), key=operator.itemgetter(1))[0]

        #Outputs better corrected orientations
        if opti == 'flipped':
            print("Orientations have been corrected and flipped 180 degrees.")
            print("Correlation is ", correl['flipped'])
            if overwrite == True:
                self.orientations = flipped
            else:
                return flipped

        elif opti == 'minus':
            print("orientations have been corrected and flipped -90 degrees")
            print("Correlation is ", correl['minus'])
            if overwrite == True:
                self.orientations = minus
            else:
                return minus

        elif opti == 'plus':
            print("orientations have been corrected and flipped +90 degrees")
            print("Correlation is ", correl['plus'])
            if overwrite == True:
                self.orientations = plus
            else:
                return plus

        elif opti == 'correc':
            print("orientations have been corrected only")
            print("Correlation is ", correl['correc'])
            if overwrite == True:
                self.orientations = correc
            else:
                return correc

class relative_fly(object): #Should be given two fly objects, and calculate relative distance, speed, angle from focus to other fly.

    def __init__(self, focusfly, newfly):
        """Should be given two fly_data objects. Produces relative position and angle of the second fly to the first."""
        self.positions = newfly.positions - focusfly.positions
        xs = self.positions[:,0]
        ys = self.positions[:,1]

        self.dist, absol_angle = angleFromPoints(xs,ys)
        angle = absol_angle - focusfly.orientations
        angle[angle < 0] += 360
        self.angle = angle
        self.speed = self.dist[1:] - self.dist[:-1]
        self.speed = np.insert(self.speed, 0,0)

class relative_set(object): #Given a list of fly_data objects, calculates and outputs the relative_fly of every fly to the others.
    def __init__(self, flystack):
        pos_stack = np.empty([1,2])
        dist_stack = np.empty([])
        angle_stack = np.empty([])

        for focus in flystack:
            for fly in flystack:
                if focus != fly:
                    rel = relative_fly(focus, fly)
                    angle = np.radians(rel.angle)
                    ys = rel.dist*np.sin(angle)
                    xs = rel.dist*np.cos(angle)
                    pos = np.column_stack([xs,ys])
                    pos_stack = np.vstack([pos_stack, pos])
                    dist_stack = np.hstack([dist_stack, rel.dist])
                    angle_stack = np.hstack([angle_stack, rel.angle])
        pos_stack = pos_stack[1:,]
        self.positions = pos_stack
        self.dist = dist_stack
        self.orientations = angle_stack

#Functions

def get_ori(Dir, video, traj, thresh = 50, noise_thresh=0.5): #Gets raw orientations and directions from numpy array of positions and video file.
    #Both .npy file and video file should be in the same Dir folder.

    #Fantastic files and where to find them
    path_to_vid = r'{}{}{}'.format(Dir, os.sep, video)
    path_to_traj = r'{}{}{}'.format(Dir, os.sep, traj)
    cap = cv2.VideoCapture(path_to_vid)

    trajectories_dict = np.load(path_to_traj, encoding='latin1').item() #Trajectorie data from idtrackerai.
    trajectories = trajectories_dict['trajectories']

    #Some information that will be useful later
    nberflies = len(trajectories_dict['trajectories'][0]) #Get number of individuals from trajectories
    framerate = cap.get(cv2.CAP_PROP_FPS)

    i = 0 #Index for taking the right trajectories.

    while(cap.isOpened()):
    #for _ in range(500): #To be used to make it run faster if needed

        #Take the next image from the video and turn it grey
        ret, img = cap.read()
        if img is not None:
            img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        else: #If no more images, break the loop
            cap.release()
            continue

    #Set the threshold and get the binary image
        ret, diff_img = cv2.threshold(img,thresh,255,cv2.THRESH_BINARY)

                #Get a bunch of contours from the binary
        contours,hierarchy = cv2.findContours(diff_img,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

                #For every contours, get its center, and put contour in a dict with center as key
        centers = list()
        right_contours = list()

        for c in contours:
            if len(c)>15 and len(c)<100: #contour should be in a reasonable size range
                M = cv2.moments(c)
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                centers.append([cX, cY]) #Add center to the list
                right_contours.append(c) #Add corresponding contour to a similar list

                #Get the trajectory data from idtrackerai
        positions = trajectories[i]

        ori_frame = list() #A list of orientations for the current frame

        for fly in positions:
            if (np.isfinite(fly[0])):
                ind = spatial.KDTree(centers).query(fly)[1]
                ellipse = cv2.fitEllipse(right_contours[ind]) #Fitting the ellipse
                orientation = np.float(ellipse[2])
                ori_frame.append(orientation)

            else:
                ori_frame.append(np.nan)
        ori_frame = np.array(ori_frame)
        try:
            ori_stack
        except NameError:
            ori_stack = ori_frame
        else:
            ori_stack = np.vstack([ori_stack, ori_frame])

    #Get directions part :
        shape_pos = np.arange(nberflies)
        if i == 0: #If first iteration, everything is zero
            direc_stack = np.zeros_like(shape_pos)
            speed_stack = np.zeros_like(shape_pos)
            dist_stack = np.zeros_like(shape_pos)
            direc = np.zeros_like(shape_pos)
        elif isinstance(i, int): #If not the first iteration
            dist, direc = get_angle(trajectories, i, direc, noise_thresh)
            speed = dist*framerate

            dist_stack = np.vstack([dist_stack, dist]) # distance traveled in pixels
            speed_stack = np.vstack([speed_stack, speed]) #Speed in pixels per second
            direc_stack = np.vstack([direc_stack, direc]) #direction in degrees

        i+=1 #An index so that we take the right trajectories for every frame.

    data = dict() #Dictionary in which we will put the three stacks of data.
    data['trajectories'] = trajectories
    data['speeds'] = speed_stack
    data['directions'] = direc_stack
    data['orientations'] = np.array(ori_stack)
    data['mov'] = dist_stack
    data['contours'] = right_contours

    flystack = list()
    for fly in range(nberflies):

        flystack.append(fly_data(data, fly))

    return flystack

def get_angle(trajectories, frameID, previous_angles, noise_thresh=0.5):
                #Outputs direction, speed and distance for a given frame.

    positions = trajectories[frameID]

    oldpositions = trajectories[frameID-1] #Get previous values
    delta = positions - oldpositions #Compute difference between two iterations
    xs = delta[:,0]
    ys = delta[:,1]
    #Calculate angle and distance
    dist, angle = angleFromPoints(xs, ys)
    for i in range(len(delta)):
        x = xs[i]
        y = ys[i]
        #Remove noise
        if (x > -noise_thresh) & (x < noise_thresh) &\
        (y > -noise_thresh) & (y < noise_thresh):
            dist[i] = 0
            angle[i] = previous_angles[i]

    return(dist, angle)

def convert180to360(ori): #Should be given an array of numbers

    ori_conv = copy.deepcopy(ori)
    diffs = ori_conv[1:] - ori_conv[0:-1]
    bool = True
    for i in range(len(diffs)):
        if abs(diffs[i]) > 90 and bool == True:
            ori_conv[i+1:] += 180
            bool = False
        elif abs(diffs[i]) > 90 and bool == False:
            ori_conv[i+1:] -= 180
            bool = True
    return(ori_conv)

def flip(ori, angle=180): #Should be given an array of numbers and a single value

    ori_flip = copy.deepcopy(ori)
    ori_flip += angle
    for i in range(len(ori_flip)):
        if ori_flip[i] >= 360:
            ori_flip[i:] -= 360
        elif ori_flip[i] <= 0:
            ori_flip[i:] +=360
    return(ori_flip)

def direc_stats(data, chunkrange, fly):     #Get stats about a chunk
                                            #Not really useful atm

    tronc_direc = data['directions'][chunkrange,fly]
    ori = data['orientations'][chunkrange,fly]
    print("Stats for fly {} from frame {} to {}".format(fly, chunkrange[0], chunkrange[-1]))
    print("Variance of the direction over the chunk is :", np.var(tronc_direc))
    print("Cross correlations : ",np.correlate(tronc_direc, ori))
    print("Correlation coef : ",np.corrcoef(np.vstack([tronc_direc, ori]))[1,0], '\n')
    plt.figure(figsize=(20,5))
    plt.ylim([-10,370])
    plt.plot(ori)
    plt.plot(tronc_direc)

def angleFromPoints(x,y): #Gets two arrays of x/y distances between two points
                          #Can do case by case or batch treatment.

    dist = np.sqrt((x*x)+(y*y)) #Distance between each couple of points
    angle = np.degrees(np.arctan(np.absolute(y)/np.absolute(x)))
    #Angle correction based on negativity of coordinates.
    #This ensure angle range on 0:360 and correspond to trigonometric circle. 0 is looking on the right.
    for i in range(len(angle)):
        if   x[i] <0 and y[i] <0:
            angle[i] += 180
        elif x[i] <0:
            angle[i] = 180 - angle[i]
        elif y[i] <0:
            angle[i] =360 - angle[i]
    return dist, angle

#Handling the data in a "packaged" way

def save_ori_pickle(session_name):
    Dir = "/home/maubry/python/idtrackerai/raw"
    st = time.time()
    video = session_name+".avi"
    traj = session_name+".npy"
    pkl_name = session_name+"_ori_data.pkl"

    flystack = get_ori(Dir, video, traj)
    f = open(pkl_name, "wb")
    pkl.dump(flystack, f)
    laps = time.time() - st
    print('time elapsed : {}min and {}sec'.format(laps//60, int(laps%60)))

def get_ori_pickle(session_name):
    pkl_name = session_name+"_ori_data.pkl"
    f = open(pkl_name, "rb")
    random_stack = pkl.load(f)
    return random_stack


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import unittest

class NewVisitorTest (unittest.TestCase):

    def setUp(self):
        self.browser = webdriver.Firefox()

    def tearDown(self):
        self.browser.quit()

    def test_can_start_a_list_and_retrieve_it_later(self):
        # Simon's heard about a cool new online to-do app. He checks out its homepage
        self.browser.get('http://localhost:8000')

        # He notices that the page title and header mention "to-do lists"
        self.assertIn ('To-Do', self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn('To-Do', header_text)

        # He's invited to enter a to-do item straight away
        inputbox = self.browser.find_element_by_id('id_new_item')
        self.assertEqual(
            inputbox.get_attribute('placeholder'),
            'Enter a to-do item'
        )

        # He types "go checkout out 'Eloquent JavaScript'" into a text box (Simon's hobby is building websites)
        inputbox.send_keys('Buy Eloquent JavaScript')
        # Whe he hits enter, the page updates, and now the page lists:
        # 1: "Buy 'Eloquent JavaScript'" as an item in a to-do list
        inputbox.send_keys(Keys.ENTER)
        time.sleep(1)

        table = self.browser.find_element_by_id('id_list_table')
        rows = table.find_elements_by_tag_name('tr')
        self.assertTrue(
            any(row.text == '1: Buy Eloquent JavaScript' for row in rows),
            "Ouch, man, here's your own failure message"
        )

        # There's still a text box inviting him to add another item.
        # He enters "check for a review of online JavaScript learning resources" (Simon's very methodical)
        self.fail('Finish the test!')
        # The page updates again, and now shows both items on his list
        [...]
        # Simon wonders whether the site will remember his list.
        # Then she sees that the site has generated a unique URL for him -- there is some explanatory text to that effect.

        # Simon visits that URL - his to-do list is still there.

        # Satisfied, he goes back to building his own website

if __name__ == '__main__':
    unittest.main(warnings='ignore')


import sys
import time
from collections import abc

import numpy as np

# linear partitions
def linParts(numAtoms, numThreads):
    # partition of atoms with a single loop
    parts = np.linspace(0, numAtoms, min(numThreads, numAtoms) + 1)
    parts = np.ceil(parts).astype(int)
    return parts

def nestedParts(numAtoms, numThreads, upperTriang=False):
    # partition of atoms with an inner loop
    parts, numThreads_ = [0], min(numThreads, numAtoms)
    for num in range(numThreads_):
        part = 1 + 4 * (parts[-1] ** 2 + parts[-1] + numAtoms * (numAtoms + 1.) / numThreads_)
        part = (-1 + part ** .5) / 2.
        parts.append(part)
    parts = np.round(parts).astype(int)
    if upperTriang:  # the first rows are heaviest
        parts = np.cumsum(np.diff(parts)[::-1])
        parts = np.append(np.array([0]), parts)
    return parts

import pathos.multiprocessing as mp  # use dill instead of pickle
import datetime as dt

def reportProgress(jobNum, numJobs, time0, task):
    # Report progress as asynch jobs are completed
    msg = [float(jobNum) / numJobs, (time.time() - time0) / 60.]
    msg.append(msg[1] * (1 / msg[0] - 1))
    timeStamp = str(dt.datetime.fromtimestamp(time.time()))
    msg = timeStamp + ' ' + str(round(msg[0] * 100, 2)) + '% ' + task + ' done after ' + \
          str(round(msg[1], 2)) + ' minutes. Remaining ' + str(round(msg[2], 2)) + ' minutes.'
    if jobNum < numJobs:
        sys.stderr.write(msg + '\r')
    else:
        sys.stderr.write(msg + '\n')
    return

def processJobs(jobs, task=None, numThreads=24):
    # Run in parallel.
    # jobs must contain a 'func' callback, for expandCall
    if task is None: task = jobs[0]['func'].__name__
    pool = mp.Pool(processes=numThreads, maxtasksperchild=1000)
    outputs, out, time0 = pool.imap_unordered(expandCall, jobs), [], time.time()
    # Process asyn output, report progress
    for i, out_ in enumerate(outputs, 1):
        out.append(out_)
        reportProgress(i, len(jobs), time0, task)
    pool.close();
    pool.join()  # this is needed to prevent memory leaks
    return out

def expandCall(kargs):
    # Expand the arguments of a callback function, kargs['func']
    func = kargs['func']
    del kargs['func']
    out = func(**kargs)
    return out

def processJobs_(jobs):
    # Run jobs sequentially, for debugging
    out = []
    for job in jobs:
        out_ = expandCall(job)
        out.append(out_)
    return out

def mpPandasObj(func, pdObj, numThreads=24, mpBatches=1, linMols=True, isVerticalParallel=False, **kargs):
    '''
    Parallelize jobs, return a dataframe or series
    + func: function to be parallelized. Returns a DataFrame
    + pdObj[0]: Name of argument used to pass the molecule
    + pdObj[1]: List of atoms that will be grouped into molecules
    + numthreads = num processes that will be used in parallel
    + mpBatchs = number of parallel batches,jobs per process
    + linMols or nestedMols => if first mol more heavy thatn the rest
    + isVerticalParallel => true if allign in the end vertically (columns), not horizontal
    + kwds: any other argument needed by func

    Example: df1=mpPandasObj(func,('molecule',df0.index),24,**kwds)
    '''
    import pandas as pd
    # if linMols:parts=linParts(len(argList[1]),numThreads*mpBatches)
    # else:parts=nestedParts(len(argList[1]),numThreads*mpBatches)
    if linMols:
        parts = linParts(len(pdObj[1]), numThreads * mpBatches)
    else:
        parts = nestedParts(len(pdObj[1]), numThreads * mpBatches)

    jobs = []
    for i in range(1, len(parts)):
        job = {pdObj[0]: pdObj[1][parts[i - 1]:parts[i]], 'func': func}
        job.update(kargs)
        jobs.append(job)
    if numThreads == 1:
        out = processJobs_(jobs)
    else:
        out = processJobs(jobs, numThreads=numThreads)
    if isinstance(out[0], pd.DataFrame):
        df0 = pd.DataFrame()

    elif isinstance(out[0], pd.Series):
        df0 = pd.Series()

    # Add to multiprocessing vectorized if is a dict!
    elif isinstance(out[0], abc.Mapping):
        dictOutput = {}
        for i in out:
            for keyOfDict in i:
                dataframe = i[keyOfDict]
                if keyOfDict not in dictOutput:
                    dictOutput[keyOfDict] = dataframe
                else:
                    if isinstance(dictOutput[keyOfDict], pd.DataFrame):
                        if not isVerticalParallel:
                            dictOutput[keyOfDict] = dictOutput[keyOfDict].append(dataframe)
                            dictOutput[keyOfDict] = dictOutput[keyOfDict].sort_index()
                        else:
                            joinDF(dictOutput[keyOfDict], dataframe)
                    else:
                        listValues = dataframe
                        if listValues is not None and len(listValues) > 0:
                            dictOutput[keyOfDict].append(listValues)

            # for keyOfDict in dict:
            #     dataframe = dict[keyOfDict]
            #     if keyOfDict not in dictOutput:
            #         dictOutput[keyOfDict] = dataframe
            #     else:
            #         if isinstance(dictOutput[keyOfDict], pd.DataFrame):
            #             columnSeries = dictOutput[keyOfDict].dropna(axis=1)
            #             column = columnSeries.columns[0]
            #             dictOutput[keyOfDict][column] = dataframe[column]
            #         else:
            #             #is a list
            #             if dataframe is not None and len(dataframe)>0:
            #                 dictOutput[keyOfDict].append(dataframe)
        return dictOutput
    else:
        return out

    # If is a dataframe processing/series
    for i in out:
        if isVerticalParallel:
            df0 = joinDF(df0, i)
        else:
            df0 = df0.append(i)
    df0 = df0.sort_index()
    return df0

def joinDF(df0, dataframeIn):
    if len(df0) == 0:
        df0 = dataframeIn
    else:
        i_clean = dataframeIn.replace([np.inf, -np.inf], np.nan)
        i_clean = i_clean.fillna(0)
        i_clean = dataframeIn[dataframeIn.columns[(i_clean.sum().astype(int) != 0) == True]]
        df0[i_clean.columns] = dataframeIn[i_clean.columns]
    return df0


import qi
import time
import argparse

QUESTIONS = [
    "Will a stone float on water?",
    "Are there fish in the sea?",
    "Does one pound weigh more than two pounds?",
    "Can you use a hammer to pound a nail?"
]

ANSWERS = [
    "no",
    "yes",
    "no",
    "yes"
]

class DisorganisedThinkingYesNo:
    def __init__(self, session, auto_start=True):
        self.asr = session.service("ALSpeechRecognition")
        self.mem = session.service("ALMemory")
        self.tts = session.service("ALTextToSpeech")
        self.ap = session.service("ALAudioPlayer")
        if auto_start:
            self.start()

    def start(self):
        self.asr.subscribe("Test_ASR")

    def stop(self):
        self.asr.unsubscribe("Test_ASR")

    def say_introduction(self):
        self.tts.say("Could you please answer the following questions with")
        time.sleep(0.25)
        self.tts.say("yes")
        time.sleep(0.25)
        self.tts.say("or")
        time.sleep(0.25)
        self.tts.say("no")
        time.sleep(0.25)
        self.tts.say("responses?")
        time.sleep(0.5)

    def interview(self, questions, answers):
        self.asr.pause(1)
        self.asr.setLanguage("English")
        vocabulary = list(set(answers))
        self.asr.setVocabulary(vocabulary, False)

        self.say_introduction()

        failures = 0
        for i, question in enumerate(questions):
            self.asr.pause(1)
            self.tts.say(question)
            time.sleep(0.5)

            self.mem.insertData("WordRecognized", ("", 0.0))
            self.asr.pause(0)

            start_time = time.time()
            while time.time() - start_time < 5.0:
                word, score = self.mem.getData("WordRecognized")
                print(word, score)
                if not word == "" and score >= 0.4:
                    break
                time.sleep(0.1)

            if not (word == ANSWERS[i] and score >= 0.4):
                failures += 1
            time.sleep(0.5)

        return failures

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip", dest="ip", action="store", type=str, default="pepper.local")
    parser.add_argument("--port", dest="port", action="store", type=int, default=9559)
    args = parser.parse_args()

    app = qi.Application(["CAMICU", "--qi-url=tcp://{}:{}".format(args.ip, args.port)])
    app.start()
    session = app.session

    feature_4_1 = DisorganisedThinkingYesNo(session)
    feature_4_1.interview(QUESTIONS, ANSWERS)
    feature_4_1.stop()


from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
    path('add-user', views.add_user),
    path('result/<int:id>', views.result),
    path('reset/<int:id>', views.reset)

]