from PyQt5.QtWidgets import QWidget,QLineEdit,QHBoxLayout, QVBoxLayout
from UI.Components.button_container import ButtonContainer #buttonClickNoise
from UI.KeyboardPage.completer import suggestWords

groupedChars = ['abc | def | ghi',
                'jkl | mno | pqr',
                'stu | vwx | yz0',
                '123 | 456 | 789']

groupedChars2 = [['a | b | c','d | e | f','g | h | i'],
                ['j | k | l','m | n | o','p | q | r'],
                ['s | t | u','v | w | x','y | z | 0'],
                ['1 | 2 | 3','4 | 5 | 6','7 | 8 | 9']]
class KeyboardWidget(QWidget):

    def __init__(self, parent):
        super().__init__(parent)
        layout = QVBoxLayout()
        self.setObjectName("Keyboard Page")

        layout.addWidget(self.keyboardWidgetUpper(parent))
        layout.addWidget(self.keyboardWidgetLower(parent))

        self.setLayout(layout)

        # #create auto completer
        # self.completer = AutoCompleter()
        # self.completer.setWidget(self)

    def keyboardWidgetUpper(self,parent):
        keyboardKeys = QWidget()
        layout = QHBoxLayout()
        keyboardKeys.setObjectName("Keyboard Widget")

        buttons = []
        for x in range(4):
            button = ButtonContainer(groupedChars[x], freqName=f"Keyboard {x+1}", checkable=False)
            buttons.append(button)
            layout.addWidget(button)

        buttons[0].clicked.connect(lambda: keyboardClick(parent,buttons, buttons[0]))
        buttons[1].clicked.connect(lambda: keyboardClick(parent,buttons, buttons[1]))
        buttons[2].clicked.connect(lambda: keyboardClick(parent,buttons, buttons[2], prediction=True))
        buttons[3].clicked.connect(lambda: keyboardClick(parent,buttons, buttons[3], prediction=True))

        keyboardKeys.setLayout(layout)
        return keyboardKeys

    def keyboardWidgetLower(self,parent):
        sidebar = QWidget()
        layout = QHBoxLayout()
        buttons = []

        sidebar.setObjectName("low keys")

        toggleBtn = ButtonContainer("Toggle Words", freqName="Word Toggle", checkable=False)
        toggleBtn.setObjectName("Toggle")
        buttons.append(toggleBtn)

        buttons.append(ButtonContainer("Space",freqName="Space",checkable=False))
        buttons.append(ButtonContainer("Backspace",freqName="Backspace",checkable=False))

        for button in buttons:
            layout.addWidget(button)

        buttons[0].clicked.connect(lambda: toggle(parent))
        buttons[1].clicked.connect(lambda: space(parent))
        buttons[2].clicked.connect(lambda: backspace(parent))

        sidebar.setLayout(layout)
        return sidebar

def clickedGroup(parent, buttons, text, level):
    print(level)

    if level == 1:
        nextGroup = groupedChars2[groupedChars.index(text)]

    elif level == 2:
        nextGroup = list(text.split(' | '))
        print(nextGroup)
    print(len(buttons))
    print("length")
    for x in range(len(buttons) - 1):
        print(x)
        buttons[x].label.setText(nextGroup[x])

    buttons[3].label.setText("Back")

def clickedBack(parent, buttons, text, level):
    if level == 2:
        for x in range(len(buttons)):
            buttons[x].label.setText(groupedChars[x])

    elif level == 3:
        currentCharGroup = ""
        for x in range(len(buttons) - 2):
            currentCharGroup +=  buttons[x].label.text()
            currentCharGroup +=  " | "
        currentCharGroup +=  buttons[2].label.text()
        print(currentCharGroup)

        for group in groupedChars2:
            if currentCharGroup in group:
                for x in range(len(buttons)-1):
                    buttons[x].label.setText(groupedChars2[groupedChars2.index(group)][x])
                break

def keyboardClick(parent,buttons,selected,prediction=False):
    #buttonClickNoise()

    toggleBtn = parent.findChild(ButtonContainer,"Toggle")
    btnText = selected.label.text()

    if btnText in groupedChars:
        clickedGroup(parent, buttons, btnText, 1)
    elif any(btnText in subl for subl in groupedChars2):
        clickedGroup(parent, buttons, btnText, 2)
    elif btnText == "Back":
        if any(buttons[0].label.text() in subl for subl in groupedChars2):
            clickedBack(parent, buttons, btnText, 2)
        else:
            clickedBack(parent, buttons, btnText, 3)

    elif prediction == True: # Different button functionality when using GTP3 for prediction

        writePredictionToInput(parent, buttons, btnText, charMode=toggleBtn.label.text() == "Toggle Words")
        suggestWords(parent)
    else:
        writeToInput(parent, buttons, btnText)

def writeToInput(parent, buttons, text):
    inputField = parent.findChild(QLineEdit,"Input")

    prevText = inputField.text()
    if len(text) == 1:
        for x in range(len(buttons)):
            buttons[x].label.setText(groupedChars[x])
    else:
        prevText =  " ".join(inputField.text().split()[0:-1]) + " "
        text = text + " "
    temp = text
    if prevText:
        temp = prevText + text

    inputField.setText(temp)

def writePredictionToInput(parent, buttons, text, charMode):
    inputField = parent.findChild(QLineEdit,"Input")
    prevText = inputField.text()

    # Deletes space between any words and puncuations
    if not text[0].isalpha():
        print("NOT:" + text + "END")
        prevText = prevText.rstrip()

    temp = text

    # If user is typing individual characters
    if charMode == True and len(text) == 1:
        for x in range(len(buttons)):
            buttons[x].label.setText(groupedChars[x])
    else:
        temp += ' '

    inputField.setText(temp)

def backspace(parent):
    #buttonClickNoise()

    inputField = parent.findChild(QLineEdit,"Input")

    temp = inputField.text()

    if len(temp) != 0 :
        inputField.setText(temp[:-1])

def space(parent):
    #buttonClickNoise()

    inputField = parent.findChild(QLineEdit,"Input")

    temp = inputField.text() + " "
    inputField.setText(temp)

def toggle(parent):
    #buttonClickNoise()

    toggleBtn = parent.findChild(ButtonContainer,"Toggle")
    keyboardWidget = parent.findChild(QWidget,"Keyboard Widget")
    keyboardBtns = keyboardWidget.findChildren(ButtonContainer)

    if toggleBtn.label.text() == "Toggle Words":
        toggleBtn.label.setText("Toggle Characters")
        # Request API call for GPT-3
        suggestWords(parent)
        keyLabels = ['word','word','this is a phrase','this is a phrase']

    else:
        toggleBtn.label.setText("Toggle Words")
        keyLabels = groupedChars
        for x in range(len(keyboardBtns)):
            keyboardBtns[x].label.setText(keyLabels[x])


import xarray as xa
from data import eisc
from data import zc
from data import dcm

test_run = True
input_dir = "/discover/nobackup/projects/eis_freshwater/swang9/OL_1km/OUTPUT.RST.2013"
month = "201303" if test_run else  "*"
eisc( cache = "/gpfsm/dnb43/projects/p151/zarr", mode = "eis.freshwater.swang9" )
input = f"{input_dir}/SURFACEMODEL/{month}/LIS_HIST" + "_{time}.d01.nc"

if __name__ == '__main__':

    dcm().init_cluster()
    dset: xa.Dataset = zc().get_input( input, merge_dim="time" )

    time = dset['time'].values
    path = dset['_eis_source_path'].values
    for idx in range(time.size):
       print( f"{time[idx]}: {path[idx]}")


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Created on 2017/12/16

__author__ = "Jianguo Jin (jinjianguosky@hotmail.com)"

"""
    Description:

"""
import unittest
from selenium import webdriver

class SearchTest(unittest.TestCase):
    """【天猫产品搜索】单元测试版本 """

    def test_search_by_name(self):
        driver = webdriver.Chrome()
        driver.implicitly_wait(20)
        driver.get('https://www.tmall.com')

        search_field = driver.find_element_by_name('q')
        search_field.clear()
        search_field.send_keys('小米 Note')
        search_field.submit()

        products = driver.find_elements_by_xpath('//*[@id="J_ItemList"]/div/div/div/a[1]')
        self.assertEqual(158, len(products))

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


import copy
import unittest

# Local stuff:
from game_board import GameBoard
import solvers

# A constant valid board. I absolutely did not copy this by hand from an example online.
valid_board = [
    [5, 3, 4, 6, 7, 8, 9, 1, 2],
    [6, 7, 2, 1, 9, 5, 3, 4, 8],
    [1, 9, 8, 3, 4, 2, 5, 6, 7],
    [8, 5, 9, 7, 6, 1, 4, 2, 3],
    [4, 2, 6, 8, 5, 3, 7, 9, 1],
    [7, 1, 3, 9, 2, 4, 8, 5, 6],
    [9, 6, 1, 5, 3, 7, 2, 8, 4],
    [2, 8, 7, 4, 1, 9, 6, 3, 5],
    [3, 4, 5, 2, 8, 6, 1, 7, 9],
]

# The same board with a few elements removed, ripe for solving.
partial_board_1 = [
    [5, None,    4,    6,    7,    8,    9,    1,    2],
    [6,    7, None,    1,    9,    5, None,    4,    8],
    [1,    9,    8,    3,    4,    2,    5,    6, None],
    [8, None,    9,    7, None,    1,    4,    2,    3],
    [4,    2,    6,    8,    5,    3,    7,    9,    1],
    [7,    1,    3,    9,    2,    4,    8, None,    6],
    [9,    6,    1, None,    3,    7,    2,    8,    4],
    [2,    8,    7,    4,    1,    9,    6,    3,    5],
    [3,    4,    5,    2,    8,    6,    1,    7,    9],
]

# The same board with a few more elements removed.
partial_board_2 = [
    [5, None,    4,    6,    7,    8,    9,    1,    2],
    [6,    7, None,    1,    9,    5, None,    4,    8],
    [1,    9,    8,    3,    4, None,    5,    6, None],
    [8, None,    9,    7, None,    1,    4,    2,    3],
    [4,    2,    6,    8,    5,    3,    7,    9,    1],
    [7,    1,    3,    9,    2,    4,    8, None,    6],
    [None, 6,    1, None,    3,    7,    2,    8,    4],
    [None, None, 7,    4,    1,    9,    6,    3,    5],
    [None, None, 5,    2,    8,    6,    1,    7,    9],
]

# A harder problem
partial_board_3 = [
    [5, None,    4,    6,    7,    8,    9,    1,    2],
    [6,    7, None,    1,    9,    5, None,    4,    8],
    [1,    9,    8,    3,    4, None,    5,    6, None],
    [8, None,    9,    7, None,    1,    4,    2,    3],
    [4,    2,    6,    8,    5,    3,    7,    9,    1],
    [7,    1,    3, None,    2, None,    8, None,    6],
    [None, 6,    1, None,    3,    7,    2,    8,    4],
    [None, None, 7,    4,    1, None,    6,    3,    5],
    [None, None, 5,    2,    8,    6, None,    7,    9],
]

class TestGameBoard(unittest.TestCase):
    def test_valid_board(self):
        """ A simple, complete and valid board should be considered solved.
        """
        board = GameBoard()
        board.initialise_board(valid_board)

        self.assertTrue(board.is_solved())
        self.assertEqual(board.occupancy(), 1.0)

    def test_repeated_value(self):
        """ A board with a repeated value should not be valid.
        """
        board = GameBoard()
        board.initialise_board(valid_board)
        board.value(0, 0, 2)

        self.assertFalse(board.is_valid())

    def test_out_of_range(self):
        """ A board with an out-of-range value should not be valid.
        """
        board = GameBoard()
        board.initialise_board(valid_board)
        board.value(1, 1, 10)

        self.assertFalse(board.is_valid())

    def test_incomplete(self):
        """ A board that is missing an element should not be considered complete.
        """
        board = GameBoard()
        board.initialise_board(valid_board)
        board.erase(0, 0)

        self.assertFalse(board.is_complete())

    def test_empty_board(self):
        """ An empty board cannot be completed or solved.
        """
        board = GameBoard()

        self.assertFalse(board.is_solved())
        self.assertTrue(board.is_valid())
        self.assertFalse(board.is_complete())

    def test_random_board(self):
        """ Test generating a random board.

        A random board should (extremely likely) not be solved, should (extremely likely) not be valid, and should be
        complete.
        """
        board = GameBoard()
        board.random_init()

        self.assertFalse(board.is_solved())
        self.assertFalse(board.is_valid())
        self.assertTrue(board.is_complete())

    def test_random_partial_board(self):
        """ We can specify not wanting to initialise the whole board.
        """
        board = GameBoard()
        board.random_init(50)

        self.assertFalse(board.is_solved())
        self.assertFalse(board.is_valid())
        self.assertFalse(board.is_complete())

    def test_random_board_iterator(self):
        """ Test generating a random board iterator.
        """
        board = GameBoard()
        elements = list(board.random_board_iterator())

        self.assertTrue(len(elements) == len(set((tuple(elem) for elem in elements))))
        self.assertTrue(len(elements) == 81)

    def test_occupancy(self):
        """ The occupancy function returns how much of the grid is occupied.
        """
        board = GameBoard()

        self.assertEqual(board.occupancy(), 0)

        board = GameBoard()
        board.random_init(9)
        self.assertAlmostEqual(board.occupancy(), 0.1, 1)

        board = GameBoard()
        board.random_init(18)
        self.assertAlmostEqual(board.occupancy(), 0.2, 1)

    def test_erase_random(self):
        """ Random erasure function should do what we want it to.

        E.g. if we add only one element, it should remove it.
        """
        board = GameBoard()

        board.random_init(1)
        self.assertGreater(board.occupancy(), 0)

        board.erase_random()
        self.assertEqual(board.occupancy(), 0)

        board = GameBoard()
        board.random_init(5)

        for _ in range(5):
            board.erase_random()

        self.assertEqual(board.occupancy(), 0)

    def test_fixed_positions(self):
        """ Elements added as fixed should be reported as such.
        """
        board = GameBoard()
        board.random_init(1, True)

        count = 0
        for i, j in board.board_iterator():
            if board.value(i, j) != None:
                count += 1
                self.assertTrue(board.is_fixed(i, j))

        self.assertEqual(count, 1)

    def test_non_fixed_positions(self):
        """ Elements added as non-fixed should be reported as such.
        """
        board = GameBoard()
        board.random_init(1, False)

        count = 0
        for i, j in board.board_iterator():
            if board.value(i, j) != None:
                count += 1
                self.assertFalse(board.is_fixed(i, j))

        self.assertEqual(count, 1)

    def test_sub_board_coordinates(self):
        board = GameBoard()

        coordinates = [
            (0, 0),
            (3, 3),
            (5, 6)
        ]
        sub_board_indices = [
            (0, 0),
            (1, 1),
            (1, 2)
        ]

        for elem, expected in zip(coordinates, sub_board_indices):
            self.assertEqual(board.sub_board_from_indices(*elem), expected)

class TestBacktrackSolver(unittest.TestCase):
    def test_generate_from_empty(self):
        """ If we solve an empty board, it should generate a solved board.
        """
        generated_board = solvers._backtrack(GameBoard(), 1000000)
        self.assertTrue(generated_board.is_solved())

    def test_solve_from_partial(self):
        """ If we solve a partial board, it should generated a solved board.

        The solved board should be equal to the valid board, since I didn't remove enough elements to generate a
        multi-solution problem.

        The original board should remain unchanged, which is useful e.g. for benchmarking solvers.
        """
        board = GameBoard()
        board.initialise_board(partial_board_1)
        solved_board = solvers._backtrack(board, 1000)

        self.assertTrue(solved_board.is_solved())
        self.assertEqual(board._board, partial_board_1)
        self.assertEqual(solved_board._board, valid_board)

class TestDeductiveSolver(unittest.TestCase):
    def test_solve_from_partial(self):
        """ If we solve a partial board, it should generated a solved board.
        """
        board = GameBoard()
        board.initialise_board(partial_board_1)
        solved_board = solvers._deductive(board, 1000)

        self.assertTrue(solved_board.is_solved())
        self.assertEqual(board._board, partial_board_1)
        self.assertEqual(solved_board._board, valid_board)

    def test_solve_from_partial(self):
        """ Should be able to solve a slightly harder problem.
        """
        board = GameBoard()
        board.initialise_board(partial_board_2)
        solved_board = solvers._deductive(board, 1000)

        self.assertTrue(solved_board.is_solved())
        self.assertEqual(board._board, partial_board_2)
        self.assertEqual(solved_board._board, valid_board)

class TestCombinedSolvers(unittest.TestCase):
    def test_solve_from_partial(self):
        """ The deductive solver might not be able to tackle a certain harder problem

        ... but a combination of deductive and backtrack should.
        """
        board = GameBoard()
        board.initialise_board(partial_board_3)
        intermediate_board = solvers._deductive(board, 1000)

        # The deductive solved should be unable to solve the problem, but should return a valid board.
        self.assertFalse(intermediate_board.is_solved())
        self.assertLess(intermediate_board.occupancy(), 1.0)
        self.assertTrue(intermediate_board.is_valid())
        self.assertFalse(intermediate_board.is_complete())

        solved_board = solvers._backtrack(intermediate_board, 10000)
        self.assertTrue(solved_board.is_solved())

    def test_top_level_solve(self):
        """ The top-level solve function should be able to solve any valid problem.
        """
        board = GameBoard()
        board.initialise_board(partial_board_3)
        solved_board = solvers.solve(board, 10000)
        self.assertTrue(solved_board.is_solved())

if __name__ == "__main__":
    unittest.main()


from django.urls import path
from django.http import HttpResponse
from django.template import Template, Context

def index(request):
    return HttpResponse('''

Welcome to my homepage

        My favorite Game of Thrones characters

        About me

    ''')

def characters(request):
    return HttpResponse('''

My favorite Game of Thrones Characters

Daenerys Targaryen

Jon Snow

Tyrion Lannister

Arya Stark

        Back to home page
    ''')

def about_me(request):
    return HttpResponse('''

About me

Just your average django dev

        Back to home page
    ''')

urlpatterns = [
    path('', index),
    path('my-favorite-characters', characters),
    path('ABout-/-/meeeee', about_me),
]

# Boilerplate -- Don't worry about understanding anything from here down
def main():
    import sys
    from django.conf import settings
    from django.core.management import execute_from_command_line

    settings.configure(
        DEBUG=True,
        ROOT_URLCONF=sys.modules[__name__],
    )

    execute_from_command_line(sys.argv)

if __name__ == '__main__':
    main()


#Program to prove the Collatz conjecture

n = int(input("Enter a positive integer: "))

#Keep looping until we reach 1
while n!= 1:
#Print the current value of n
    print(n)
    #If n is even, divide by 2
    if n % 2 == 0:
        n = n//2
    #If n is odd, multiply by 3 and add 1
    else:
        n = (3*n) +1

#Finally, print the 1
print(n)


from django.db import models
from django.contrib.auth.models import User
from final.settings import AUTH_USER_MODEL as User
# 질문란
class Question(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=200)
    content = models.TextField()
    create_date = models.DateTimeField()
    modify_date = models.DateTimeField(null=True, blank=True)
    # 작성한 질문이 제목으로 보여지게 함
    def __str__(self):
        return self.subject
# 댓글란
class Answer(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    content = models.TextField()
    create_date = models.DateTimeField()
    modify_date = models.DateTimeField(null=True, blank=True)


# Jan Faryad
# 2. 7. 2017
#
# conversion of the onto IDs to udapi nodes

class Onto_word_conversion:
    def __init__( self, list_of_corefs_clusters, list_of_corresponding_words):
        """
        list of clusters, cluster have list of coreferents of type Onto_coreferent
        correspondence ... pairs ( onto id, node )
        """
        self.list_of_corresponding_words = list_of_corresponding_words
        for coref_cluster in list_of_corefs_clusters:
            new_coreferents = [] # will be filled with Nodes instead of onto ids
            for coreferent in coref_cluster.coreferents:
                new_coreferent = self.convert_coref( coreferent) # udapi node
                new_coreferents.append( new_coreferent)
            coref_cluster.coreferents = new_coreferents

    def convert_coref( self, coreferent): # -> udapi node
        try:
            sentence_split = coreferent.position_string.split( '.') # a.b-c, a - sentence number, b/c - first/last word number
            sent_number = int( sentence_split[0])
            word_split = sentence_split[1].split( '-')
            first_word_number = int( word_split[0])
            last_word_number = int( word_split[1])
        except:
            return None

        subtree = [] # the whole expression (interval of Nodes)
        for pair in self.list_of_corresponding_words:
            ( onto_sent_id, onto_word_id ) = pair[0]
            if ( onto_sent_id == sent_number and onto_word_id >= first_word_number and onto_word_id <= last_word_number ):
                subtree.append( pair[1]) # corresponding conll node

        #subtree_form = ""
        #for i in subtree:
        #    subtree_form += " " + i.form

        # we have to chose the head of the interval - this will be the only corefering word
        subtree_head = None
        for node in subtree: # finding the head of the interval
            head = True
            for other_node in subtree:
                if ( node.is_descendant_of( other_node) ): # head musn't be descendant of another node from the interval
                    head = False
                    break
            if ( head ):
                subtree_head = node
                break

        #print( subtree_form)
        #print( subtree_head.form)
        #print("")
        return subtree_head


import random
import requests
import time

class LED_manager:
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(LED_manager, cls).__new__(cls)
        return cls.instance

    def __init__(self) -> None:
        self.leds = []
        self.create_leds()

    def configure_wled(self,url, settings):
        try:
            response = requests.post(url, json=settings)
            response.raise_for_status()
            print("Konfigurace úspěšně odeslána.")
        except requests.exceptions.RequestException as e:
            print("Chyba při odesílání požadavku:", e)

    def create_leds(self,count=15):
        for i in range(count):
            self.leds.append(LED(i))

    def set_color(self,led_id,rgb):
        self.leds[led_id].color = rgb

    def set_brightness(self,led_id,brightness):
        self.leds[led_id].brightness = brightness

    def  set_state(self,led_id,state):
        self.leds[led_id].state = state

    def settings(self):
        settings = {"seg": []}
        for led in self.leds:
            settings["seg"].append({
                "on":led.state,
                "bri":led.brightness,
                "col":[[led.color[0],led.color[1],led.color[2],0],[],[]],
                "start":led.position,
                "stop": led.position+1
            })
        return settings
    def change_state(self,device_id:int, state: bool, rgb: list, brightness=128 ):
        wled_url = "http://10.10.3.24/json/state"  # Nahraďte <adresa_wled> IP adresou a portem WLED
        for i in range(15):
            self.set_state(i,state)
            self.set_color(i,rgb)
            self.set_brightness(i,brightness)
        self.configure_wled(wled_url,self.settings())

class LED():
    def __init__(self,position) -> None:
        self.state = True
        self.color = [0,0,255]
        self.brightness=128
        self.position = position

manager = LED_manager()
"""
time.sleep(1)
manager.change_state(1,False,[255,0,0])
time.sleep(1)
manager.change_state(1,True,[0,255,0],brightness=255)

time.sleep(1)
manager.change_state(1,True,[0,0,255])
manager.set_color(2,[0,0,0])
manager.change_state(2,True,[255,0,0])
manager.change_state(3,True,[0,255,0])
"""


from .transformer import Transformer
from musikla.core import Voice
from musikla.core.events import MusicEvent, NoteEvent, RestEvent, ChordEvent
from typing import List, Optional

class SlidingAverage():
    def __init__ ( self, capacity : int = 0 ):
        self.history : List[float] = []
        self.capacity = capacity
        self.sum : float = 0
        self.count : int = 0

    def __iadd__ ( self, value : float ):
        if self.count == 0:
            self.sum = value
            self.count = 1

            if self.capacity > 0:
                self.history.append( value )
        else:
            #  ( ( self.average / self.count ) + ( value / ( self.count + 1 ) ) )
            self.sum += value

            if self.capacity == 0 or self.count < self.capacity:
                self.count += 1
            else:
                self.sum -= self.history.pop( 0 )

            if self.capacity > 0:
                self.history.append( value )

        return self

    def __int__ ( self ):
        if self.count == 0:
            return 0

        return int( self.sum / self.count )

    def __float__ ( self ):
        if self.count == 0:
            return 0

        return float( self.sum / self.count )

class VoiceIdentifierVoice():
    def __init__ ( self, transformer : 'VoiceIdentifierTransformer', parent : Voice, index : int, staff : int = None ):
        self.transformer : VoiceIdentifierTransformer = transformer
        self.parent_name : str = parent.name
        self.parent_staff : Optional[int] = staff
        self.voice : Voice = parent.clone( parent.name + '/' + str( index ) )
        self.index = index
        self.average_pitch : SlidingAverage = SlidingAverage()
        self.auto_create_rests : bool = True
        self.auto_create_end_rests : bool = True
        self.last_event : Optional[MusicEvent] = None

    @property
    def last_timestamp ( self ):
        if self.last_event is None:
            return 0

        return self.last_event.timestamp

    @property
    def last_end_timestamp ( self ):
        if not self.last_event:
            return 0

        return self.last_event.end_timestamp

    def is_busy_at ( self, timestamp : int ) -> bool:
        return self.last_end_timestamp > timestamp

    def is_connected_at ( self, timestamp : int ) -> bool:
        return abs( timestamp - self.last_end_timestamp ) <= 3

    def distance ( self, event : NoteEvent ) -> float:
        return abs( int( event ) - int( self.average_pitch ) )

    def create_rest ( self, target : int, visible : bool = True ) -> RestEvent:
        duration = target - self.last_end_timestamp

        value = self.voice.from_duration_absolute( duration )

        return RestEvent(
            timestamp = self.last_end_timestamp,
            visible = visible,
            duration = duration,
            value = value,
            voice = self.voice,
            staff = self.parent_staff
        )

    def append ( self, *events : MusicEvent ):
        for event in events:
            if isinstance( event, NoteEvent ) or isinstance( event, ChordEvent ):
                self.average_pitch += int( event ) if isinstance( event, NoteEvent ) \
                                else  sum( event.pitches ) / len( event.pitches )

                # TODO Allow setting a minimum rest duration. If the empty space between the events is less than
                # said minimum, then no rest is created
                if self.auto_create_rests and self.last_end_timestamp < event.timestamp - 1:
                    self.transformer.add_output( self.create_rest( event.timestamp ) )

            self.transformer.add_output( event.clone( voice = self.voice ) )

            self.last_event = event

class VoiceIdentifierTransformer(Transformer):
    """
    This class receives a flat, ordered stream of musical events and splits them in multiple voices and identifies parallel notes/chords
    """
    def __init__ ( self, auto_create_rests : bool = True, auto_create_end_rests : bool = True ):
        super().__init__()

        self.voices : List[VoiceIdentifierVoice] = []

        self.auto_create_rests : bool = auto_create_rests

        self.auto_create_end_rests : bool = auto_create_end_rests

    def create_voice_for ( self, event : NoteEvent ) -> VoiceIdentifierVoice:
        index = max( ( voice.index for voice in self.voices if voice.parent_name == event.voice.name ), default = 0 )

        voice = VoiceIdentifierVoice( self, event.voice, index + 1, event.staff )

        voice.auto_create_rests = self.auto_create_rests
        voice.auto_create_end_rests = self.auto_create_end_rests

        self.voices.append( voice )

        return voice

    def find_voice_for ( self, event, auto_create : bool = True ) -> Optional[VoiceIdentifierVoice]:
        best_voice, best_voice_dst = None, None

        for voice in self.voices:
            if voice.parent_name != event.voice.name or voice.parent_staff != event.staff:
                continue

            # If the voice already has a sound playing at this timestamp
            if voice.is_busy_at( event.timestamp ):
                continue

            if event.staff is not None:
                return voice

            voice_dst = voice.distance( event )

            if best_voice is None or best_voice_dst > voice_dst:
                best_voice = voice
                best_voice_dst = voice_dst

        if best_voice is None and auto_create:
            best_voice = self.create_voice_for( event )

        return best_voice

    def find_voice_for_rest ( self, event, auto_create : bool = True ) -> VoiceIdentifierVoice:
        for voice in self.voices:
            if voice.parent_name != event.voice.name or voice.parent_staff != event.staff:
                continue

            # If the voice already has a sound playing at this timestamp
            if voice.is_connected_at( event.timestamp ):
                return voice

        return self.create_voice_for( event )

    def register_rest ( self, event : RestEvent ):
        voice = self.find_voice_for_rest( event )

        if voice is not None:
            voice.append( event )

    def register_note ( self, event : NoteEvent ):
        voice = self.find_voice_for( event )

        if voice is not None:
            voice.append( event )

    def register_chord ( self, event : ChordEvent ):
        voice = self.find_voice_for( event )

        if voice is not None:
            voice.append( event )

    def transform ( self ):
        """
        For now, NoteOn/NoteOff events will be ignored.
        Use the compose transformer before passing events into this notation builder.
        This might change in the future.
        """
        while True:
            done, event = yield

            if done: break

            if isinstance( event, NoteEvent ):
                self.register_note( event )
            elif isinstance( event, RestEvent ):
                self.register_rest( event )
            elif isinstance( event, ChordEvent ):
                self.register_chord( event )
            else:
                self.add_output( event )

        if self.auto_create_end_rests and self.voices:
            last_voice_timestamp : int = max( [ voice.last_end_timestamp for voice in self.voices ] )

            for voice in self.voices:
                if voice.last_end_timestamp < last_voice_timestamp:
                    self.add_output( voice.create_rest( last_voice_timestamp, visible = False ) )


import random

user_wins = 0
computer_wins = 0

options = ['r', 'p', 's']

while True:
    user_input = input("Type Rock[r]/Paper[p]/Scissors[s] or q to quit: ").lower()
    if user_input == 'q':
        break
    if user_input not in options:
        continue

    random_number = random.randint(0, 2)
    # rock: 0, paper: 1, scissors: 2
    computer_pick = options[random_number]
    print(f'Computer picked, {computer_pick}.')

    if user_input == 'r' and computer_pick == 's':
        print('You won!')
        user_wins += 1

    elif user_input == 'p' and computer_pick == 'r':
        print('You won!')
        user_wins += 1

    elif user_input == 's' and computer_pick == 'p':
        print('You won!')
        user_wins += 1

    else:
        print('You lost!')
        computer_wins += 1

print(f"You won {user_wins} times.")
print(f"The computer won {computer_wins} times.")
print('Goodbye!')


from streamer.database import StreamerDB
from pymongo.errors import WriteError

class StreamerUsers:

    def __init__(self):
        """
        BookdlUsers is the mongo collection for the documents that holds the details of the users.

        Functions:
            insert_user: insert new documents, that contains the details of the new users who started using the bot.

            get_user: return the document that contains the user_id for the the given telegram user id.

        """
        self.user_collection = StreamerDB().db['Users']

    async def insert_user(self, user_id: int):
        if self.user_collection.count_documents({'user_id': user_id}) > 0:
            return
        else:
            self.user_collection.insert_one({
                'user_id': user_id,
                'stream_locations': [],
            })

    async def get_user(self, user_id: int):
        return self.user_collection.find_one({'user_id': user_id})

    async def add_stream_loc(self, user_id: int, stream_chat_id: int,
                             name: str, stream_url: str, stream_key: str):
        try:
            res = self.user_collection.update_one({'user_id': user_id}, {
                '$push': {
                    'stream_locations': {
                        'name': name,
                        'stream_url': stream_url,
                        'stream_key': stream_key,
                        'stream_chat_id': stream_chat_id
                    }
                }
            })
        except WriteError as e:
            None, e.details
        return res, None

    async def remove_stream_loc(self,
                                user_id: int,
                                stream_chat_id: int = None):
        try:
            if stream_chat_id:
                query = {
                    '$pull': {
                        'stream_locations': {
                            'stream_chat_id': stream_chat_id
                        }
                    }
                }
            else:
                query = {'$set': {'stream_locations': []}}

            res = self.user_collection.update_one({'user_id': user_id}, query)

        except WriteError as e:
            None, e.details
        return res, None

    async def get_stream_loc(self, user_id: int, stream_chat_id: int = None):
        res = (await self.get_user(user_id))['stream_locations']
        if not stream_chat_id:
            return res
        else:
            return next(
                (loc
                 for loc in res if loc['stream_chat_id'] == stream_chat_id),
                None)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Oct  2 14:31:00 2019

@author: andrew
"""

import numpy as np
from pyDOE import lhs as LHS
import subprocess
import os
import time
from scipy.special import erf as ERF
#import sys
from os.path import expanduser

import IscaOpt

# home directory
home = expanduser("~")

from hydro_plane import Ellipse

from multiprocessing import Process, Queue, current_process, freeze_support

try:
    from data import support
except:
    from .data import support

#from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile

current = os.getcwd()

from scipy.spatial.distance import euclidean
import shutil

# APR added
try:
    from data.SnappyHexOptimise import BasicHeatExchangerRun
except:
    from .data.SnappyHexOptimise import BasicHeatExchangerRun
try:
    from interfaces import EllipseInterface
except:
    from .interfaces import EllipseInterface
try:
    from base_class import Problem
except:
    from .base_class import Problem
try:
    from data import support
except:
    from .data import support

#############
# Environment
#############
# On ISCA, there can be batches of up to the maximum number of samples

#environment = 'isambard'
#environment = 'isambard_test'
#environment = 'isca'
#environment = 'isca_test'

#environment = 'isca_forrester'
environment = 'local_forrester'

no_of_nodes = 4

# Locally, there can only be three "nodes" as each one has 2 CPUS, and I only have 8 CPUs
#environment = 'local'
#no_of_nodes = 3

##########
# Sampling
##########
#sampling = 'manual'
#sampling = 'latin'
sampling = 'latin_forrester'

##########################
# Selection of bash script
##########################

# this bash script is for the OpenFOAM run
if environment == 'isca':
    bash = 'run_script_isca_parallel.sh'
elif environment == 'isca_test':
    # initial sampling does not need to use the optimiser!!!!
    bash = 'isca_initial_sampling_parallel_test.sh'
elif environment == 'isambard':
    # initial sampling does not need to use the optimiser!!!!
    bash = 'isambard_initial_sampling_parallel.sh'
elif environment == 'isambard_test':
    # initial sampling does not need to use the optimiser!!!!
    bash = 'isambard_initial_sampling_parallel_test.sh'
elif environment == 'isca_forrester':
    bash = 'isca_forrester_initial_sampling_parallel.sh'
else:
    bash = 'local_forrester_initial_sampling_parallel.sh'

################
# Create failure
################
failure = True

# HeadCell object:
class HeadCell(Problem, EllipseInterface):

    def __init__(self, settings):
        self.source_case = settings.get('source_case', './data/HeadCell/source/')
        self.case_path = settings.get('case_path', './data/HeadCell/case_local/')
        self.mesh_path = settings.get('mesh_path', './data/HeadCell/meshes/')
        self.setup()

    def setup(self, verbose=False):
        """
        Just sets values
        """
        self.L = 4.0
        self.A = 45.0
        self.R = 1.0
        self.xlb, self.xub = -self.L, self.L
        self.zlb, self.zub = -self.L, self.L
        self.anglelb, self.angleub = 0, self.A
        self.majorlb, self.majorub = 4.0*self.R, 8.0*self.R
        self.minorlb, self.minorub = 4.0*self.R, 8.0*self.R

        EllipseInterface.__init__(self, self.xlb, self.xub, self.zlb, self.zub, \
                                 self.anglelb, self.angleub, self.majorlb, self.majorub, \
                                 self.minorlb, self.minorub)

    def info(self):
        raise NotImplementedError

    def get_configurable_settings(self):
        raise NotImplementedError

    def run(self, shape, verbose=False):
        xp, yp, rp = shape
        support.circle_to_stl(rp, xp, yp, \
            file_directory=self.case_path+self.stl_dir, file_name=self.stl_file_name, draw=False)
        t, p = self.problem.cost_function(sense="multi", verbose=verbose)
        return t, p

    def evaluate(self, decision_vector, verbose=False):
        if not self.constraint(decision_vector):
            raise ValueError('Constraint violated. Please supply a feasible decision vector.')
        shape = self.convert_decision_to_shape(decision_vector)
        try:
            return self.run(shape, verbose)
        except Exception as e:
            print('Solution evaluation failed.')
            print(e)

def lhs_initial_samples(n_dim, ub, lb, n_samples=4, cfunc=None, cargs=(), ckwargs={}):
    """
    Generate Latin hypercube samples from the decision space using pyDOE.

    Parameters.
    -----------
    n_samples (int): the number of samples to take.
    cfunc (method): a cheap constraint function.
    cargs (tuple): arguments for cheap constraint function.
    ckawargs (dictionary): keyword arguments for cheap constraint function.

    Returns a set of decision vectors.
    """
    seed = 1234
    np.random.seed(seed)
    samples = LHS(n_dim, samples=n_samples)

    scaled_samples = ((ub - lb) * samples) + lb

    if cfunc is not None: # check for constraints
        print('Checking for constraints.')
        scaled_samples = np.array([i for i in scaled_samples if cfunc(i, *cargs, **ckwargs)])

    return scaled_samples

# constaints:
def gap_and_checkMesh_constraint(x, layout):
    """
    Create meshes and check the constraints using the decision vector and layout.

    Parameters.
    -----------
    x (numpy array): the decision vector.
    layout (Ellipse object): the object for the generation of the pointwise files.

    Returns whether the constraint was successfully passed.
    """
    # get the current directory
    current = os.getcwd()

    # defaults for success:
    minimum_gap_success = True
    checkMesh_success = False
    success = False

    # checkMesh:
    utility3 = "checkMesh"

    # platform specific changes (not used by Isambard):
    if environment == 'blades':
        Pointwise_path='/usr/local/Pointwise/PointwiseV18.0R2/pointwise'
    elif environment == 'local':
        Pointwise_path='/home/andrew/Pointwise/PointwiseV18.0R2/pointwise'
    elif ((environment == 'isca') or (environment == 'isca_test')):
        Pointwise_path = '/gpfs/ts0/home/apr207/Pointwise/PointwiseV18.0R2/pointwise'
    else:
        #local is default
        Pointwise_path='/home/andrew/Pointwise/PointwiseV18.0R2/pointwise'

    # paths:
    mesh_path = "/data/HeadCell/meshes/"
    source_path = "/data/HeadCell/source/"

    # the neccessary name for the child directory:
    dir_name = "_"

    for j in range(len(x)):
        dir_name += "{0:.4f}_".format(x[j])
        dir_name = dir_name.replace("[","")
        dir_name = dir_name.replace("]","")

    # make the child directory:
    subprocess.call(['mkdir', '-p', current + mesh_path + dir_name + '/system' ])
    subprocess.call(['mkdir', '-p', current + mesh_path + dir_name + '/constant/polyMesh' ])

    # location of centre of ellipse:
    bottom_x_centre = x[0]
    bottom_z_centre = x[1]

    # rotation angle:
    rot_angle = x[2]*(np.pi/180.0)

    # ellipse sizes:
    a = x[3]
    b = x[4]

    # create space for corners and gaps:
    corners = np.zeros((4,2))
    gaps = np.zeros(4)

    # the bottom of the tray:
    y_bottom = -14.9375

    # very top of tray:
    p1 = np.array([0, 6.0625, 0])

    # very bottom of tray:
    p2 = np.array([bottom_x_centre, y_bottom, bottom_z_centre])

    # the radii at the first tray layer:
    a_top = layout.get_ellipse_radii(21.25, a, -2.34375)
    b_top = layout.get_ellipse_radii(21.25, b, -2.34375)

    # the points at the first tray layer:
    c_top = layout.get_ellipse_points(p1, p2, -2.34375)

    # the angle at the first tray layer:
    angle_top = layout.get_ellipse_angles(rot_angle, -2.34375)

    # obtain the four corners:
    for i in range(1,5):
        angles = np.linspace(start=0.5*i*np.pi, stop=0.5*(i-1)*np.pi, num=1, endpoint=True)
        corners[i-1,:] = layout.generate_ellipse(c_top, a_top, b_top, angles, theta=angle_top+np.pi, n=0)

    # compute horizontal gaps:
    for j in range(0,4):
        gaps[j] = 21.25 - np.sqrt((corners[j,0])**2 + (corners[j,1])**2)

    # minimim horizontal gap:
    min_gap=min(gaps)

    # get the index of the minimum horizontal gap and the maximum x-extent:
    index = np.where(gaps == min_gap)
    x_extent_vector = abs(corners[index])
    x_extent= np.amax(x_extent_vector)

    # Definition of the x-y plane locations
    x1 = 21.25
    x2 = x_extent
    x3 = x_extent
    x4 = 21.25

    y1 = -2.9375
    y2 = -2.34375
    y3 = -6.59375
    y4 = 1.3125

    # Hero's formula for the normal gap
    A = y2 - y3
    B = np.sqrt((y4 - y2)**2 + (x4 - x2)**2)
    P = np.sqrt((x1 - x2)**2 + (y1 - y2)**2)
    S = (A+B+P)/2
    Area = np.sqrt(S*(S-A)*(S-B)*(S-P))
    H = 2*Area/B

    # constraints:
    if (H < 2.0):
        # is the centre in the right place?:
        minimum_gap_success = False

    else:

        # copy controlDict and fvSchemes ssfor checkMesh
        shutil.copyfile(current + source_path + 'system/controlDict', current + mesh_path + dir_name + '/system/controlDict')
        shutil.copyfile(current + source_path + 'system/fvSchemes', current + mesh_path + dir_name + '/system/fvSchemes')
        shutil.copyfile(current + source_path + 'system/fvSolution', current + mesh_path + dir_name + '/system/fvSolution')

        # copy all mesh files to mesh path
        for filename in os.listdir(current + source_path):
            full_file_name = os.path.join(current + source_path, filename)
            if os.path.isfile(full_file_name):
                shutil.copy(full_file_name, current + mesh_path + dir_name)

        # update Pointwise files using decision vector (needs checking)
        layout.update(x)

        # decide where we are to run Pointwise:
        if ((environment == 'isambard') or (environment == 'isambard_test')):

            # copy pointwise_script.sh to submit script
            shutil.copyfile(current + '/pointwise_script.sh', current + mesh_path + dir_name + '/pointwise_script.sh')

            # write the location of the current directory to a shell script - used by ssh and qsub
            with open(home + "/pointwise_directory.sh", "a") as myfile:
                myfile.write('export POINTWISE_DIRECTORY=' + '"'+ current + mesh_path + dir_name + '"' + '\n')

            print("checkMesh_constraint(): written current directory to a file")

            # name of the script to submit pointwise with
            bash_pointwise = 'pointwise_script.sh'

            # change bash_pointwise in order to run from current directory
            with open(current + mesh_path + dir_name + '/' + bash_pointwise, 'r') as f:
                data = f.readlines()

            # read in each line and change the directory location
            for line in range(len(data)):
                if '#PBS -o' in data[line]:
                    data[line] = '#PBS -o 10.141.0.1:' + current + mesh_path + dir_name + '/log.pointwise' + '\n'

                if '#PBS -e' in data[line]:
                    data[line] = '#PBS -e 10.141.0.1:' + current + mesh_path + dir_name + '/err.pointwise' + '\n'

            # write the changes to bash_pointwise
            with open(current + mesh_path + dir_name + '/' + bash_pointwise, 'w') as f:
                f.writelines(data)

            # use ssh to send the job to phase 1
            subprocess.call(['ssh','ex-aroberts@login-01.gw4.metoffice.gov.uk', 'source $HOME/pointwise_directory.sh; export PBS_HOME=/cm/shared/apps/pbspro/var/spool; export PBS_EXEC=/cm/shared/apps/pbspro/19.2.4.20190830141245; /cm/shared/apps/pbspro/19.2.4.20190830141245/bin/qsub $POINTWISE_DIRECTORY/pointwise_script.sh;'], cwd=current)

            # check if the log files exist
            while not (os.path.exists(current + mesh_path + dir_name + '/' + 'log.pointwise') and os.path.exists(current + mesh_path + dir_name + '/' + 'err.pointwise')):
                time.sleep(1)

            print("checkMesh_constraint(): pointwise completed")

            # remove the shell script from the home directory
            subprocess.call(['rm', home + '/' + 'pointwise_directory.sh'])

        else:
            # run pointwise on isca or locally using Pointwise_path:
            subprocess.call([Pointwise_path, '-b', current + mesh_path + dir_name + '/Hydro_V18_3_tray_APR_grit_pot_parameterised_ellipse_correction.glf'], cwd=current, \
                              stdout = open(current + mesh_path + dir_name + '/log.pointwise', 'w'), \
                              stderr = open(current + mesh_path + dir_name + '/err.pointwise', 'w'))

        # run checkmesh:
        subprocess.call([utility3, '-case', current + mesh_path + dir_name], cwd=current, \
                      stdout = open(current + mesh_path + dir_name + '/log.checkMesh', 'w'), \
                      stderr = open(current + mesh_path + dir_name + '/err.checkMesh', 'w'))

        # check if the mesh was successful and assign boolean if succeeded
        with open(current + mesh_path + dir_name + "/log.checkMesh") as f:
            if 'Mesh OK.' in f.read():
                checkMesh_success = True

    # Convert boolean into integer
    if minimum_gap_success == True:
        g_success = 1
    else:
        g_success = 0

    # Convert boolean into integer
    if checkMesh_success == True:
        c_success = 1
    else:
        c_success = 0

    # Load the constraints file
    file_constraints = 'constraints.npz'
    data = np.load(current + '/' + file_constraints)

    # Load and set the decision vector
    X = data['arr_0']
    X_current = x

    if X.size != 0:
        X_new = np.vstack((X, X_current))
        print('appended ', X_current, ' to ', X)
        print('this gives ', X_new)
    else:
        X_new = X_current
        print('set ', X_new, ' to ', X_current)

    # Load and set gap constaint success
    G = data['arr_1']
    G_current = g_success

    if G.size != 0:
        G_new = np.vstack((G, G_current))
        print('appended ', G_current, ' to ', G)
        print('this gives ', G_new)
    else:
        G_new = G_current
        print('set ', G_new, ' to ', G_current)

    # Load and set checkMesh success
    C = data['arr_2']
    C_current = c_success

    if C.size != 0:
        C_new = np.vstack((C, C_current))
        print('appended ', C_current, ' to ', C)
        print('this gives ', C_new)
    else:
        C_new = C_current
        print('set ', C_new, ' to ', C_current)

    # Save the decision vector and checkMesh to a file:
    try:
        np.savez(current + '/' + file_constraints, X_new, G_new, C_new)
        print('Data saved in file: ', file_constraints, ' X ', X_new, ' gap constraint ', G_new, ' checkMesh ', C_new)
    except Exception as e:
        print(e)
        print('Data saving failed.')

#    try:
#        np.savez(current + '/' + file_C, initial_X, initial_C)
#        print('Data saved in file: ', file_C)
#    except Exception as e:
#        print(e)
#        print('Data saving failed.')

    print('gap_and_checkMesh_constraint(x): minimum_gap_success passed? ', str(minimum_gap_success), ' as H = ', H)
    print('gap_and_checkMesh_constraint(x): checkMesh_success passed? ', str(checkMesh_success))

    success = checkMesh_success and minimum_gap_success

    # if either it failed the centre location check or the checkMesh, delete the mesh:
    if(checkMesh_success == False):
        # remove mesh if there is a mesh failure
        subprocess.call(['rm', '-r', current + mesh_path + dir_name + '/'])
        print('centre_constraint(): mesh deleted')

    return success

#
# NOT USED FOR INITIAL ISAMBARD TEST:
#
def worker(input, output):
    for func, args in iter(input.get, 'STOP'):
        result = calculate(func, args)
        output.put(result)

#
# NOT USED FOR INITIAL ISAMBARD TEST:
#
def calculate(func, args):
    result = func(*args)
    return '%s says that %s%s = %s' % \
        (current_process().name, func.__name__, args, result)

#
# NOT USED FOR INITIAL ISAMBARD TEST:
#
def mul(d):

    if ((environment == 'isca') or (environment == 'isca_test') or (environment == 'isca_forrester')):
        start_msub = time.time()
        subprocess.call(['msub', '-K', d + '/' + bash], cwd=d, \
              stdout = open(d + '/log.subprocess', 'w'), \
              stderr = open(d + '/err.subprocess', 'w'))

    # submit job using qsub if on isambard:
    elif ((environment == 'isambard') or (environment == 'isambard_test')):
        start_msub = time.time()
        subprocess.call(['qsub', '-W', 'block=true', d + '/' + bash], cwd=d, \
              stdout = open(d + '/log.subprocess', 'w'), \
              stderr = open(d + '/err.subprocess', 'w'))

    else:
        start_msub = time.time()
        subprocess.call(['sh', d + '/' + bash], cwd=d, \
              stdout = open(d + '/log.subprocess', 'w'), \
              stderr = open(d + '/err.subprocess', 'w'))

    return "Done time," + str(time.time() - start_msub)

#
# NOT USED FOR INITIAL ISAMBARD TEST:
#
def queue():

    filedirs = initialisation()

    task_list = [(mul, (d,)) for d in filedirs]

    # Create queues
    task_queue = Queue()
    done_queue = Queue()

    # Submit tasks
    for task in task_list:
        task_queue.put(task)

    # Start worker processes
    for i in range(no_of_nodes):
        Process(target=worker, args=(task_queue, done_queue)).start()

    # Get and print results
    print('Unordered results:')
    for i in range(len(task_list)):
        print('\t', done_queue.get())

    # Tell child processes to stop
    for i in range(no_of_nodes):
        task_queue.put('STOP')

def no_queue():
    """
    Submit the job to the relevant queue without a python queue.

    Parameters.
    -----------
    There are no parameters.

    Does not return anything.
    """
    filedirs = initialisation()

    # submit job using moab if on isca:
    if ((environment == 'isca') or (environment == 'isca_test') or (environment == 'isca_forrester')):
        for d in range(len(filedirs)):
            subprocess.Popen(['msub', filedirs[d] + '/' + bash], cwd=filedirs[d], \
                  stdout = open(filedirs[d] + '/log.subprocess', 'w'), \
                  stderr = open(filedirs[d] + '/err.subprocess', 'w'))

    # submit job using qsub if on isambard:
    elif ((environment == 'isambard') or (environment == 'isambard_test')):
        for d in range(len(filedirs)):
            subprocess.Popen(['qsub', filedirs[d] + '/' + bash], cwd=filedirs[d], \
                  stdout = open(filedirs[d] + '/log.subprocess', 'w'), \
                  stderr = open(filedirs[d] + '/err.subprocess', 'w'))

    # submit job as a shell script if on local pc:
    else:
        for d in range(len(filedirs)):
            subprocess.Popen(['sh', filedirs[d] + '/' + bash], cwd=filedirs[d], \
                  stdout = open(filedirs[d] + '/log.subprocess', 'w'), \
                  stderr = open(filedirs[d] + '/err.subprocess', 'w'))

def initialisation():
    """
    Samples the design space,
    Writes the decision vector to a file
    Creates an empty initial samples file
    Copies and edits the qsub or msub submission script.

    Parameters.
    -----------
    There are no parameters.

    Returns a list of directories for submission.
    """

    if(sampling == 'latin_forrester'):
        # number of dimensions and samples
        n_dim = 1
        #n_samples = 11*n_dim -1
        n_samples = 5
        ub = 1.4
        lb = 0.3
        print("initialisation(): number of Latin Hypercube samples", str(n_samples))
        samples = lhs_initial_samples(n_dim, ub, lb, n_samples, cfunc=None, cargs=(), ckwargs={})
        samples = np.array([np.array([0.5501084598698482]), np.array([0.6004338394793927]), np.array([0.9509761388286335]), np.array([1.2008676789587853]), np.array([1.3015184381778744])])

        case_path = "/data/Forrester/case_local/"
        source_file = 'run_case.py'

        # create filedirs
        filedirs = []

        # loop through the list to create directories:
        for s in samples:

            # create a working directory from the sample:
            dir_name = "_"
            for j in range(len(s)):
                dir_name += "{0:.4f}_".format(s[j])

            # replace any directories containing []
            dir_name = dir_name.replace("[","")
            dir_name = dir_name.replace("]","")

            # add the name to a list of directories
            filedirs.append(current + case_path + dir_name)

            # create the directory from the last in the list and
            subprocess.call(['mkdir', filedirs[-1] + '/'])

            # copy run_case.py to that directory
            subprocess.call(['cp', '-r', current + '/' + source_file, filedirs[-1] + '/'])

            # write the decision vector to a file
            with open(filedirs[-1] + "/decision_vector.txt", "a") as myfile:
                for i in range(0,len(s)):
                    myfile.write(str(s[i])+ '\n')
            print("initialisation(): written decision vector to a file")

        # read decision vector and write to npz file
        print('Writing empty initial_samples.npz file...')

        # hyper volume improvement is null
        hpv = []
        initial_time = 0
        initial_X = []
        initial_Y = []

        # the name of the sim_file is initial_samples.npz
        sim_file = 'initial_samples.npz'

        # remove npz file if it exists
        subprocess.call(['rm', '-r', current + '/' + sim_file])

        # initial_X is decision vector
        # initial_Y is 2 objectives
        # hpv is hypervolume improvement
        # initial_time is zero
        # initial_convergence is convergence failure
        try:
            np.savez(current + '/' + sim_file, initial_X, initial_Y, hpv, initial_time)
            print('Data saved in file: ', sim_file)
        except Exception as e:
            print(e)
            print('Data saving failed.')

    else:

        # set the location of the case path
        case_path = "/data/HeadCell/case_local/"
        source_path = "/data/HeadCell/source/."

        source_file = 'run_case.py'

        # remove the current case path and create a new case path
        subprocess.call(['rm', '-r', current + case_path])
        subprocess.call(['mkdir','-p', current + case_path])

        # get the lower and upper bounds
        lb, ub = prob.get_decision_boundary()

        print("lb, ub", lb, ub)

        # number of dimensions and samples
        n_dim = 5
        n_samples = 11*n_dim -1

        # read decision vector and write to checkMesh.npz file
        print('Writing empty constraints.npz file...')

        # gap and checkMesh is null
        initial_X = []
        initial_H = []
        initial_C = []

        file_constraints = 'constraints.npz'

        subprocess.call(['rm', '-r', current + '/' + file_constraints])

        # initial_X is decision vector
        # initial_H is gap constraint
        # initial_C is checkMesh

        try:
            np.savez(current + '/' + file_constraints, initial_X, initial_H, initial_C)
            print('Data saved in file: ', file_constraints)
        except Exception as e:
            print(e)
            print('Data saving failed.')

        # take samples for the decision vector, either manual or latin hypercube
        if sampling == 'manual':
            print("initialisation(): number of manual samples", str(9))

            # 3 deliberate passes:
            one = np.array([0.5, 0.5, 10.0, 4.0, 4.0]) # 5,145,018 cells, 906 severly orthoginal faces, passes checkMesh Should result in H=3.02 inches
            two = np.array([1.0, 1.0, 20.0, 4.0, 5.0]) # 5,095,425 cells, 1087 severly orthoginal faces, passes checkMesh Should result in H=2.85 inches
            three = np.array([1.5, 1.5, 30.0, 4.0, 6.0]) # 4,993,048 cells, 1331 severly orthoginal faces, passes checkMesh Should result in H=2.67 inches

            # 3 deliberate failures
            four = np.array([4.0, 4.0, 10.0, 8.0, 6.0]) # Should result in H=1.51 inches
            five = np.array([4.0, -4.0, 30.0, 8.0, 4.0]) # Should result in H=1.62 inches
            six = np.array([4.0, -4.0, 45.0, 8.0, 4.0]) # Should result in H=1.76 inches

            # Mix of success and failure
            seven = np.array([1.0, 1.0, 10.0, 4.0, 5.0]) # Should result in H=2.83 inches
            eight = np.array([1.5, 1.5, 10.0, 4.0, 6.0]) # Should result in H=2.61 inches
            nine = np.array([1.0, 1.0, 30.0, 4.0, 5.0]) # Should result in H=2.88 inches

            all_samples = np.array([one, two, three, four, five, six, seven, eight, nine])

            samples = []

            for x in all_samples:
                constraint_success = gap_and_checkMesh_constraint(x, layout)
                if constraint_success == True:
                    samples.append(x)
        else:
            print("initialisation(): number of Latin Hypercube samples", str(n_samples))
            samples = lhs_initial_samples(n_dim, ub, lb, n_samples, cfunc=gap_and_checkMesh_constraint, cargs=(layout,), ckwargs={})

        # create filedirs
        filedirs = []

        # loop through the list to create directories:
        for s in samples:

            # create a working directory from the sample:
            dir_name = "_"
            for j in range(len(s)):
                dir_name += "{0:.4f}_".format(s[j])

            # replace any directories containing []
            dir_name = dir_name.replace("[","")
            dir_name = dir_name.replace("]","")

            # add the name to a list of directories
            filedirs.append(current + case_path + dir_name)

            # create the directory from the last in the list and
            subprocess.call(['mkdir', filedirs[-1] + '/'])

            # copy all source files into the newly created directory
            subprocess.call(['cp', '-r', current + source_path, filedirs[-1]])

            # copy run_case.py to that directory
            subprocess.call(['cp', '-r', current + '/' + source_file, filedirs[-1] + '/'])

            # write the decision vector to a file
            with open(filedirs[-1] + "/decision_vector.txt", "a") as myfile:
                for i in range(0,len(s)):
                    myfile.write(str(s[i])+ '\n')
            print("initialisation(): written decision vector to a file")

        # read decision vector and write to npz file
        print('Writing empty initial_samples.npz file...')

        # hyper volume improvement is null
        hpv = []
        initial_time = 0
        initial_X = []
        initial_Y = []
        initial_convergence = []

        # the name of the sim_file is initial_samples.npz
        sim_file = 'initial_samples.npz'

        # remove npz file if it exists
        subprocess.call(['rm', '-r', current + '/' + sim_file])

        # initial_X is decision vector
        # initial_Y is 2 objectives
        # hpv is hypervolume improvement
        # initial_time is zero
        # initial_convergence is convergence failure
        try:
            np.savez(current + '/' + sim_file, initial_X, initial_Y, hpv, initial_time, initial_convergence)
            print('Data saved in file: ', sim_file)
        except Exception as e:
            print(e)
            print('Data saving failed.')

    # decide environment and adjust bash script for running.
    if ((environment == 'isca') or (environment == 'isca_test')):
        # if the environment is isca
        for d in range(len(filedirs)):

            # copy the bash run script to the run directory
            subprocess.call(['cp', current + '/' + bash, filedirs[d] + '/'])

            # open the bash script for running
            with open(filedirs[d] + '/' + bash, 'r') as f:
                data = f.readlines()

            # change the line to the correct directory
            for line in range(len(data)):
                if '#PBS -d' in data[line]:
                    data[line] = '#PBS -d '+ filedirs[d]+'/' + '\n'

            #write the lines to the file
            with open(filedirs[d] + '/' + bash, 'w') as f:
                f.writelines(data)

    elif ((environment == 'isambard') or (environment == 'isambard_test')):
        # if the environment is isambard
        for d in range(len(filedirs)):

            # copy the bash run script to the run directory
            subprocess.call(['cp', current + '/' + bash, filedirs[d] + '/'])

            # open the bash script for running
            with open(filedirs[d] + '/' + bash, 'r') as f:
                data = f.readlines()

            # change the line to the correct directory
            for line in range(len(data)):
                if '#PBS -d' in data[line]:
                    data[line] = '#PBS -d '+ filedirs[d]+'/' + '\n'

            #write the lines to the file
            with open(filedirs[d] + '/' + bash, 'w') as f:
                f.writelines(data)

    else:
        # if the environment is local:
        for d in range(len(filedirs)):
            # copy the bash script to the local directory
            subprocess.call(['cp', current + '/' + bash, filedirs[d] + '/'])

    print('Total number of simulations, ', len(filedirs))
    print('All directories created.')

    return filedirs

def transform_sequence(n, lb=0, ub=185, scale=0.01, lw=0.25, uw=0.75):
    np = (n/ub * (ub -lb)) - ((ub -lb)/2)
    nub = (ub -lb)/2
    nlb = -(ub-lb)/2
    w = (ERF(scale*np) - ERF(scale*nlb))/(ERF(scale*nub) - ERF(scale*nlb))
    w = (w * (uw - lw)) + lw
    return w

def expected_improvement_weighting(self, x, obj_sense=1, lb=None, ub=None, weight=None, n=None,\
                            cfunc=None, cargs=(), ckwargs={}):
    """Calculate the expected improvement at a given set of input parameters,
    based on the trained model. See the following for details.
    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.139.9315&rep=rep1&type=pdf (maximisation)
    http://www.schonlau.net/publication/_96jsm_global_optimization.pdf (minimisation)

    Parameters.
    -----------
    x: a set of input parameters.
    obj_sense: whether to maximise or minimise. Key for the input:
                 1: maximise
                -1: minimise (default)
    Returns the expected improvement value at x.
    """
    #print(x, x.shape)
    if len(x.shape) < 2:
        x = np.array(x)
        x = x[:, np.newaxis].T
    if lb is not None:
        #print(x, lb, ub)
        xp = np.clip(x.copy(), lb, ub)
        rows = x.shape[0]
        e = np.ones(rows)
        e_inds = [i for i in range(xp.shape[0]) \
            if np.any(np.all(np.abs(xp[i] - self.X) <= 1e-9, axis=1))]
        if len(e_inds) == rows:
            return e[:, np.newaxis].T
    c_inds = []
    if cfunc is not None:
        #print('==========')
        #print('xp: ', xp)
        if xp.shape[0] == 1:
            #print(cfunc(None, xp[0], *cargs, **ckwargs))
            if not cfunc(xp[0], *cargs, **ckwargs):
                #print('Infeasible solution.')
                return np.zeros((1,1))
        else:
            #print('------')
            #for i in xp:
            #    print(cfunc(None, i, *cargs, *ckwargs))
            #c_inds = np.array([i for i in range(xp.shape[0]) if not cfunc(xp[i], *cargs, **ckwargs)])
            xp = np.array([i for i in xp if cfunc(i, *cargs, **ckwargs)])

    y, std_dev = self.predict(xp)
    epsilon = 0
    if n is not None:
        weight = transform_sequence(n)
    f_best = obj_sense * np.max(obj_sense * self.Y) + (obj_sense * epsilon)
    u =  obj_sense * (y - f_best) / std_dev
    # normal cumulative distribution function
    PHI = (0.5 * ERF(u/np.sqrt(2.0)))+0.5
    # normal density function
    phi = 1/np.sqrt(2.0*np.pi)*np.exp(-u**2/2.0)
    if weight is None:
        a =  std_dev * ((u * PHI) + (phi))
    else:
        a =  std_dev * ((weight * u * PHI) + ((1 - weight) * phi))
    a[e_inds] = 0
    #a[c_inds] = 0
    #print(a.shape)
    return a

def expected_improvement(self, x, obj_sense=1, lb=None, ub=None,\
                            cfunc=None, cargs=(), ckwargs={}):
    """
    Calculate the expected improvement at a given set of decision vectors,
    based on the trained model. See the paper for details.

    Parameters.
    -----------
    x (np.array): a set of decision vectors.
    obj_sense (int): whether to maximise or minimise. Key for the input:
                 1: maximise
                -1: minimise (default)
    lb (np.array): lower bound for the decision space.
    ub (np.array): upper cound for the decision space.
    cfunc (function): cheap constraint fucntion.
    cargs (tuple): arguments for the constraint function.
    ckwargs (dict): keyword arguments for the constraint function.

    Returns the expected improvement values at x.
    """
    if len(x.shape) < 2:
        x = np.array(x)
        x = x[:, np.newaxis].T
    if lb is not None:
        xp = np.clip(x.copy(), lb, ub)
        rows = x.shape[0]
        b_inds = [i for i in range(rows) if not np.all(xp[i]==x[i])]
        if len(b_inds) == rows: # outside boundary = zero exp. imp.
            return np.zeros((rows, 1))
        e_inds = [i for i in range(x.shape[0]) \
            if np.any(np.all(np.abs(x[i] - self.X) <= 1e-9, axis=1))]
        if len(e_inds) == rows: # violates xtol = zero exp. imp.
            return np.zeros((rows, 1))
    if cfunc is not None:
        c_inds = []
        if xp.shape[0] == 1:
            if not cfunc(xp[0], *cargs, **ckwargs):
                return np.zeros((1,1))
        else:
            c_inds = [i for i in range(xp.shape[0]) if not cfunc(xp[i], *cargs, **ckwargs)]
            if len(c_inds) == rows:
                return np.zeros((rows, 1))
    y, std_dev = self.predict(xp)
    f_best = obj_sense * np.max(obj_sense * self.Y)
    u =  obj_sense * (y - f_best) / std_dev
    sinds = [i for i in range(std_dev.shape[0]) if std_dev[i] == 0] # to get rid of NaN issues
    u[sinds] = 1e30
    # normal cumulative distribution function
    PHI = (0.5 * ERF(u/np.sqrt(2.0)))+0.5
    # normal density function
    phi = 1/np.sqrt(2.0*np.pi)*np.exp(-u**2/2.0)
    ei =  std_dev * ((u * PHI) + (phi))
    ei[sinds] = 0
    if lb is not None:
        ei[e_inds] = 0
        ei[b_inds] = 0
    if cfunc is not None:
        ei[c_inds] = 0
    return ei

def Forrester_BO_Function(x):

#    if (x > 1.3999):
#        return 100000
#    elif (x < 0.3001):
#        return 100000
#    elif ((x > 0.76) and (x < 0.77)):
#        return 100000
#    else:
    return (6*x - 2)**2 * np.sin(12*x - 4)

if __name__ == '__main__':

    current = os.getcwd()

    if (sampling == 'latin_forrester'):

        start_sim = time.time()
        print('Forrester run.' + ' in ' + current)
        subprocess.call(['rm', '-r', current + '/data/Forrester/case_local/'])
        subprocess.call(['mkdir', '-p', current + '/data/Forrester/case_local/'])
        print("main: removed old case, copied new case")

    else:

        start_sim = time.time()
        print('Demo run for Hydro case.')

        seed = 1005
        np.random.seed(seed)
        prob = HeadCell({})

        # sets values and removes olds case directory
        subprocess.call(['rm', '-r', prob.case_path])
        subprocess.call(['rm', '-r', prob.mesh_path])
        subprocess.call(['cp', '-r', prob.source_case, prob.case_path])
        print("main: removed old case, copied new case")
        subprocess.call(['mkdir', prob.mesh_path])

        # get upper and lower bounds:
        lb, ub = prob.get_decision_boundary()
        print("lb", lb)
        print("ub", ub)

        sim_id = 20191002
        init_file_name = None
        n_samples = 10              # (11n - 1)
        budget = 90                 # (11n - 1) + (2/3)(11n-1)

        layout = Ellipse(lb, ub)

    #initialisation()
    #no_queue()

    freeze_support()
    queue()
    print("Number of simultaneous runs, ", no_of_nodes)
    print("Time taken (seconds), ", (time.time()-start_sim))

    # Serial optimiser
    start = time.time()
    n_obj = 1
    n_dim = 1
    n_samples = 5
    budget = n_samples + 3
    lb = 0.3
    ub = 1.4
    res = IscaOpt.Optimiser.EMO(Forrester_BO_Function, \
                                settings={'n_dim':n_dim, \
                                'obj_sense':[-1]*n_obj, \
                                'n_obj':n_obj, \
                                'method_name':'EGO', \
                                'lb':np.array([lb]), \
                                'ub':np.array([ub]), \
                                'n_samples':n_samples, \
                                'budget':budget, \
                                'visualise':True, \
                                'multisurrogate':False, \
                                'init_file':current + '/initial_samples.npz'})

    print('Objective function value:', res)
    print('Optimiser Time taken:', time.time()-start, ' seconds.')


import sys
import os
import argparse

from spinalcordtoolbox.utils import Metavar, SmartFormatter, init_sct, display_viewer_syntax, printv
from spinalcordtoolbox.image import Image
from spinalcordtoolbox.qmri.mt import compute_mtr

def get_parser():
    parser = argparse.ArgumentParser(
        description='Compute magnetization transfer ratio (MTR). Output is given in percentage.',
        add_help=None,
        formatter_class=SmartFormatter,
        prog=os.path.basename(__file__).strip(".py"))

    mandatoryArguments = parser.add_argument_group("\nMANDATORY ARGUMENTS")
    mandatoryArguments.add_argument(
        '-mt0',
        required=True,
        help='Image without MT pulse (MT0)',
        metavar=Metavar.float,
    )
    mandatoryArguments.add_argument(
        '-mt1',
        required=True,
        help='Image with MT pulse (MT1)',
        metavar=Metavar.float,
    )

    optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS")
    optional.add_argument(
        "-thr",
        type=float,
        help="Threshold to clip MTR output values in case of division by small number. This implies that the output image"
             "range will be [-thr, +thr]. Default: 100.",
        default=100
    )
    optional.add_argument(
        "-h",
        "--help",
        action="help",
        help="Show this help message and exit"
    )
    optional.add_argument(
        '-v',
        type=int,
        choices=(0, 1, 2),
        help='Verbose: 0 = nothing, 1 = classic, 2 = expended',
        default=1
    )
    optional.add_argument(
        '-o',
        help='Path to output file.',
        metavar=Metavar.str,
        default=os.path.join('.', 'mtr.nii.gz')
    )
    return parser

def main():
    # Check input parameters
    parser = get_parser()
    args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])
    fname_mtr = args.o
    verbose = args.v

    # compute MTR
    printv('\nCompute MTR...', verbose)
    nii_mtr = compute_mtr(nii_mt1=Image(args.mt1), nii_mt0=Image(args.mt0), threshold_mtr=args.thr)

    # save MTR file
    nii_mtr.save(fname_mtr, dtype='float32')

    display_viewer_syntax([args.mt0, args.mt1, fname_mtr])

if __name__ == "__main__":
    init_sct()
    main()


from __future__ import print_function

import sys
from operator import add

from pyspark import SparkContext

def splitWith(rowString, rowIndex):
    colValue = list(map(int, rowString.split(',')))
    retValue = []

    for colIndex,item in enumerate(colValue):
        retValue.append((colIndex,(rowIndex,item)))

    return retValue

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: matrixVectorMultiply <file>", file=sys.stderr)
        exit(-1)
    sc = SparkContext(appName="matrixVectorMultiply")
    inputFile = sc.textFile(sys.argv[1], 1)
    rowCount,columnCount = map(int,inputFile.first().split(','))
    inputFileWithIndex = inputFile.zipWithIndex()
    matrixInput = inputFileWithIndex.filter(lambda x : x[1] > 0 and x[1] <= rowCount)
    vectorInput = inputFileWithIndex.filter(lambda x : x[1] > rowCount)
    colIndexedVector = vectorInput.map(lambda x : (x[1] - rowCount -1,int(x[0])))
    colIndexedMatrix = matrixInput.flatMap(lambda x: splitWith(x[0],x[1]-1))
    rowIndexedSum = colIndexedMatrix.join(colIndexedVector).map(lambda x: (x[1][0][0], x[1][0][1] * x[1][1])).reduceByKey(add)
    output = rowIndexedSum.sortByKey().map(lambda x: x[1]).collect()
    with open('output.txt', 'w') as outputFile:
        for item in output:
            outputFile.write("{0}\n".format(item))

    sc.stop()


from pathlib import Path
import string

data_folder = Path(".").resolve()
type_to_priority = dict(zip(string.ascii_letters, range(1, 53)))

def parse_data(data):
    rucksacks = [[type_to_priority[l] for l in line] for line in data.split("\n")]
    return rucksacks

def find_common_type(rucksack):
    comp_size = len(rucksack) // 2
    common = list(set.intersection(set(rucksack[:comp_size]), set(rucksack[comp_size:])))[0]
    return common

def sum_elf_group_priorities(rucksacks):
    n_rucksacks = len(rucksacks)
    group_size = 3
    badge_priorities = []
    for group_id in range(0, n_rucksacks, group_size):
        group = [set(rucksack) for rucksack in rucksacks[group_id : group_id + group_size]]
        common = list(set.intersection(*group))[0]
        badge_priorities.append(common)
    return sum(badge_priorities)

def main():
    data = data_folder.joinpath("input.txt").read_text()
    rucksacks = parse_data(data)

    print("Part 1")
    priorities_sum = sum([find_common_type(rucksack) for rucksack in rucksacks])
    print(f"The sum of priorities of the common item types in both compartments is {priorities_sum}")

    print("Part 2")
    priorities_sum = sum_elf_group_priorities(rucksacks)
    print(f"The sum of priorities of the common item types for each elf group is {priorities_sum}")

if __name__ == "__main__":
    main()


import io
from pathlib import Path

import flask
import numpy as np
import pandas as pd

from .utils import list_dir
from .model import define_model

class ServeConfig:
    OPT_ML_DIR = Path("/opt/ml")
    MODELS_DIR = OPT_ML_DIR / "models"

    ASSETS_PATH = Path("./assets")
    ASSETS_PATH.mkdir(parents=True, exist_ok=True)
    AUDIO_PATH = ASSETS_PATH / "audio"
    AUDIO_PATH.mkdir(parents=True, exist_ok=True)
    META_PATH = ASSETS_PATH / "metadata"
    META_PATH.mkdir(parents=True, exist_ok=True)

class ScoringService(object):
    """
    A singleton for holding the model. This simply loads the model and holds it.
    It has a predict function that does a prediction based on the model and the input data.
    """

    models = None  # Where we keep the model when it's loaded

    @classmethod
    def get_model(cls):
        """Get the model object for this instance, loading it if it's not already loaded."""
        if cls.models == None:
            models = []
            model_list = list_dir(ServeConfig.MODELS_DIR)
            for name in model_list:
                cnn = define_model()
                cnn.load_weights(str(ServeConfig.IN_MODELS_DIR / name))
                models.append(cnn)
            cls.models = models
        return cls.models

    @classmethod
    def predict(cls, input: pd.DataFrame):
        """For the input, do the predictions and return them.

        Args:
            input (a pandas dataframe): The data on which to do the predictions. There will be
                one prediction per row in the dataframe"""
        models = cls.get_model()
        res = np.zeros(input.shape[0], dtype=float)
        input_features = input.values
        for model in models:
            res += model.predict(input_features)

        output = res / len(models)
        return output

app = flask.Flask(__name__)

@app.route("/ping", methods=["GET"])
def ping():
    """Determine if the container is working and healthy. In this sample container, we declare
    it healthy if we can load the model successfully."""
    health = ScoringService.get_model() is not None

    status = 200 if health else 404
    return flask.Response(response="\n", status=status, mimetype="application/json")

@app.route("/invocations", methods=["POST"])
def invocations():
    data = None

    # Convert from CSV to pandas
    if flask.request.content_type == "text/csv":
        data = flask.request.data.decode("utf-8")
        s = io.StringIO(data)
        data = pd.read_csv(s, header=None)
    else:
        return flask.Response(
            response="This predictor only supports CSV data",
            status=415,
            mimetype="text/plain",
        )

    print("Invoked with {} records".format(data.shape[0]))

    # Do the prediction
    predictions = ScoringService.predict(data)

    # Convert from numpy back to CSV
    out = io.StringIO()
    pd.DataFrame({"results": predictions}).to_csv(
        out, header=False, index=False)
    result = out.getvalue()

    return flask.Response(response=result, status=200, mimetype="text/csv")


from const import *
import sys
from datetime import datetime
import numpy as np
import cv2
import os
from time import sleep
from threading import *
from utils import *

def removeTxt(txtBuffer):
    import os
    txtFileList = os.listdir(txtBuffer)
    for item in txtFileList:
        if item.endswith(".txt"):
            os.remove(os.path.join(txtBuffer, item))

def storeTxtToJpg(TXT_PATH,IMAGE_PATH,label,mode="dataCollection"):
    """
    TXT_PATH: folder name of the txt files
    IMAGE_PATH: destinated image folder to save, DO NOT include filename like .jpg
    mode: 'dataCollection' or 'prediction'

    """
    def arrayFromFile(file_name):
        arr=[]
        status=-1
        try:
            with open(file_name,'r') as f:
                for line in f.readlines(): #line is a string
                    line_arr=[float(x) for x in line.split(",")]
                    arr.append(line_arr)
            arr=np.array(arr)
            status=True
        except:
            status=False
        return arr, status
    def isEmptyTxt(file_name):
        return os.stat(f"{file_name}").st_size == 0
    def currentTimeInfo():
        return datetime.now().strftime("%Y%m%d_%H%M%S")
    #convert all txt files from {TXT_PATH} into jpg images and store them in {IMAGE_PATH}
    #1. list all files name with txt extension
    if mode=="dataCollection":
        destination_folder= os.path.join(IMAGE_PATH,f"{label}")
        for file in os.listdir(TXT_PATH):
            if file.endswith(".txt"):
                file_name=os.path.join(TXT_PATH,file)
                if not isEmptyTxt(file_name):
                    print(file_name)
                    img_array,result=arrayFromFile(file_name)
                    if (result==False or result==-1):
                        continue
                    if (result==-1):
                        raise Exception("error occur in arrayFromFile()")
                    sleep(1)

                    #cv2.imwrite(img_)
                    #path=os.path.join("images","your_file.jpg")
                    output_path=os.path.join(destination_folder,currentTimeInfo()+".jpg")
                    print(f"output_path={output_path}")
                    cv2.imwrite(output_path,img_array)
                    #print("complete image writing")
    elif mode=="prediction":
        destination_folder= os.path.join(IMAGE_PATH,f"{label}")
        for file in os.listdir(TXT_PATH):
            if file.endswith(".txt"):
                file_name=os.path.join(TXT_PATH,file)
                if not isEmptyTxt(file_name):
                    print(file_name)
                    img_array=arrayFromFile(file_name)
                    sleep(1)

                    #cv2.imwrite(img_)
                    #path=os.path.join("images","your_file.jpg")
                    output_path=os.path.join(destination_folder,"0.jpg")
                    print(f"output_path={output_path}")
                    cv2.imwrite(output_path,img_array)
                    print("complete image writing")
    else:
        raise Exception("INVALID MODE IN storeTxtToJpg()")
        quit()
def moveToBuffer(FromPath,ToPath):
    print("moving files from txtStorage to txtBuffer")
    source = FromPath
    destination = ToPath

    # gather all files
    allfiles = os.listdir(source)

    # iterate on all files to move them to destination folder
    for f in allfiles:
        src_path = os.path.join(source, f)
        dst_path = os.path.join(destination, f)
        os.rename(src_path, dst_path)

if __name__=='__main__':

    if len(sys.argv)!=3:#test 0
        raise Exception("""MISSING ARGUMENT(S)!!!
        python3 txtToJpg.py [train/test] [label]
        """)
        print("QUITTED")
        quit()
    if not (sys.argv[1]=='test' or sys.argv[1]=='train'):
        print("NO SUCH MODE, PLEASE ENTER test or train as mode")
        print("QUIT")
        quit()

    jsonAccesser=ConfJsonDictAccesser()
    conf_json_dict=jsonAccesser.get_dict()
    modelDataType=conf_json_dict["modelDataType"]

    if sys.argv[1]=='test':
        if modelDataType==jsonAccesser.DataLengthType.fix:
            path=FIXED_LENGTH_TEST_PATH
        elif modelDataType==jsonAccesser.DataLengthType.unfix:
            path=VARIED_LENGTH_TEST_PATH
    elif sys.argv[1]=='train':
        if modelDataType==jsonAccesser.DataLengthType.fix:
            path=FIXED_LENGTH_TRAIN_PATH
        elif modelDataType==jsonAccesser.DataLengthType.unfix:
            path=VARIED_LENGTH_TRAIN_PATH

    moveToBuffer(TXT_PATH,TXT_BUFFER)
    storeTxtToJpg(TXT_BUFFER,path,sys.argv[2])
    removeTxt(TXT_BUFFER)


# 풀이 참조

from sys import *

input = stdin.readline
from collections import *

def bfs(x, y):
    q = deque()
    q.append((x, y))
    visit[x][y] = 1
    while q:
        x, y = q.popleft()
        for dx, dy in [(-1, 0), (0, 1), (1, 0), (0, -1)]:
            nx, ny = x + dx, y + dy
            if nx < 0 or ny < 0 or nx > n - 1 or ny > m - 1 or visit[nx][ny] != -1: continue
            if arr[nx][ny] <= 0:
                arr[x][y] -= 1
            else:
                visit[nx][ny] = 1
                q.append((nx, ny))

n, m = map(int, input().split())
arr = []
for i in range(n):
    arr.append(list(map(int, input().split())))
cnt = 0
while 1:
    f = 0
    visit = [[-1] * m for _ in range(n)]
    for i in range(n):
        for j in range(m):
            if arr[i][j] > 0 and visit[i][j] == -1:
                bfs(i, j)
                f += 1
    if f == 0:
        print(0)
        break
    elif f >= 2:
        print(cnt)
        break
    cnt += 1


import collections
import math
from collections import deque

class Graph:
    def __init__(self):
        self.vertices = set()
        # makes the default value for all vertices an empty list
        self.edges = collections.defaultdict(list)
        self.weights = {}

    def add_vertex(self, value):
        self.vertices.add(value)

    def add_edge(self, from_vertex, to_vertex, distance):
        if from_vertex == to_vertex: pass
        self.edges[from_vertex].append(to_vertex)
        self.weights[(from_vertex, to_vertex)] = distance

    def __str__(self):
        string = "Vertices: " + str(self.vertices) + "\n"
        string += "Edges: " + str(self.edges) + "\n"
        string += "Weights: " + str(self.weights)
        return string

def dijkstra(graph, start):
    # initializations
    S = set()

    # lenght_of_shortest_path represents the length shortest distance paths from start to edge, for edge in lenght_of_shortest_path.
    #initialize every vertex with path of infinity
    lenght_of_shortest_path = dict.fromkeys(list(graph.vertices), math.inf)
    previous = dict.fromkeys(list(graph.vertices), None)

    # then we set the path length of the start vertex to 0
    lenght_of_shortest_path[start] = 0

    # while there exists a vertex v not in S
    while S != graph.vertices:
        # let v be the closest vertex that has not been visited,it will be 'start'
        v = min((set(lenght_of_shortest_path.keys()) - S), key=lenght_of_shortest_path.get)

        # for each neighbor of v not in S
        for neighbor in set(graph.edges[v]) - S:
            new_path = lenght_of_shortest_path[v] + graph.weights[v, neighbor]

            # check new path length with current
            if new_path < lenght_of_shortest_path[neighbor]:
                # since it's optimal, update the shortest path for neighbor
                lenght_of_shortest_path[neighbor] = new_path

                # set the previous vertex of neighbor to v
                previous[neighbor] = v

        S.add(v)

    return lenght_of_shortest_path, previous

def shortest_path(graph, start, end):
    visited, paths = dijkstra(graph, start)
    full_path = deque()
    _destination = paths[end]

    #while end point is not start point append destination to path
    while _destination != start:
        full_path.appendleft(_destination)
        _destination = paths[_destination]

    full_path.appendleft(start)
    full_path.append(end)

    #return shortest way
    return visited[end], list(full_path)

if __name__ == '__main__':

    graph = Graph()
    with open('input.txt') as read_file:
        n = int(read_file.readline())
        for i in range(n):
            node_list = read_file.readline().split()
            graph.add_vertex(node_list[0])
            graph.add_vertex(node_list[1])
            graph.add_edge(node_list[0], node_list[1], int(node_list[2]))
        points = read_file.readline().split()
        start_point = points[0]
        end_point = points[1]
        print( shortest_path(graph, start_point, end_point))