#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 14 10:09:38 2018

@author: pc

"""

#!/usr/bin/env python
# coding: utf-8

'''
**********************************************************************************************************************************************************************************
**********************************************************************************************************************************************************************************

Game Name : 5Ws of Wizarding World !

**********************************************************************************************************************************************************************************
“ “ “

DocString:

A)	INTRODUCTION

        A very warm welcome to you in Hogwarts – School of Witchcraft and Wizardy!

        It is my pleasure to have you as our student with us. I am Professor Dumbledore, your headmaster.

        I hope you have already visited Diagon Alley to get :

            1.	Magic Wand :
                If you do not have this, please grab a nearby pen or chopstick NOW to mimic the wand. Swing / Swish the wand 3 times to test if the spells work.

            2.	Textbooks :
                Required for classes in “Potions” and “Defense Against the Dark Arts”

            3.	Marauder’s Map:
                Tracking of all Hogwarts people and properties

        In order to be assigned to your Hogwarts house – Gryffindor/Ravenclaw/Hufflepuff/Slytherin , you need to play the orientation game which has 3 stages.

            1. Magical Powers
            2. Wizard Training
            3. How good a wizard am I?

        Off you go now!

“ “ “
**********************************************************************************************************************************************************************************
'''

import numpy as np

from PIL import Image, ImageFilter

import colorama
from colorama import Fore

import random

import os
import glob

import time

# start game

def start_game():
#     """ To start game. """
    key = ''
    while(key.lower() != 's'):
        key = input(">Press 's' to begin...")
    return True

def get_integer_input(question):
# """ To convert input into integer """
    while True:
        try:
            integer_input = int(input (question))
            return integer_input
        except:
            print ("ERROR - Please enter a valid integer value!")

# Pre-Orientation

# Make sure student has the magic wand.

def wand_available(name) :
#     """ Check if student has the magic wand """

    print ('\n\n\n{}, do you have your magic wand?'.format(name))
    while True :
        wand_available = input('> Please input Y or N:  ').upper()

        if wand_available == 'Y':
            print ('\nGreat! You are ready to proceed...')
            break
        elif wand_available == 'N':
            print ('\nThis is not a good start {}, you are not following instructions. Please get a wand – either a pen or a chopstick equivalent. If not, you will have 1 detention class next week in the Dungeons.'.format(name))
            break
        else:
            print( ' ERROR. Please input Y or N.')
#     input('<Press Enter>')

# Make sure student has some background on the Harry Potter series.

def HP_knowledge(name):
#     """ Check how much knowledge student has about the Harry Potter series. """

    print('\nMoving forward, on a scale of 1 to 5, how much do you know about the Harry Potter series?')
#     HP_know = int(input (' > Please enter answer on scale of 1 (smallest) to 5 (biggest): \n'))

    while True:
        HP_know = get_integer_input(' > Please enter answer on scale of 1 (smallest) to 5 (biggest): \n')
        if HP_know in [1,2,3] :
            print ( '\nSince you are new , here is some additional information  to prepare you for the tasks ahead: ')
            time.sleep(2)
            print ('*' * 50)
            print ('\n*Hogwarts is a school that students attend to learn magic! \n\n*Good guys: Most Hogwarts students and professors. Specifically, Harry Potter and his good friends Hermoine and Ron. \n\n*Bad guys: Voldemort, who is a serial killer, and his supporters.')
            print ('*' * 50)
            time.sleep(2)
            break
        elif HP_know in [4,5] :
            print ('*' * 50)
            print ('\nSince you are familiar, no additional information for you. Proceed on.')
            time.sleep(2)
            break

    input ('< Press Enter to Continue: >')
    print ('\nNow that you are all set {}, your magical journey of 3 stages begins! Swing your wand 3 times for the good luck spell "JiaYou!".'.format(name))
    print (' \n\t*1. Magical Powers \n\t*2. Wizard Training \n\t*3. How good a wizard am I?')
    input ('< Press Enter to Continue: >')

### Stage 1 - Magical Powers

def get_input_option(black_lake):
#     """ Get input from student on the move he/she would like to make .  """

    if 'hagrid' in black_lake[0]:
        departing, arriving = black_lake[0], black_lake[1]
    else:
        departing, arriving = black_lake[1], black_lake[0]

    while True:
        option = input (">Your option to move a creature or Hagrid : ")
        print('\n\n')
        if option.lower() in departing:
            return option
        elif option.lower() in arriving:
            print ('\nOnly Hagrid can move the creature! Move either Hagrid or a creature from another side')
        else:
            print ('\nPlease enter valid option from {}'.format(departing))

def print_black_lake_layout(black_lake):
#      """ Printing the layout. """

    left_side, right_side = black_lake
    if len(left_side)==0:
        left_side = '{}'
    if len(right_side)==0:
        right_side = '{}'
    print ('\n{}    | BLACK LAKE |    {}'.format(left_side, right_side))

def check_safe(black_lake, departing):
#      """ Safety check of all creatures. """

    if 'dragon' in departing and 'tarantula' in departing:
        print_black_lake_layout(black_lake)
        print ('\n\n\nOops... Dragon ate Tarantula... Yum! Yum! ... You lost but will allow you to proceed to next stage')
        return False
    if 'tarantula' in departing and 'owl' in departing:
        print_black_lake_layout(black_lake)
        print ('\n\n\nOops... Tarantula ate Owl... Yum! Yum! ... You lost but will allow you to proceed to next stage')
        return False
    return True

def cross(black_lake):
#      """ Hagrid's movements. """

    if 'hagrid' in black_lake[0]:
        departing, arriving = black_lake[0], black_lake[1]
    else:
        departing, arriving = black_lake[1], black_lake[0]

    departing.remove('hagrid')
    arriving.add('hagrid')

    safe = check_safe(black_lake, departing)

    return black_lake, safe

def cross_n_move_creature(black_lake, creature):
#      """ Creature movements with Hagrid. """

    if 'hagrid' in black_lake[0]:
        departing, arriving = black_lake[0], black_lake[1]
    else:
        departing, arriving = black_lake[1], black_lake[0]

    departing.remove('hagrid')

    if creature in departing:
        departing.remove(creature)
        arriving.add(creature)

    arriving.add('hagrid')

    safe = check_safe(black_lake, departing)

    return black_lake, safe

def Magical_Powers (name) :
#      """ Student to solve this challenge. """
    print(Fore.MAGENTA + '\n\nLoading Stage 1: Magical Powers.......\n')
    print(Fore.BLACK)
    time.sleep(2)

    print('*'*50)
    print ('\nWelcome to Magical Powers, {}! \n'.format(name))
    print ('\nAim: To help Professor Hagrid safely get 3 creatures (Dragon, Tarantula, Owl) across the Black Lake.')
    print ('\nRules: \n\t- Professor Hagrid must be sailing the boat. \n\t- At any time, Professor Hagrid can only take one creature with him on the boat. \n\t- Not Safe: Dragon and Tarantula together as the dragon eats the tarantula. \n\t- Not Safe: Tarantula and Owl together as the tarantula eats the owl. \n\t- All creatures are safe when Professor Hagrid is present.\n')
    print('*'*50)
    input('<Press Enter to Continue>')
    print('\nWho would you put on the boat to cross the Black Lake? Select one creature or Hagrid. \n\n- Continue selecting one creature or Hagrid every time till all have safely crossed Black Lake. You have maximum 20 moves.\n\n')
    input('<Press Enter to Continue>')

    left_side = {'hagrid', 'dragon', 'tarantula', 'owl'}
    right_side = set([])
    black_lake = (left_side, right_side)

    count = 0

    while True:
        if count > 20:
            print ('\nYou took too long. The creatures have escaped ...')

        if len(black_lake[1]) == 4:
            print ('\n Congrats! Hagrid is very pleased with your help :) ')
            return True

        print_black_lake_layout(black_lake)
        time.sleep(1)

        option = get_input_option(black_lake).lower()

        if option == 'hagrid':
            black_lake, safe = cross(black_lake)
        else:
            black_lake, safe = cross_n_move_creature(black_lake, option)

        if not safe:
            return False

        count += 1

# Stage 2 - Wizard Training : 2 questions to test your magical knowledge.

def Wizard_Training_A (name) :
#     """ Student to solve 1 riddle"""
    print(Fore.MAGENTA + '\n\nLoading Stage 2A: Wizard Training A.......\n')
    print(Fore.BLACK)
    time.sleep(2)

    print('*'*50)
    print ('\nWelcome to Wizard Training A, {}! \n'.format(name))
    print ('\nAim: Solve a riddle.')
    print ('\nRules:\n\t- You have maximum 3 tries.')
    print('*'*50)
    input('<Press Enter to Continue>')
    #time.sleep(5)

    print ('\nQuestion : What boy wizard magically grew a beard each night?')

    count = 0

    while True:
        if count != 0 and count < 3:
            print ('\nSorry, that is not correct! Please try again.')

        if count == 3:
            print ('\nNope, that is not right! Oh No! Oops you used up all your 3 tries! Too bad. But you can get a secret entry to continue...')
            return False

        riddle_guess = input ('>Your answer : ')

        if riddle_guess.lower() == 'hairy potter' :
            print('\nCongratulations! That is correct! You have a great sense of humour - like me :) \n')
            return True

        count += 1

def Wizard_Training_B (name) :
#     """Student to solve another riddle"""
    print(Fore.MAGENTA + '\n\nLoading Stage 2B: Wizard Training B.......\n')
    print(Fore.BLACK)
    time.sleep(2)

    print('*'*50)
    print ('\nWelcome to Wizard Training B, {}! \n'.format(name))
    print ('\nAim: Identify what/who is shown in the image.')
    print ('\nRules:\n\t- You have maximum 3 tries.')
    print('*'*50)
    input('<Press Enter to Continue>')

    #time.sleep(5)

    print ('\nQuestion : Name one of the characters you see in the image below.')
    time.sleep(1)

    image = Image.open('./snape_sirius.jpg')
    display (image)

    count = 0

    while True:
        if count != 0 and count < 3:
            print ('\nSorry, that is not correct! Please try again. A hint is their names begin with the alphabet S.')

        if count == 3:
            print ('\nSorry :( \n\n\t\t\t ************* \n\t\t\t --GAME OVER-- \n\t\t\t ************* \n\nBased on your performance, you have been assigned to Slytherin house.\n\n\t\t\t*** Congratulations !!! *** \n\nLook forward to seeing you around in the Hogwarts castle, {}!'.format(name))
            return False

        riddle_guess = input ('>Your answer : ')

        if riddle_guess.lower() in ['snape' , 'sirius']:
            print('\nCongratulations! That is correct!')
            print ('\n\n\n\t\t\t ************* \n\t\t\t --GAME OVER-- \n\t\t\t ************* \n\nBased on your performance, you have been assigned to Ravenclaw house.\n\n\t\t\t*** Congratulations !!! *** \n\nLook forward to seeing you around in the Hogwarts castle, {}!'.format(name))
            return True

        count += 1

### Stage 3 - How Good A Wizard Am I ?

def build_ques_ans():
#     """ Game is in the form of Who Wants To Be A Millionare. One image question will be asked from a random list of images , with 4 random options. If student does not know the answer, he/she can use the 2 Lifelines available. """

    f_img = glob.glob('./options/*.jpg')
    f_img = [os.path.basename(x) for x in f_img]
    sel_img = random.choice(f_img)

    question = "Identify the character in this image: "
    correct_answer = [os.path.splitext(sel_img)[0]]

    f_img_n = [os.path.splitext(x)[0] for x in f_img if x is not sel_img]

    answer_options = correct_answer + random.sample(set(f_img_n), 3)

    return (question, answer_options, correct_answer[0])

def show_question(ques):
#     """ Prints question """

    print (ques)

def show_image(f_p, blur_factor):
#      """ Shows image with blur """

    basewidth = 320
    raw_image = Image.open(f_p)
    wpercent = (basewidth / float(raw_image.size[0]))
    hsize = int((float(raw_image.size[1]) * float(wpercent)))
    raw_image = raw_image.resize((basewidth, hsize), Image.ANTIALIAS)
    box = (15,15, 500, 500)
    ic = raw_image.crop(box)
    for i in range(blur_factor):  # with the BLUR filter, you can blur a few times to get the effect you're seeking
        ic = ic.filter(ImageFilter.BLUR)
        raw_image.paste(ic, box)

    display(raw_image)

def get_input_choice(possible_choices):
#      """ Get student input """

    while True:
        choice = input ('>\nEnter your choice: ')
        if choice in possible_choices:
            return choice
        print ('\nPlease enter a valid choice from  -->  {}'.format(possible_choices))

def show_options(choices, options, ll_choices, ll_options):
#      """ Showing all the options? """

    print ('\nOptions : \n')
    for i in range(len(choices)):
        print (choices[i] + ' :  ' + options[i])
    print ('\nLifelines Available : \n')
    for i in range(len(ll_choices)):
        print (ll_choices[i] + ': ' + ll_options[i])

    return (get_input_choice(choices + ll_choices))

def do_fi_fi(choices, options, ans):
#      """ Lifeline activated for 50-50. 2 wrong answers will be eliminated. """

    options_idx = [x for x in range(len(choices))]
    options_idx.remove(options.index(ans))
    fi_fi = sorted([options.index(ans), random.sample(set(options_idx),1)[0]])

    choices_fi_fi = [choices[idx] for idx in fi_fi]
    options_fi_fi = [options[idx] for idx in fi_fi]

    return (choices_fi_fi, options_fi_fi)

def play_Good_wizard(name):
#      """ How Good a WIzard am I?  """

    question, answer_options, correct_answer = build_ques_ans()
    choices = ['A', 'B', 'C', 'D']
    ll_choices = ['L1', 'L2']
    ll_options = ['50-50', 'de-blur']

    blur_factor = 100

    while True:
        print ('\n******************************\n')
        show_question(question)
        show_image('./options/'+correct_answer+'.jpg', blur_factor)
        in_choice = show_options(choices, answer_options, ll_choices, ll_options)

        if in_choice in choices:

            if in_choice != choices[answer_options.index(correct_answer)]:
                print ('\nWrong Answer :(')
                print ('\nSorry :( \n\n\t\t\t ************* \n\t\t\t --GAME OVER-- \n\t\t\t ************* \n\nBased on your performance, you have been assigned to Hufflepuff house.\n\n\t\t\t*** Congratulations !!! *** \n\nLook forward to seeing you around in the Hogwarts castle, {}!'.format(name))
                return False

            if in_choice == choices[answer_options.index(correct_answer)]:
                print ('\nGreat job!')
                print ('\n\n\n\t\t\t ************* \n\t\t\t --GAME OVER-- \n\t\t\t ************* \n\nBased on your performance, you have been assigned to Gryffindor house.\n\n\t\t\t*** Congratulations !!! *** \n\nLook forward to seeing you around in the Hogwarts castle, {}!'.format(name))
                return True

        if in_choice in ll_choices:
            ll = ll_choices.index(in_choice)
            del[ll_options[ll_choices.index(in_choice)]]
            ll_choices.remove(in_choice)

            if in_choice == 'L1':
                print ('\n50-50 lifeline activated... eliminating 2 wrong choices...\n')
                time.sleep(2)
                choices_fi_fi, options_fi_fi = do_fi_fi(choices, answer_options, correct_answer)
                choices = choices_fi_fi
                answer_options = options_fi_fi

            if in_choice == 'L2':
                print ('\nde-blur lifeline activated... de-blurring the image...\n')
                time.sleep(2)
                blur_factor = 2

def Good_wizard (name):
#      """ To start test on How Good a Wizard am I? """
    print(Fore.MAGENTA + '\n\nLoading Stage 3: How Good a wizard am I?.......\n')
    print(Fore.BLACK)
    time.sleep(2)

    print('*'*50)
    print (' \nWelcome to the test "How Good A Wizard am I?", {}! \n'.format(name))
    print ('\nAim: Identify the person shown in the image.')
    print ('\nRules:\n\t- You will be given 4 options to choose from. \n\t- If you are stuck, you have 2 lifelines. \n\t\t~ Lifeline 1: "50-50" : 2 of the wrong answers will be eliminated.\n\t\t~ Lifeline 2: Image will be de-blurred.\n')
    print('*'*50)
    input('<Press Enter to Continue>')

#    time.sleep(10)

    Good_wizard_result = play_Good_wizard(name)

def do_restart():
    while True:
        get_last_choice = get_integer_input('\n>Your choice 1 or 2: ')

        if get_last_choice == 1:
            return True

        if get_last_choice == 2 :
            return False

### Main Game Code

def PLAY_GAME():

    if (start_game()):
        print ("Starting game...")
        time.sleep(1)

        print (Fore.MAGENTA + '\nWelcome to Hogwarts! I hope you have a magical journey ahead!')
        print(Fore.BLACK)

        name = input('Please enter your name: ')
        print ('\nAs your headmaster, I need to do some pre-orientation checks.... :')
        wand_available (name)
        time.sleep(2)
        HP_knowledge (name)
        time.sleep(3)

        while True:
            Magical_Powers_result = Magical_Powers(name)   # stage 1
            time.sleep(1)
            if Magical_Powers_result :
                Good_wizard_result = Good_wizard (name)   # stage 3
                break
            else:
                Wizard_Training_A_result = Wizard_Training_A(name)   # stage 2a

                if Wizard_Training_A_result:
                    Good_wizard_result = Good_wizard (name)   # stage 3
                    break

                else:
                    print('\nYou have an option here. Do you want to: \n\n\t 1: Go back to Stage 1 - Magical Powers to try your luck again at getting Hagrid and his creatures across the Blake Lake? \n\n\t 2: Proceed to Training B? ')

                    restart = do_restart()
                    if restart:
                        print('You are going back to Magical Powers.')
                        time.sleep(.5)
                        continue
                    else:
                        print('You are proceeding to Wizard Training B.')
                        Wizard_Training_B (name)
                        break

PLAY_GAME()


#
# @lc app=leetcode.cn id=417 lang=python3
#
# [417] 太平洋大西洋水流问题
#
# https://leetcode-cn.com/problems/pacific-atlantic-water-flow/description/
#
# algorithms
# Medium (48.00%)
# Likes:    472
# Dislikes: 0
# Total Accepted:    61.2K
# Total Submissions: 111.7K
# Testcase Example:  '[[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]'
#
# 有一个 m × n 的矩形岛屿，与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界，而 “大西洋” 处于大陆的右边界和下边界。
#
# 这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights ， heights[r][c] 表示坐标 (r, c)
# 上单元格 高于海平面的高度 。
#
# 岛上雨水较多，如果相邻单元格的高度 小于或等于 当前单元格的高度，雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。
#
# 返回网格坐标 result 的 2D 列表 ，其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动
# 既可流向太平洋也可流向大西洋 。
#
#
#
# 示例 1：
#
#
#
#
# 输入: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
# 输出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
#
#
# 示例 2：
#
#
# 输入: heights = [[2,1],[1,2]]
# 输出: [[0,0],[0,1],[1,0],[1,1]]
#
#
#
#
# 提示：
#
#
# m == heights.length
# n == heights[r].length
# 1 <= m, n <= 200
# 0 <= heights[r][c] <= 10^5
#
#
#

# @lc code=start
class Solution:
    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
        n = len(heights)
        m = len(heights[0])
        stats = [[0 for _ in range(m)] for _ in range(n)]

        # 初始化临海点
        que = []
        que.append([0,m-1])
        stats[0][m-1] |= 3
        que.append([n-1,0])
        stats[n-1][0] |= 3
        for i in range(m-1):
            que.append([0,i])
            stats[0][i] |= 1
            que.append([n-1,i+1])
            stats[n-1][i+1] |= 2
        for i in range(n-1):
            que.append([i,0])
            stats[i][0] |= 1
            que.append([i+1,m-1])
            stats[i+1][m-1] |= 2
        # print(stats)
        # 广遍
        while len(que) != 0:
            l = len(que)
            nq = []
            for i in range(l):
                px = que[i][0]
                py = que[i][1]
                for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
                    x = px + dx
                    y = py + dy
                    if x >= 0 and x < n and y>= 0 and y < m and heights[x][y] >= heights[px][py]:
                        if stats[px][py] & 1 == 1 and stats[x][y] & 1 == 0:
                            stats[x][y] |= 1
                            nq.append([x, y])
                        if stats[px][py] & 2 == 2 and stats[x][y] & 2 == 0:
                            stats[x][y] |= 2
                            nq.append([x, y])
            que = nq
        # print(stats)
        res = []
        for i in range(n):
            for j in range(m):
                if stats[i][j] & 3 == 3:
                    res.append([i, j])
        return res
# @lc code=end

417.太平洋大西洋水流问题.py


# nama = input("masukan nama anda! ")
# nim = input("masukan nim anda! ")
# kelas = input("masukan kelas anda! ")
# prodi = input("masukan prodi anda! ")
# print ("--------------------")
# print("nama anda adalah ", nama)
# print("nim anda adalah", nim)
# print("kelas anda adalah", kelas)
# print("prodi anda adalah", prodi)

Nama = ("maximillian")
kelas = ("a")
jurusan = ("teknik informatika")
quote = ("just do it than you dont at all")

print ("nama = ", Nama, "\n", "kelas =", kelas, "\n", "jurusan = ", jurusan, "\n", "quote = ", quote)


from selenium import webdriver
from selenium.webdriver.common.by import By
from traceback import *
from selenium.webdriver.support import exception_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import *

class keywords_library:
####################################

    def __init__(self, driver):
        self.driver = driver

####################################
    def launch_url(self, url):
        '''
            launch the url
            paramater: URL
            return value: None
        '''
        self.driver.get(url)

####################################
    def verify_title(self, text):
        '''
            verify the title
            paramater: title text to verify
            return value: True or False
        '''
        text = text.lower()
        captured_title = self.driver.title
        if text == captured_title.lower():
            print('title match - pass, title from the browser is ' + captured_title)
            return True
        else:
            print('title match - fail, title from the browser is ' + captured_title)
            return False

####################################

    def getByType(self, locatortype):
        '''
            function to get locator type
            parameter: locator type like ID,XPATH, CSS.. et
            return value: by. ID, by.XPATH..etc
        '''
        locatortype = locatortype.lower()
        if locatortype == 'id':
            return By.ID
        elif locatortype =='xpath':
            return By.XPATH
        elif locatortype=='css':
            return By.CSS_SELECTOR
        elif locatortype == 'name':
            return By.NAME
        elif locatortype == 'linktext':
            return By.LINK_TEXT
        elif locatortype == 'partiallinktext':
            return By.PARTIAL_LINK_TEXT
        elif locatortype =='tagname':
            return By.TAG_NAME
        else:
            print('locator type is invalid')
            return None

####################################

    def getElement(self, locator,locatortype='ID'):
        '''
            enter the text in the editbox field
            parameters:  locatortype, locator
            return value: element or None
        '''
        element = None
        try:
            by_value= getByType(locatortype)
            element = self.driver.find_element(by_value, locator)
            print('Element is found')
            return element
        except:
            print('Element is not found')
        return None

####################################

    def waitForElement(self, locator, timeout=10, locatortype='ID',poll_frequency=1):
        '''
            Explicit wait
            paramters: locator, locator type, timeout
            return:
        '''
        element = None
        try:
            locatortype= locatortype.lower()
            byType = self.getByType(locatortype)
            wait = WebDriverWait(driver, timeout, poll_frequency,
                                 ignored_exceptions=[NoSuchElementException,
                                                     ElementNotVisibleException,
                                                     ElementNotSelectableException])
            element = wait.until(ec.element_to_be_clickable((byType,locator)))
            print("Element appeared on the web pages")
        except:
            print("Element not appeared on the web pages")
            print_stack()
        return element


from __future__ import print_function
from __future__ import absolute_import

from tests.test_base import *
from qgate.script import *
import numpy as np

if hasattr(qgate.simulator, 'cudaruntime') :

    class TestMultiDeviceCUDA(SimulatorTestBase) :

        def set_mgpu_preference(self) :
            # max chunk size, 2 MB.
            max_po2idx_per_chunk = 21
            # device memory per memstore
            memory_store_size = 5 * (1 << 20)
            # device ids.
            device_ids = [0] * 8
            # initialize
            qgate.simulator.cudaruntime.set_preference(device_ids, max_po2idx_per_chunk, memory_store_size)

        def term_module(self) :
            qgate.simulator.cudaruntime.module_finalize()

        def setUp(self) :
            # using fp64, 16 MB.
            self.n_qregs = 20
            self.term_module()

        def tearDown(self) :
            self.term_module()
            qgate.simulator.cudaruntime.reset_preference()

        def run_sim(self, circuit) :
            sim = qgate.simulator.cuda(circuit_prep = qgate.prefs.one_static)
            sim.run(circuit)
            return sim

        def compare(self, circuit) :
            self.set_mgpu_preference();
            mc_states = self.run_sim(circuit).qubits.get_states()
            self.term_module()
            qgate.simulator.cudaruntime.reset_preference()
            sc_states = self.run_sim(circuit).qubits.get_states()
            self.term_module()

            n_states = 1 << self.n_qregs
            self.assertTrue(np.allclose(mc_states, sc_states))

        def test_hadmard_gate(self) :
            qregs = new_qregs(self.n_qregs)
            circuit = [H(qreg) for qreg in qregs]
            self.compare(circuit)

        def test_cx_gate(self) :
            qregs = new_qregs(self.n_qregs)
            circuit = [ X(qregs[0]) ]
            for idx in range(0, self.n_qregs - 1) :
                cx = ctrl(qregs[idx]).X(qregs[idx + 1])
                circuit.append(cx)
            self.compare(circuit)

        def test_measure_x_mimimal(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            neg_cregs = new_references(self.n_qregs)

            circuit = [
                [I(qreg) for qreg in qregs],
                X(qregs[0]),
                measure(neg_cregs[1], qregs[1]),
                measure(neg_cregs[2], qregs[2])
            ]

            sim = self.run_sim(circuit)
            self.assertEqual(sim.values.get(neg_cregs[1]), 0)

        def test_measure_x_minimal_2(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            init_cregs = new_references(self.n_qregs)
            neg_cregs = new_references(1)

            circuit = []
            for idx in range(0, self.n_qregs) :
                circuit.append(measure(init_cregs[idx], qregs[idx]))
            circuit.append(X(qregs[0]))
            circuit.append(measure(neg_cregs[0], qregs[1]))
            sim = self.run_sim(circuit)
            self.assertEqual(0, sim.values.get(neg_cregs[0]))

        def test_measure_x_minimal_3(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            neg_cregs = new_references(self.n_qregs)

            circuit = [
                [I(qreg) for qreg in qregs],
                X(qregs[2]),
                measure(neg_cregs[0], qregs[0]),
                measure(neg_cregs[1], qregs[1]),
                measure(neg_cregs[2], qregs[2])
            ]
            sim = self.run_sim(circuit)

            self.assertEqual(0, sim.values.get(neg_cregs[0]))
            self.assertEqual(0, sim.values.get(neg_cregs[1]))
            self.assertEqual(1, sim.values.get(neg_cregs[2]))

        def test_measure_x(self) :
            self.set_mgpu_preference()
            for lane in range(0, self.n_qregs) :
                qregs = new_qregs(self.n_qregs)
                init_cregs = new_references(self.n_qregs)
                neg_cregs = new_references(self.n_qregs)

                circuit = []
                for idx in range(0, self.n_qregs) :
                    circuit += [measure(init_cregs[idx], qregs[idx])]
                circuit.append(X(qregs[lane]))
                for idx in range(0, self.n_qregs) :
                    circuit += [measure(neg_cregs[idx], qregs[idx])]
                sim = self.run_sim(circuit)
                for idx in range(0, self.n_qregs) :
                    self.assertEqual(0, sim.values.get(init_cregs[idx]))
                    if idx == lane :
                        self.assertEqual(1, sim.values.get(neg_cregs[idx]))
                    else :
                        # print('lane {}, idx []'.format(lane, idx))
                        self.assertEqual(0, sim.values.get(neg_cregs[idx]))

        def test_prob(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            circuit = [H(qreg) for qreg in qregs]
            sim = self.run_sim(circuit)
            for qreg in qregs :
                prob = sim.qubits.calc_probability(qreg)
                self.assertAlmostEqual(0.5, prob)

        def test_cx_prob(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            circuit = [X(qregs[0]),
                       [ctrl(qregs[idx]).X(qregs[idx + 1]) for idx in range(0, self.n_qregs - 1)],
            ]
            sim = self.run_sim(circuit)
            for qreg in qregs :
                prob = sim.qubits.calc_probability(qreg)
                self.assertAlmostEqual(0., prob)

        def test_ccx_prob(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            circuit = [X(qregs[0]), X(qregs[1]),
                       [ctrl(qregs[idx], qregs[idx + 1]).X(qregs[idx + 2]) for idx in range(0, self.n_qregs - 2)],
            ]
            sim = self.run_sim(circuit)
            for qreg in qregs :
                prob = sim.qubits.calc_probability(qreg)
                self.assertAlmostEqual(0., prob)

        def test_ccx_prob_0(self) :
            self.set_mgpu_preference()
            qregs = new_qregs(self.n_qregs)
            circuit = [X(qregs[0]), I(qregs[1]),
                       [ctrl(qregs[idx], qregs[idx + 1]).X(qregs[idx + 2]) for idx in range(0, self.n_qregs - 2)],
                       X(qregs[0])
            ]
            sim = self.run_sim(circuit)
            for qreg in qregs :
                prob = sim.qubits.calc_probability(qreg)
                self.assertAlmostEqual(1., prob)

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


import gc

import numpy as np
from numba import cuda

from ._helpers import Ctx

class system:
    def __init__(self, x, box, typ, bond=None, diameter=None, gpu=0, num=None):
        gpu_table = {}
        for s in Ctx.get_all_systems():
            if gpu_table.get(s.gpu) is None:
                gpu_table[s.gpu] = []
            gpu_table[s.gpu].append(s.num)
        if gpu in gpu_table.keys():
            raise ValueError(
                "gpu %d has been already occupied by system %s!" % (gpu, gpu_table[gpu])
            )
        cuda.select_device(gpu)  # select gpu before everything.
        self.x = x
        self.nlist = None
        self.box = box
        self.dtype = x.dtype
        self.N = x.shape[0]
        self.n_dim = x.shape[1]
        self.gpu = gpu
        typ = np.asarray(typ)
        self.types = list(set(typ))
        self.typid = np.zeros(self.N, dtype=np.int32)
        for i, t in enumerate(self.types):
            self.typid[typ == t] = i
        if bond:
            self.bond = bond
            self.bonds = np.asarray(list(set(bond.T[0])), dtype=np.int32)
        self.diameter = diameter if diameter is not None else np.ones(self.N, dtype=x.dtype)
        with cuda.gpus[gpu]:
            self.d_x = cuda.to_device(x)
            self.d_box = cuda.to_device(box)
            self.d_typid = cuda.to_device(self.typid)
            # self.d_types = cuda.to_device(self.types)
            if bond:
                self.d_bond = cuda.to_device(bond)
                self.d_bonds = cuda.to_device(self.bonds)
            self.d_diameter = cuda.to_device(diameter)
            self.d_force = cuda.device_array((self.N, self.n_dim), dtype=x.dtype)
        if num is None:
            system.num = Ctx.get_num_systems() + 1
        else:
            if Ctx.has_num(num):
                raise ValueError("Number %d has already been registered!"
                                 "Please assign new number of system." % num)
        Ctx.set_active(self)

    def bond_table(self):
        pass

    def molecules(self):
        pass

    def snapshot(self):
        self.x = self.d_x.copy_to_host()
        self.box = self.d_box.copy_to_host()
        # whatever has been changed
        cuda.synchronize()
        return self

    def destroy(self):
        context = cuda.current_context(self.gpu)
        context.reset()
        # delete variables in self.
        gc.collect(1)


#Neunerln v 1.1
#Changelog:
#added in v.1.1:
#-menu
#-score system&tracking
# © Alexander Wittich

from pathlib import Path
from colorama import init
import random
import os
import pandas
init()

"""Exception to limit the amount of players to 6"""
class Over_Max(Exception):
    pass
"""Exception to limit the input number to only cards held in hand"""
class not_in_range(Exception):
    pass
"""Exception if there is no 7 in player's input"""
class no_seven(Exception):
    pass

""" creates the initial deck """
suits = ["Clubs", "Diamonds", "Hearts", "Spades"]

blueprint_deck = [ "Ace", "2", "3", "4", "5", "6", "7",
                   "8", "9", "10", "Jack", "Queen", "King"]
sortvalue = {"Ace": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6,
             "7": 7, "8": 8, "9": 9, "10": 10, "Jack": 11,
             "Queen": 12, "King": 13}

""" Builds our initial deck. Note, that this is already sorted in the right order """
deck = [i + " of " + j for i in sortvalue for j in suits]

""" Shuffles the deck """
shuffled_deck = random.sample(deck, len(deck))

""" Sorts the deck after card values, starting from aces and ending at kings """
"""solution that always works"""
def keyf(card):
    return sortvalue[card.split()[0]]

""" Defines a function for debugging """
def debug(hand_list, play_stack):

    print("----------------DEBUG----------------")
    for i in hand_list:
        print(i)
        print(len(i))
    d()
    print("This is the current stack:", play_stack)
    print("Len of deck:", len(shuffled_deck))
    print("Len of play_stack:", len(play_stack))
    print("----------------DEBUG----------------")

"""function for readability"""
def d():
    print("\n\n\n")

""" Builds the players starting hands """
def starting_hands(players):
    hand_list = []
    for i in range(players):
        hand = random.sample(shuffled_deck, 6)
        [shuffled_deck.remove(i) for i in hand]
        hand_list.append(hand)
    return hand_list

"""Function that determines what happens when deck is empty and a draw is attempted"""
def empty_deck(cards_left, player_to_draw):

    global skip_next_player
    global change_direction
    global shuffled_deck
    global play_stack

    d()
    if ace_round == True:
        shuffled_deck = random.sample(play_stack, len(play_stack))
        placeholder_deck = []    #creates a new deck because modifying a list while iteration
        play_stack = [i for i in play_stack if "Ace" in i] #functions not as we want it to
        [placeholder_deck.append(i) for i in shuffled_deck if "Ace" not in i]
        shuffled_deck = placeholder_deck
        if cards_left > 0:
            try:
                for card in range(cards_left):
                    card_draw = shuffled_deck.pop(0)
                    player_to_draw.insert(0, card_draw)
            except IndexError:  #if no cards are left to draw
                pass

    else:
        debug(hand_list, play_stack)
        d()
        first_new_card = play_stack.pop(0)
        shuffled_deck = play_stack
        shuffled_deck = random.sample(shuffled_deck, len(shuffled_deck))
        play_stack = []
        play_stack.insert(0, first_new_card)
        if cards_left > 0:
            try:
                for card in range(cards_left):
                    card_draw = shuffled_deck.pop(0)
                    player_to_draw.insert(0, card_draw)
            except IndexError:
                pass
            debug(hand_list, play_stack)

"""Function to display a list of handcards to the player"""
def new_display(hand):

    display_list = []
    display_count = 0
    for i in hand:
        display_elem = "[" + str(display_count) + "] " + i
        display_list.insert(display_count, display_elem)
        display_count += 1
    display_list = ' '.join(display_list)
    return display_list, display_count

"""Function to check if played card matches the value or suit of the top card"""
def validation(card, stack):

    global chosen_suit
    global suit_wish
    global ace_round

    for i in suits:
        if i in card:
            card_suit = i
        if i in stack:
            stack_suit = i
    for i in blueprint_deck:
        if i in card:
            card_value = i
        if i in stack:
            stack_value = i

    if suit_wish == True:
        stack_suit = chosen_suit

    if ace_round == True and card_value != "Ace":
        return False

    if card_suit == stack_suit or card_value == stack_value:
        return True
    elif "10" in card:
        return True

""" Function to compute what happens when one of the special cards is played"""
def special_cards(card, hand):

    global skip_next_player
    global change_direction
    global player_range
    global chosen_suit
    global suit_wish
    global ace_round
    global aces_in_stack

    if "7" in card:
        next_inc = 0        #initial values for determination of playorder
        inc_value = 1
        if change_direction == True:
            inc_value = -1
        next_inc += inc_value

        player_that_played =  hand_list.index(hand)

        cards_to_draw = 2

        while True:

            check_7_in_next_player = False

            next_player = player_that_played + next_inc
            """checks if last player or first player is reached and changes the
            next player accordingly to uphold the turn order"""
            if next_player == players:
                next_player = 0
                next_inc = 0
                player_that_played = 0
            elif next_player < 0:
                next_player = player_range[-1]
                next_inc = 0
                player_that_played = player_range[-1]

            if score_track == False:
                next_player_disp = next_player + 1
                next_player_disp = "Player" + str(next_player_disp)
            elif score_track == True:
                next_player_disp = player_list[next_player]

            for card in hand_list[next_player]:
                if "7" in card:
                    check_7_in_next_player = True

            if check_7_in_next_player == True:
                display_list, display_count = new_display(hand_list[next_player])
                played_card = input(f"{next_player_disp}, play a 7.\n {display_list}\n>")
                try:
                    int_input = int(played_card)
                    if int_input not in range(display_count):
                        raise not_in_range
                    elif "7" not in hand_list[next_player][int_input]:
                        raise no_seven
                    else:
                        played_card = hand_list[next_player].pop(int_input)
                        play_stack.insert(0, played_card)
                        cards_to_draw += 2
                        next_inc += inc_value

                except ValueError:
                    print("\nThis is not an Integer. Try again.\n")
                except not_in_range:
                    print("""\nThis is not the number of a card you have in your hand.
                             \rTry again.\n""")
                except no_seven:
                    print("This is not a 7. Try again.")

            else:
                print(f"{next_player_disp} draws {cards_to_draw} cards.")
                cards_left = cards_to_draw
                for i in range(cards_to_draw):
                    try:
                        card_draw = shuffled_deck.pop(0)
                        hand_list[next_player].insert(0, card_draw)
                        cards_left -= 1
                    except IndexError:
                        print("Index Error occurred. Cards left:", cards_left)
                        empty_deck(cards_left, hand_list[next_player])
                        debug(hand_list, play_stack)
                        break
                break

    elif "8" in card:
        skip_next_player = True

    elif "9" in card:
        if change_direction == True:
            change_direction = False
        else:
            change_direction = True

    elif "10" in card:
        display_list, display_count = new_display(suits)
        while True:
            try:
                chosen_suit = int(input(f"What suit do you want?\n{display_list}\n>"))
                if chosen_suit not in range(display_count):
                    raise not_in_range
                chosen_suit = suits[chosen_suit]
                suit_wish = True
                break
            except ValueError:
                print("This is not an Integer. Try again.")
            except not_in_range:
                print("This is not a valid input. Try again.")

    elif "Ace" in card:
        aces_in_stack = 0       #checks how many aces are currently
        for i in play_stack:    #in the play stack
            if "Ace" in i: #should have used list comprehension
                aces_in_stack += 1
        if ace_round == False:
            input_list = ["No", "Yes"]
            display_list, display_count = new_display(input_list)
            while True:
                try:
                    """input 0 equals False, input 1 equals True"""
                    ace_round = int(input(f"Do you want to start an ace round?\n{display_list}\n>"))
                    if ace_round not in range(display_count):
                        raise not_in_range

                    break
                except ValueError:
                    print("This is not an Integer. Try again.")
                except not_in_range:
                    print("This is not a valid input. Try again.")
        elif ace_round == True and aces_in_stack == 4:
            print("All aces have been played. Ace round is now over.")
            ace_round = False

"""Function that computes one full turn"""
def turn(player, hand):

    global suit_wish
    global ace_round
    global aces_in_stack

    display_list, display_count = new_display(hand)

    input_number = None
    played = False
    int_input = None

    while True:
        prompt = """{}, type in the number of the card you want to play.
                \rType draw to draw a card.\nYour hand:\n{}\n>""".format(player, display_list)

        print("\nThe top card of the stack is: ", play_stack[0], "\n")

        if suit_wish == True:
            print("The suit of the top card is:", chosen_suit)

        if ace_round == True:
            prompt = """Ace round is currently in effect. Player {}, play an ace or draw a card.
             \rNumber of aces on the stack: {}\nYour hand:\n{}\n>""".format(player, aces_in_stack, display_list)

        input_number = input(prompt)

        d()
        try:
            int_input = int(input_number)
            if int_input not in range(display_count):
                raise not_in_range
        except ValueError:
            if input_number == "draw":
                validation_list = []
                for i in hand:
                    validation_elem =  validation(i, play_stack[0])
                    validation_list.append(validation_elem)
                if True not in validation_list:
                    try:
                        card_draw = shuffled_deck.pop(0)
                        hand.insert(0, card_draw)
                        break
                    except IndexError:
                        empty_deck(1, hand)
                        break
                else:
                    print("""You have one or more playable cards in your hand.
                            \rDrawing is only allowed if you're unable to make a play.""")

            else:
                print("""\nThis is not an Integer. Try again.
                     \rType draw to draw a card.\n""")
            d()
        except not_in_range:
            print("""\nThis is not the number of a card you have in your hand.
                     \rTry again. Type draw to draw a card.\n""")
            d()

        if int_input in range(display_count):
            for i in range(display_count):
                if i == int_input:
                    card = hand[i]
                    validated = True#validation(card, play_stack[0])

                    if validated:

                        validated_card = hand.pop(int_input)
                        play_stack.insert(0, validated_card)
                        played = True
                        suit_wish = False
                        special_cards(card, hand)

                    else:
                        print("That's an illegal move.")
                        d()

        if played == True:
            break

"""MENU COMPUTATION"""

p = r"C:\Users\Alex\Documents\Programming\ProjectCardgame\score.csv"

if not Path(p).is_file():
    open(p, mode='w+', newline='')
else:
    print("ass")
start_game = False
while not start_game:

    print(" Welcome to Mau Mau. Please select one of the following options:")
    main_menu = input("[0] Start a new game [1] Highscore Settings [2] Exit\n>")

    if main_menu == "0":
        valid_input_players = False
        while not valid_input_players:
            maximum_players = 6 + 1 # +1 since range would end at 5 otherwise
            try:
                players = int(input("How many players? (Maximum 6)\n>"))
                if players not in range(1, maximum_players):
                    raise Over_Max
                valid_input_players = True
            except ValueError:
                print("Not a number, try again.")
            except Over_Max:
                print("Input must be between 1 and 6.")

        player_range = range(players)

        """creates a list of hands"""
        hand_list = starting_hands(players)

        print("Do you want to enable score tracking for this round?")
        while True:
            track_selection = input("[0] No [1] Yes\n>")
            if track_selection == "0":
                score_track = False
                start_game = True

                break
            elif track_selection == "1":
                with open(p, mode='r', newline='') as score_file:
                    score_object = pandas.read_csv(score_file, index_col=0)
                    name_list_temp = score_object.index.tolist()
                if len(name_list_temp) < players:
                    print("Not enough names detected to track score.",
                          "Game will start without tracking.")
                    break
                else:
                    player_list = []
                    for i in range(1, players + 1 ): #change to kardinal numbers
                        while True:
                            display_name_list, display_count = new_display(name_list_temp)
                            name_of_player = int(input(f"Name of Player {i}:\n{display_name_list}\n>"))
                            if name_of_player in range(display_count):
                                player_list.append(name_list_temp[name_of_player])
                                name_list_temp.remove(name_list_temp[name_of_player])
                                break
                            else:
                                print("Not a valid input.")
                    print(player_list)
                    score_track = True
                    start_game = True
                    break

            else:
                print("Not a valid input.")

    elif main_menu == "1":
        while True:
            setting_selection = input("[0] View Highscores [1] Add names "
                                      "[2] Delete Names [3] Reset Everything "
                                      "[4] Go back\n>")
            if setting_selection == "0":
                with open(p, mode='r', newline='') as score_file:
                    if os.path.getsize(p) == 0:
                        print("No Scores detected.")
                        continue
                    score_read = pandas.read_csv(score_file, index_col=0)
                    if score_read.empty == True:
                        print("No scores detected.")
                    else:
                        print(score_read)

            elif setting_selection == "1":
                new_names = input("Add one or multiple new names, seperated by ,\n>")
                new_names = new_names.replace(" ","").split(",")
                print(new_names)
                with open(p, mode='a+', newline='') as score_file:
                    data = 0
                    if os.path.getsize(p) == 0:
                        score_panda = pandas.DataFrame(data=data,
                                       index= new_names,
                                       columns= ["Score"])
                        score_panda.to_csv(score_file)
                        print(score_file)
                    else:
                        append_frame = pandas.DataFrame(data=data,
                                       index= new_names,
                                       columns= ["Score"])
                        score_file.seek(0)
                        init_panda = pandas.read_csv(score_file, index_col=0)
                        new_frame = init_panda.append(append_frame, ignore_index=False)
                        with open(p, mode='w', newline='') as new_score_file:
                            new_frame.to_csv(new_score_file)
                        print(new_frame)

            elif setting_selection == "2":
                finished = False
                with open(p, mode='a+', newline='') as score_file:
                    while not finished:
                        score_file.seek(0)
                        try:
                            score_read = pandas.read_csv(score_file, index_col=0)
                        except pandas.errors.EmptyDataError:
                            print("No names detected. Add names first.")
                            break

                        name_list = score_read.index.tolist()
                        print(name_list)
                        if not name_list:
                            print("No Names detected. Add names first.")
                            break
                        name_list_disp, display_count = new_display(name_list)
                        try:
                            del_choice = int(input("Select Name to delete it. Type 999 "
                                                    f"to finish.\n{name_list_disp}\n>"))
                        except ValueError:
                            print("Not an integer.")
                        if del_choice in range(display_count):
                            del_choice = name_list[del_choice]
                            new_frame = score_read.drop(del_choice, axis=0)
                            with open(p, mode='w', newline='') as new_score_file:
                                new_frame.to_csv(new_score_file)
                            print(new_frame)
                        elif del_choice == 999:
                            finished = True
                        else:
                            print("Not a valid input.")

            elif setting_selection == "3":
                confirm_list = ["No", "Yes"]
                disp_con, display_count = new_display(confirm_list)
                while True:
                    try:
                        confirm = int(input(f"Are you sure?\n{disp_con}\n>"))
                        if confirm == True:
                            with open(p, mode='w', newline='') as score_file:
                                break    #truncates the file by opening it in 'w'
                        elif confirm == False:
                            break
                        else:
                            print("Not a valid input.")
                    except ValueError:
                        print("Type in a valid integer.")

            elif setting_selection == "4":
                break

    elif main_menu == "2":
        exit()

""" Initial Variables"""
valid_input_players = False
current_player = 0
aces_in_stack = 0
ace_round = False
skip_next_player = False
change_direction = False
suit_wish = False

player_range = range(players) #used for playorder determination

"""creates a list of hands"""
hand_list = starting_hands(players)

"""generates the first card on the stack"""
play_stack = []
first_card = shuffled_deck.pop(0)
play_stack.insert(0, first_card)

"""start of the main computation"""
while True:

    hand = hand_list[current_player]
    print(hand)

    if score_track == False:
        #changing ordinal to cardinal number for display
        cur_player_display = current_player + 1
        cur_player_display = "Player " + str(cur_player_display)
    elif score_track == True:
        cur_player_display = player_list[current_player]

    turn(cur_player_display, hand)
    print("----------------------------------")
    print(play_stack)
    print("-----------------------------------")
    d()

    if not hand:
        print(f"""{cur_player_display} has no cards left in his hand.
                 \r{cur_player_display} wins!""")
        if score_track == True:
            with open(p, mode='r', newline='') as score_file:
                score_file.seek(0)
                score_read = pandas.read_csv(score_file, index_col=0)
                score_read.at[cur_player_display, "Score"] += 1
                with open(p, mode='w', newline='') as new_score:
                    score_read.to_csv(new_score)
        exit()

    if change_direction == False:
        inc = 1
    if change_direction == True:
        inc = -1

    if skip_next_player == True:
        current_player += inc
        skip_next_player = False

    current_player += inc

    if current_player == players:   # executes when second to last player plays 8
        current_player = player_range[0]
    elif current_player == players + 1:  #executes when last player plays 8
        current_player = player_range[1]
    elif current_player == -1:          #same as above in reverse
        current_player = player_range[-1]
    elif current_player == -2:
        current_player = player_range[-2]


import unittest
from clusto.test import testbase

import clusto
from clusto.schema import *
from clusto.drivers.base import *
from clusto.drivers import BasicDatacenter
from sqlalchemy.exceptions import InvalidRequestError

class TestClustoCounter(testbase.ClustoTestBase):

    def testCounterDefault(self):

        e = Entity('e1')
        c = Counter(e, 'key1')

        self.assertEqual(c.value, 0)

        d = Counter(e, 'key2', start=10)

        self.assertEqual(d.value, 10)

    def testCounterIncrement(self):

        e = Entity('e1')
        c = Counter(e, 'key1')

        c.next()
        c.next()
        self.assertEqual(c.value,2)

    def testGetCounter(self):

        e = Entity('e1')

        c = Counter.get(e, 'key1')

        c.next()
        self.assertEqual(c.value, 1)

        d = Counter.get(e, 'key1', default=100)
        d.next()
        self.assertEqual(d.value, 2)

        f = Counter.get(e, 'key2', default=20)
        self.assertEqual(f.value, 20)


# Telegram Ping / Pong Speed

from pyrogram import filters
from Code_X_Mania.bot import StreamBot
import time

@StreamBot.on_message(filters.regex("ping"))
async def ping(b, m):
    start_t = time.time()
    jv = await m.reply_text("....")
    end_t = time.time()
    time_taken_s = (end_t - start_t) * 1000
    await jv.edit(f"Pong!\n{time_taken_s:.3f} ms")


from day06.path import calculate_route

class Orbit:

    def __init__(self, name: str, orbits: ['Orbit']):
        self.name = name
        self.orbits = orbits

orbits: {str: Orbit} = {}
existing_orbits: {str} = set()
dependencies: {str: str} = {}
connections: {str: [str]} = {}

with open('input.txt') as file:
    for line in file.readlines():
        parts = line.replace('\n', '').split(')')
        dependencies[parts[1]] = parts[0]
        existing_orbits.add(parts[0])
        existing_orbits.add(parts[1])

        if parts[0] not in connections:
            connections[parts[0]] = [parts[1]]
        else:
            connections[parts[0]].append(parts[1])

        if parts[1] not in connections:
            connections[parts[1]] = [parts[0]]
        else:
            connections[parts[1]].append(parts[0])

    while len(existing_orbits) > 0:
        for orbit in existing_orbits.copy():
            if orbit not in dependencies:
                existing_orbits.remove(orbit)
                orbits[orbit] = Orbit(orbit, [])
            elif dependencies[orbit] in orbits:
                existing_orbits.remove(orbit)
                target = Orbit(orbit, orbits[dependencies[orbit]].orbits.copy())
                target.orbits.append(orbits[dependencies[orbit]])
                orbits[orbit] = target

def part1():
    orbit_count = sum([len(orbits[name].orbits) for name in orbits])
    print(f'Total orbit count: {orbit_count}')

def part2():
    route_length = calculate_route(connections, 'YOU', 'SAN') - 3
    print(f'Route length: {route_length}')

if __name__ == '__main__':
    part1()
    part2()


import numpy as np
import copy
from bbase.elementary import *
from bbase.basis_change import dim_vect

# This is an implementation of the algorithm from Section 3 (and more generally Section 5 for zigzag modules).

def initialise_basis(A, t):
    v = dim_vect(A, t)
    return [np.identity(n) for n in v]

def bform(A, t, F, basis=True):
    if basis:
        return barcode_form(A, t, F, basis)
    else:
        barcode_form(A, t, F, basis)

# This is the main function of interest. It takes as input a matrix sequence A, the orientation t of the
# underlying quiver and the field F of computation. If basis is set to False (by default True),
# then it simply puts the underlying matrix sequence A in barcode form. Else, it outputs
# the matrix sequence X in barcode form together with the adequate change of basis B.
# ladder is a parameter used for decomposing ladder and can be safely ignored.
def barcode_form(A, t, F, basis=False, ladder=None):
    if basis:
        B = initialise_basis(A, t)
        A = copy.deepcopy(A)
    else:
        B = [None for k in range(len(A) + 1)]
    for l in range(len(A)):
        local_reduce(A, t, F, l, B=B, ladder=ladder)
    if basis:
        return A, B

# This implements the iterative process exhbited in Proposition 5.4.
def local_reduce(A, t, F, l, B=None, ladder=None):
    if t[l] == 0:
        if l == len(A) - 1:
            if ladder:
                if ladder[1] == 'top':
                    piv = row_reduce(A[l], F, B[l + 1], {0: [ladder[0][l + 1]]})
                elif ladder[1] == 'bot':
                    piv = row_reduce(A[l], F, B[l + 1], {1: [ladder[0][l + 1]]})
            else:
                piv = row_reduce(A[l], F, B[l + 1])
        else:
            if ladder is not None:
                if ladder[1] == 'top':
                    piv = row_reduce(A[l], F, B[l + 1], {0: [A[l + 1], ladder[0][l + 1]]})
                elif ladder[1] == 'bot':
                    piv = row_reduce(A[l], F, B[l + 1], {0: [A[l + 1]], 1: [ladder[0][l + 1]]})
            else:
                piv = row_reduce(A[l], F, B[l + 1], {t[l + 1]: [A[l + 1]]})
        for r, q in piv:
            for p in range(q + 1, A[l].shape[1]):
                if A[l][r, p] != 0:
                    zero_out(A, F, r, q, p, t, l, 'col', B=B, ladder=ladder)
    if t[l] == 1:
        if l == len(A) - 1:
            piv = col_reduce(A[l], F, B[l + 1])
        else:
            piv = col_reduce(A[l], F, B[l + 1], {t[l + 1]: [A[l + 1]]})

        for r, q in piv:
            for p in range(r):
                if A[l][p, q] != 0:
                    zero_out(A, F, r, q, p, t, l, 'row', B)

# This is a direct implementation of Lemma 5.3 for zeroing term in the last matrix of our matrix sequence A,
# where all previous matrices are in barcode form.
def zero_out(A, F, r, q, p, t, k, op_type, B, ladder=None):
    if op_type == 'col':
        x = A[k][r, p]
        add_col(A[k], q, p, -x, F, B[k])
        if ladder:
            if ladder[1] == 'top':
                add_col(ladder[0][k], q, p, -x, F)
            elif ladder[1] == 'bot':
                add_row(ladder[0][k], p, q, x, F)

        if k == 0:
            return

        elif t[k - 1] == 0:
            add_row(A[k - 1], p, q, x, F)
            if (A[k - 1][p, :] == np.zeros(A[k - 1].shape[1])).all():
                return A, B
            for i in range(A[k - 1].shape[1]):
                if A[k - 1][q, i] != 0:
                    c = i
                    break
            for i in range(c + 1, A[k - 1].shape[1]):
                if A[k - 1][p, i] != 0:
                    d = i
                    break
            zero_out(A, F, q, c, d, t, k - 1, 'col', B, ladder)

        elif t[k - 1] == 1:
            add_col(A[k - 1], q, p, -x, F)
            if (A[k - 1][:, q] == np.zeros((A[k - 1].shape[0], 1))).all():
                return A, B
            for i in range(A[k - 1].shape[0]):
                if A[k - 1][i, p] != 0:
                    d = i
                    break
            for i in range(d + 1, A[k - 1].shape[0]):
                if A[k - 1][i, p] != 0:
                    c = i
                    break
            zero_out(A, F, c, p, d, t, k - 1, 'row', B)

    if op_type == 'row':
        x = A[k][p, q]
        add_row(A[k], r, p, -x, F, B[k])

        if k == 0:
            return
        elif t[k - 1] == 0:
            add_row(A[k - 1], r, p, -x, F)
            if (A[k - 1][r, :] == np.zeros(A[k - 1].shape[1])).all():
                return A, B
            for i in range(A[k - 1].shape[1]):
                if A[k - 1][p, i] != 0:
                    c = i
                    break
            for i in range(c + 1, A[k - 1].shape[1]):
                if A[k - 1][p, i] != 0:
                    d = i
                    break
            zero_out(A, F, p, c, d, t, k - 1, 'col', B)

        elif t[k - 1] == 1:
            add_col(A[k - 1], p, r, x, F)
            if (A[k - 1][:, p] == np.zeros((A[k - 1].shape[0], 1))).all():
                return A, B
            for i in range(A[k - 1].shape[0]):
                if A[k - 1][i, r] != 0:
                    d = i
                    break
            for i in range(d + 1, A[k - 1].shape[0]):
                if A[k - 1][i, r] != 0:
                    c = i
                    break
            zero_out(A, F, c, r, d, t, k - 1, 'row', B)


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

data = np.loadtxt('C:\\Users\\Heera Baiju\\Desktop\\Q2data.txt')
xdata = data[:,1]
ydata = data[:,2]
error = data[:,3]

def compute_sigma_level(trace1, trace2, nbins = 20):
    L, xbins, ybins = np.histogram2d(trace1, trace2, nbins)
    L[L == 0] = 1E-16
    shape = L.shape
    L = L.ravel()

    i_sort = np.argsort(L)[::-1]
    i_unsort = np.argsort(i_sort)
    L_cumsum = L[i_sort].cumsum()
    L_cumsum /= L_cumsum[-1]
    xbins = 0.5 * (xbins[1:] + xbins[:-1])
    ybins = 0.5 * (ybins[1:] + ybins[:-1])
    return xbins, ybins, L_cumsum[i_unsort].reshape(shape)

def plot_MCMC_trace(ax, trace, scatter = False, **kwargs):

    xbins, ybins, sigma = compute_sigma_level(trace[0], trace[1])
    ax.contour(xbins, ybins, sigma.T, levels = [0.683, 0.955], **kwargs)
    if scatter:
        ax.plot(trace[0], trace[1], ',k', alpha = 0.1)
    ax.set_xlabel('m')
    ax.set_ylabel('b')

def plot_MCMC_results(trace, colors = 'k'):

    fig, ax = plt.subplots(1, 1, figsize = (8, 5))
    plt.title('68% and 95% joint confidence intervals on b and m')
    plot_MCMC_trace(ax, trace, True, colors = colors)

def log_prior(theta):
    beta = theta
    return -1.5 * np.log(1 + beta ** 2)

def log_likelihood(theta, x, y):
    alpha, beta = theta
    y_model = alpha + beta * x
    return -0.5 * np.sum(np.log(2 * np.pi * error ** 2) + (y - y_model) ** 2 / error **
2)

def log_posterior(theta, x, y):
    return log_prior(theta) + log_likelihood(theta, x, y)

ndim = 2
nwalkers = 50
nburn = 1000
nsteps = 2000

np.random.seed(0)
starting_guesses = np.random.random((nwalkers, ndim))
sampler = emcee.EnsembleSampler(nwalkers, ndim, log_posterior, args = [xdata,
ydata])
sampler.run_mcmc(starting_guesses, nsteps)
emcee_trace = sampler.chain[:, nburn:, :].reshape(-1, ndim).T
plot_MCMC_results(emcee_trace)
plt.show()


import re

data = []
with open("day4input.txt") as infile:
    for line in infile:
        data.append(re.split(r'[-,\n]', line))

total = 0

for item in data:
    one, two, three, four, blank = item
    if (int(one) >= int(three)) and (int(two) <= int(four)):
        total += 1
    elif (int(three) >= int(one)) and (int(four) <= int(two)):
        total += 1

print(total)


import cvxpy as cp
import numpy as np
import matplotlib.pyplot as plt

# wf_space_data = np.load('../data/svdSpatialComponents.npy')               #  US 500

xp = np.loadtxt("gt_dynamics.csv", delimiter=",", dtype=float)
ywf = np.loadtxt("gt_WF_dynamics.csv", delimiter=",", dtype=float)
ynp = np.loadtxt("gt_NP_dynamics.csv", delimiter=",", dtype=float)
t = xp[:, 0]
n = xp.shape[1] - 1
print(n)
x0 = np.loadtxt("gt_init.csv", delimiter=",", dtype=float)
um = np.loadtxt("gt_eigvec.csv", delimiter=",", dtype=str)
# Make a function to convert csv string to python complex
print(um)
Um = np.zeros((n,n),dtype=complex)

for i in range(n):
    for j in range(n):
        s = um[i,j]
        s = s.replace('i', 'j')
        v = complex(s)
        Um[i, j] = v

print(Um)
dm = np.loadtxt("gt_eigval.csv", delimiter=",", dtype=str)
print(dm)
Dm = np.zeros((n,n),dtype=complex)

for i in range(n):
    for j in range(n):
        s = dm[i,j]
        s = s.replace('i', 'j')
        v = complex(s)
        Dm[i,j] = v

print(Dm)

print(xp.shape)
print(ywf.shape)
print(ynp.shape)

# Generate a random non-trivial quadratic program.
T = 1000
N = 100

Q = 0.1*np.eye(n)
R = 0.1*np.eye(n)
IN = np.eye(N)
QN = np.kron(IN, Q)
RN = np.kron(IN, R)

F = np.array([])
G = np.array([])
F = np.empty((0,n), float)
G = np.empty((0,n*N), float)
print(Um.shape)
print(Dm.shape)
print(Um @ Dm**0 @ Um.T)
for i in range(N):

    F = np.real(np.append(F, Um @ Dm**i @ Um.T, axis=0))
    #F = np.vstack((F, Um @ Dm**i @ Um.T))

    #print(F)
    cc = np.empty((n,0), float)
    #cc = np.array([])

    for j in range(N):
        if j <= i:
            c = np.real(Um @ (Dm**(i-j+1)) @ Um.T)
        else:
            c = np.zeros((n, n))

        cc = np.append(cc, c, axis=1)
        #print(cc.shape)
    G = np.append(G, cc, axis=0)

print(F.shape)
print(G.shape)

B = cp.Variable(n*N)
#prob = cp.Problem(cp.Minimize((F@x0 + G@B).T @ QN @ (F@x0 + G@B) + B.T@RN@B))
prob = cp.Problem(cp.Minimize((cp.quad_form((F@x0 + G@B), QN) + (cp.quad_form(B, RN)))))

prob.solve()

print(prob.value)
print(B.value)
X = F@x0 + G@B.value

tn = np.linspace(0, 1, 100)
x = np.reshape(X, (n, N))
b = np.reshape(B.value, (n, N))
fig = plt.figure()
plt.plot(x[:,:].T)
plt.xlabel("states")
plt.ylabel("time")
plt.show()

print(x[:,0])

fig = plt.figure()
plt.plot(tn,b[:,].T)
plt.xlabel("states")
plt.ylabel("time")
plt.show()


"""
Problem name: Two Sum II - Input array is sorted

Description: Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.

Note:

Your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution and you may not use the same element twice.
Example:

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
"""

from typing import List

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        print("")
        print("numbers:{}".format(numbers))
        print("target:{}".format(target))
        list_len = len(numbers)
        i = 0
        first_index = None
        second_index = None
        prev_num = None

        for num in numbers:
            j = i + 1

            # Stop the loop if num > target (note that this is sorted list)
            if num > target:
                break

            # Avoid checking the same number again (note that this is sorted list)
            if prev_num is not None and num == prev_num:
                # increase the first index
                i = i + 1
                continue

            # Loop through all numbers next to chosen number (num)
            # Stop the loop
            #   -- when loop reached end of the list or
            #   -- when numbers[j] is <= or >= target depending on if target is +ve or -ve number
            while j < list_len and \
                    (
                            (target > 0 and numbers[j] <= target) or
                            (target <= 0 and numbers[j] >= target)
                    ):

                if num + numbers[j] == target:
                    # index pair found
                    first_index = i
                    second_index = j
                    # break while loop
                    break

                # increase the second index
                j = j + 1

            if first_index is not None:
                # index pair found
                # break for loop
                break

            # increase the first index
            i = i + 1
            prev_num = num
        # -- End of for loop

        if first_index is not None:
            print("Matched Index Pair:[{},{}]".format(first_index, second_index))
            print("Matched Value Pair:[{},{}]".format(numbers[first_index], numbers[second_index]))
            print("Returned Index Pair:[{},{}]".format(first_index+1, second_index+2))
            return [first_index+1, second_index+1]
        else:
            return[]

if __name__ == "__main__":
    s1 = Solution()
    returned_list = s1.twoSum(numbers=[2, 7, 11, 15], target=9)
    print(returned_list)


import os
import argparse
import numpy as np
import matplotlib.pyplot as plt
import sis_utils

TEST_DATA_DIR = 'dcc_urban_mapper_height_valid'
CITY_NAME = 'JAX,TAM'
RSR_DATA_DIR = r'/media/ei-edl01/data/remote_sensing_data'
PATCH_DIR = r'/home/lab/Documents/bohao/data/urban_mapper'
TEST_PATCH_APPENDIX = 'valid_augfr_um_npy'
TEST_TILE_NAMES = ','.join(['{}'.format(i) for i in range(0, 16)])
RANDOM_SEED = 1234
BATCH_SIZE = 5
INPUT_SIZE = 572
CKDIR = r'/home/lab/Documents/bohao/code/sis/test/models/UrbanMapper_Height_npy'
MODEL_NAME = 'unet_origin_scratch_um_augfr_5'
NUM_CLASS = 2
GPU = '0'

def read_flag():
    parser = argparse.ArgumentParser()
    parser.add_argument('--test-data-dir', default=TEST_DATA_DIR, help='path to release folder')
    parser.add_argument('--rsr-data-dir', default=RSR_DATA_DIR, help='path to rsrClassData folder')
    parser.add_argument('--patch-dir', default=PATCH_DIR, help='path to patch directory')
    parser.add_argument('--test-patch-appendix', default=TEST_PATCH_APPENDIX, help='valid patch appendix')
    parser.add_argument('--test-tile-names', default=TEST_TILE_NAMES, help='image tiles')
    parser.add_argument('--city-name', type=str, default=CITY_NAME, help='city name (default austin)')
    parser.add_argument('--random-seed', type=int, default=RANDOM_SEED, help='tf random seed')
    parser.add_argument('--batch-size', default=BATCH_SIZE, type=int, help='batch size (10)')
    parser.add_argument('--input-size', default=INPUT_SIZE, type=int, help='input size 224')
    parser.add_argument('--ckdir', default=CKDIR, help='ckpt dir (models)')
    parser.add_argument('--num-classes', type=int, default=NUM_CLASS, help='# classes (including background)')
    parser.add_argument('--GPU', type=str, default=GPU, help="GPU used for computation.")
    parser.add_argument('--model-name', type=str, default=MODEL_NAME, help='Model name')

    flags = parser.parse_args()
    flags.input_size = (flags.input_size, flags.input_size)
    return flags

def evaluate_results(flags, model_name, height_mode):
    result = sis_utils.test_authentic_unet_height(flags.rsr_data_dir,
                                                  flags.test_data_dir,
                                                  flags.input_size,
                                                  model_name,
                                                  flags.num_classes,
                                                  flags.ckdir,
                                                  flags.city_name,
                                                  flags.batch_size,
                                                  ds_name='urban_mapper',
                                                  height_mode=height_mode)

    print(result)

    _, task_dir = sis_utils.get_task_img_folder()
    np.save(os.path.join(task_dir, '{}.npy'.format(model_name)), result)

if __name__ == '__main__':
    '''flags = read_flag()

    model_name = 'unet_origin_fix_scratch_um_augfr_4'
    if int(model_name[-1] == 4):
        height_mode = 'subtract'
    elif int(model_name[-1] == 5):
        height_mode = 'all'
    else:
        height_mode = 'subtract_all'

    evaluate_results(flags, model_name, height_mode)

    _, task_dir = utils.get_task_img_folder()
    result = dict(np.load(os.path.join(task_dir, '{}.npy'.format(model_name))).tolist())

    iou = []
    for k, v in result.items():
        iou.append(v)
    result_mean = np.mean(iou)
    print(result_mean)'''

    data_dir = r'/media/ei-edl01/user/bh163/tasks/2017.11.20.urban_mapper_heights'
    model_name = 'UnetInria_Origin_fr_resample_EP-25_DS-20_DR-0.1_LY-6_LR-0.5-1.0e-04'
    iou = dict(np.load(os.path.join(data_dir, model_name+'.npy')).tolist())
    print(iou['JAX004'])
    print(iou['JAX005'])
    print(iou['TAM000'])
    print(iou['TAM001'])
    print((iou['JAX004']+iou['JAX005']+iou['TAM000']+iou['TAM001'])/4)

    print()
    data_dir = r'/media/ei-edl01/user/bh163/tasks/2017.11.15.grid_experiments'
    model_name = 'UNET_um_no_random_scratch.npy'
    iou = dict(np.load(os.path.join(data_dir, model_name)).tolist())
    print(iou['JAX004'])
    print(iou['JAX005'])
    print(iou['TAM000'])
    print(iou['TAM001'])
    print((iou['JAX004'] + iou['JAX005'] + iou['TAM000'] + iou['TAM001']) / 4)


import tkinter as tk
from tokenizzatore import tokenizza

class Interfaccia:
    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry('550x125')
        self.root.title('Tokenizzatore')

        # label
        self.label = tk.Label(self.root)
        self.label.config(text='Inserisci frase da tokenizzare')

        # botton
        self.btn1 = tk.Button(self.root, text='Tokenizza', width=25, padx=5, pady=15)

        # entry
        self.entry = tk.Entry(self.root, width=50)
        self.entry.insert(0, 0)
        self.contents = tk.IntVar()
        self.contents.set('')
        self.entry['textvariable'] = self.contents

        # packing
        self.label.pack(fill=tk.BOTH)
        self.entry.pack(fill=tk.BOTH)
        self.btn1.pack(fill=tk.X)

        # binding evento
        self.btn1.bind('<Button-1>', self.tokenizza)
        self.btn1.bind('<Key>', self.tokenizza)

        # stringa da tokenizzare, elementi da non normalizzare
        self.text_entry = ''
        self.to_capitalize = list()

        self.root.mainloop()

    def tokenizza(self, event):
        self.text_entry = self.entry.get()

        self.label.config(text='Inserisci, se presenti, termini da non normalizzare (separati da spazio)')
        self.contents.set('')

        self.btn2 = tk.Button(text='Inserisci', command=lambda: self.inserisci_path(normalizza=True), width=25, padx=5, pady=15)
        self.btn3 = tk.Button(text='Normalizza tutto', command=self.inserisci_path, width=25, padx=5, pady=15)

        event.widget.pack_forget()
        self.btn2.pack(fill=tk.X, side=tk.LEFT, expand=True)
        self.btn3.pack(fill=tk.X, side=tk.RIGHT, expand=True)

    def inserisci_path(self, normalizza=False):
        if normalizza:
            tmp = self.entry.get().split()
            for word in tmp:
                word = word.capitalize()
                self.to_capitalize.append(word)

        self.contents.set('')
        self.label.config(text="Inserisci il path dove memorizzare l'output")
        self.btn4 = tk.Button(self.root, text='Inserisci', command=self.avvia_tokenizzazione, width=25, padx=5, pady=15)

        self.btn2.pack_forget()
        self.btn3.pack_forget()
        self.btn4.pack(fill=tk.X)

    def avvia_tokenizzazione(self):
        path = self.entry.get().rstrip()
        try:
            last_index = path.rindex('/')
        except ValueError:
            testo = 'Path non valido. Inserisci path come /Users/myUsername/Desktop/myFolder'
            self.label.config(text=testo)
        else:
            self.contents.set('')
            nome_folder = path[last_index + 1:]
            tokenizza(self.text_entry, path, non_normalizzare=self.to_capitalize)
            testo = f"Tokenizzazione completata con successo. " \
                    f"Tokenizzazione memorizzata nel file {nome_folder} \n\nPATH:{path}"
            self.label.config(text=testo)

            self.btn5 = tk.Button(self.root, text='Esci', command=self.root.quit, width=25, padx=5, pady=15)

            self.btn4.pack_forget()
            self.btn5.pack(fill=tk.BOTH)


from sys import stdin as Si, maxsize as m
from math import factorial as F
import collections

class Solution(object):
    def binSearch(self,Elemnt, Seq,N):
        l=len(Seq)
        low,high=0,l-1
        mid = 0
        while low<high:
            mid = int((low+high)/2)

            if N[Seq[mid]]<Elemnt:
                low = mid +1
            else:
                high = mid
        return high

    def increasingTriplet(self, nums):
        if nums==[]:    return False
        elem = []   #elem_indexes
        p = [None for _ in nums]      #parent

        for i in range(len(nums)):
            if elem==[] or nums[i]>nums[elem[-1]]:
                if len(elem)>0: p[i]=elem[-1]
                elem.append(i)

            else:
                pos = self.binSearch(nums[i],elem,nums)
                elem[pos]=i
                if pos!=0:
                    p[i]=elem[pos-1]

        cp = elem[-1]
        lis = []
        while cp is not None:
            lis.append(nums[cp])
            cp=p[cp]
        #lis.reverse()

        if len(lis)>=3: return True
        else:   return False

#NOTE This is a O(N*log(N)) solution, O(N^2) solution also exist using 2-D dynamic Pro
if __name__=='__main__':

    n = list(map(int,Si.readline().split()))
    S = Solution()
    print (S.increasingTriplet(n))

'''
 Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.

Formally the function should:

    Return true if there exists i, j, k
    such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.

Your algorithm should run in O(n) time complexity and O(1) space complexity.

Examples:
Given [1, 2, 3, 4, 5],
return true.

Given [5, 4, 3, 2, 1],
return false.
'''


import tldextract
from pythonScripts.data import insert_scraped_page
from bs4 import BeautifulSoup
from urllib.request import urlopen
import re
from pythonScripts.queue_jobs import crawl_website
import time

def crawl(task_id, website_id, website_url, depth):
    if (depth==-1):
        return None
    else:
        try:
            html = urlopen(website_url)
        except:
            html= "NA"
            print("Invalid website_url", website_url)
        start_time= time.time()
        soup = BeautifulSoup(html, 'html.parser')
        links = soup.find_all("a", href=re.compile("([A-Za-z0-9_:()])+"))
        page_domain = tldextract.extract(website_url).domain
        try:
            page_title = soup.title.string
        except:
            page_title = "NA"
        content_tags = set([tag.name for tag in soup.find_all()])
        insert_scraped_page(task_id=task_id, website_id=website_id, page_url=website_url, page_domain=page_domain,
                            page_title=page_title, html=str(soup), content_tags=str(content_tags))
        parts = website_url.split('//', 1)
        base_url = parts[0] + '//' + parts[1].split('/', 1)[0]
        end_time= time.time()
        print("Time taken for crawling : ", end_time-start_time)
        extensionsToCheck = (".epub", ".mobi", ".docx", ".doc", ".opf", ".7z", ".ibooks", ".cbr", ".avi", ".mkv", ".mp4", ".jpg", ".jpeg",
                             ".png", ".gif", ".pdf", ".iso", ".rar", ".tar", ".tgz", ".zip", ".dmg", ".exe")
        if(depth>0):
            print("For depth = ", depth, "and website url", website_url, "the total number of links generated=",
                  len(set(links)))
            for link in set(links):
                try:
                    if(urlopen(base_url + link['href'])):
                        if (base_url + link['href']).endswith(extensionsToCheck)==False:
                            if tldextract.extract(base_url + link['href']).domain in page_domain:
                                #valid_link.append(str(link['href']))
                                crawl_website(task_id= task_id, website_id= website_id, website_url= base_url + link['href'], crawl_depth= depth-1)
                                #print("The lamda function has the following website_url=", base_url + link['href'])
                except:
                    try:
                        if(urlopen(link['href'])):
                            if (link['href']).endswith(extensionsToCheck) == False:
                                if tldextract.extract(link['href']).domain in page_domain:
                                    #valid_link.append(str(link['href']))
                                    crawl_website(task_id= task_id, website_id= website_id, website_url= link['href'], crawl_depth= depth-1)
                                    #print("The lamda function has the following direct website_url=", link['href'])
                    except:
                        #print("Did not go to Lambda")
                        #invalid_link.append(str(base_url+link['href']))
                        continue
            print("Task Ends for website=", website_url)
    return None


from django import forms

from .models import WorkoutLog

class WorkoutLogForm(forms.ModelForm):
    class Meta:
        fields = ["day", "summary", "goal", "exercises", "muscles"]
        model = WorkoutLog
        widgets = {
            "day": forms.Select(attrs={"class": "form-control"}),
            "summary": forms.Textarea(attrs={"class": "form-control", "rows": "3"}),
            "goal": forms.Select(attrs={"class": "form-control"}),
            "exercises": forms.CheckboxSelectMultiple(
                attrs={"class": "list-unstyled", "type": "checkbox"}
            ),
            "muscles": forms.CheckboxSelectMultiple(
                attrs={"class": "list-unstyled", "type": "checkbox"}
            ),
        }


#!/usr/bin/env python3
"""MeetUp 177 - Beginners' Python and Machine Learning - Wed 15 Mar 2023 - email

Youtube: https://youtu.be/CMS7JUMVh_I
Source:  https://github.com/timcu/bpaml-sessions/raw/master/online/meetup177_tim_email.py

Learning objectives:
- sending emails automatically from within Python program

@author D Tim Cummings

Refs:
https://aiosmtpd.readthedocs.io/
https://docs.python.org/3/library/email.examples.html
https://docs.python.org/3/library/smtplib.html
https://developers.google.com/gmail/api/quickstart/python
https://developers.google.com/gmail/api/guides/sending#python
"""

import base64
import collections
import datetime
import imghdr
import os.path
import smtplib
import unicodedata

from email.message import EmailMessage
from email.utils import make_msgid

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

EMAIL_TO = ""
IMAGE_FILE = "bpaml.webp"

# Task 1. Set up Python project
"""
# If not using IDE such as PyCharm Community Edition, type the following on the command line
mkdir bpaml-email-pdf
cd bpaml-email-pdf
# Copy this file into that directory
"""
# Task 2. Create virtual environment
r"""
# If not using IDE type the following on the command line
python -m venv venv177                      # Windows
python3 -m venv venv177                     # Mac or Linux
conda create --name venv177                 # Anaconda

# activate virtual environment
source venv177/bin/activate                 # Mac or Linux or Windows Git-Bash
conda activate venv177                      # Anaconda
venv177\Scripts\activate.bat                # Windows command prompt
venv177\Scripts\Activate.ps1                # Windows powershell
"""
# Task 3: Install requirements
"""
# Add the following to requirements.txt in the project directory
google-api-python-client
google-auth-httplib2
google-auth-oauthlib
aiosmtpd

# If you are not using an IDE, install requirements from command line
pip install -r requirements.txt                            # Windows, Mac or Linux without Anaconda
conda install --name venv177 --file requirements.txt       # Anaconda
# or if you don't want to use the requirements.txt file
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib aiosmtpd
"""

# Task 4: Create an email message using email.message.EmailMessage
def message_from_str(subject="Creating a plain text email"):
    str_body = f"""\
Greetings from Beginners' Python and Machine Learning.

This email is the result of demonstrating: "{subject}"
It was created by a python bot at {datetime.datetime.now()}.

Email message created using email.message.EmailMessage().
https://docs.python.org/3/library/email.examples.html
https://docs.python.org/3/library/email.message.html
    """
    email_message = EmailMessage()
    email_message.set_content(str_body)
    email_message['Subject'] = subject
    email_message['To'] = EMAIL_TO
    email_message.preamble = "You will not see this preamble in a MIME-aware mail reader.\n"
    return email_message

# print(message_from_str())

# Task 5: Run debugging email server aiosmtpd
# https://aiosmtpd.readthedocs.io/
"""
python -m aiosmtpd -n --listen localhost:8025 --debug
# Stop with ctrl-c
"""

# Task 6: Send a message to the debug server. Try including a non-ascii unicode character
def send_message_via_aiosmtpd(email_message):
    email_message['From'] = "debugger@my_computer.python"
    # Ports 8025 debugging server, 25 SMTP(), 465 SMTP_SSL(), 587 .starttls()
    smtp_port = 8025  # For debugging server
    smtp_host = "127.0.0.1"
    with smtplib.SMTP(smtp_host, smtp_port) as smtp_server:
        smtp_server.set_debuglevel(1)
        smtp_server.send_message(email_message)

# send_message_via_aiosmtpd(message_from_str("Task 6: Test to debugging server"))
# send_message_via_aiosmtpd(message_from_str("Task 6: Test to debugging server ðŸ˜ƒ"))

# Task 7: Send a message via ISP server.
# Telstra/Bigpond: smtp.telstra.com
# Optus: mail.optusnet.com.au
# TPG: mail.tpg.com.au
def send_message_via_isp(email_message):
    email_message['From'] = "bpaml@pythonator.com"
    with smtplib.SMTP("smtp.telstra.com") as server:
        server.set_debuglevel(1)
        server.send_message(email_message)

# send_message_via_isp(message_from_str("Task 7: Test to ISP server ðŸ˜ƒ"))

# Task 8: Set up a gmail account for sending email
# https://developers.google.com/gmail/api/quickstart/python
#
# Create project - eg bpaml177
# https://console.cloud.google.com
#
# Enable the API - enable Gmail API -
# https://console.cloud.google.com/flows/enableapi?apiid=gmail.googleapis.com
#
# Configure consent screen
# https://console.cloud.google.com/apis/credentials/consent?project=bpaml177
# External - because we don't have an organisation - Create
# App name - bpaml177
# User support email - your gmail address
# Developer contact info - your gmail address
# Save and continue
# Add or remove scopes
# Filter - API:Gmail API
# .../auth/gmail.readonly
# .../auth/gmail.send
# Save and Continue
# Test users: + Add users : your email address
# Save and continue
# Back to dashboard
#
# Authorise credentials for desktop application
# https://console.cloud.google.com/apis/credentials
# Create Credentials > OAuth Client ID
# Application Type > Desktop App
# Name > bpaml177
# Under OAuth 2.0 Client IDs download client id as client_secret.json
# Save client_secret.json in project directory
#
# Copy quickstart code but add in scope for gmail.send
# Run quickstart.py
def gmail_service():
    """Gmail API to get the Gmail service. Needs client_secret.json in working directory

    If token.json doesn't exist then the user's browser will open for them to authenticate
    before service is able to send emails.

    :returns: Authorized Gmail API service instance.
    """
    # if you change scopes then you will need to delete token.json and get another one
    scopes = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.send']

    credentials = None
    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.json'):
        credentials = Credentials.from_authorized_user_file('token.json', scopes)
    # If there are no (valid) credentials available, let the user log in.
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('client_secret.json', scopes)
            credentials = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(credentials.to_json())
    return build('gmail', 'v1', credentials=credentials)

# print(gmail_service())

# Task 9: Send email via gmail
# https://developers.google.com/gmail/api/guides/sending#python
def send_message_via_gmail(email_message: EmailMessage):
    """Send an email message via Gmail."""
    email_message['From'] = 'pythonatordev@gmail.com'
    # user_id: User's email address. The special value "me" can be used to indicate the authenticated user.
    # gmail_body: {"raw": base64 encoded message as a Python 3 str}
    # for other ways of constructing a gmail_body see help(gmail_service().users().messages().send)
    gmail_body = {"raw": base64.urlsafe_b64encode(email_message.as_bytes()).decode(encoding='utf-8')}
    gmail_response = gmail_service().users().messages().send(userId="me", body=gmail_body).execute()
    print("Gmail response", gmail_response)

# send_message_via_gmail(message_from_str("Task 9: Send email via gmail"))

# Task 10: Attach image to email
# https://docs.python.org/3/library/email.examples.html
def message_with_image_attachment():
    email_message = message_from_str("Task 10: Attaching a WEBP image to an email")
    # Place image in same directory as this Python script and put name in next line
    with open(IMAGE_FILE, 'rb') as fp:
        img_data = fp.read()
    # img_data is a bytes object
    # MIME type will be image/webp which comes from maintype/subtype
    # imghdr determines type of image by looking at the first few bytes of the image
    # filename is optional. It provides a default name should the recipient save the attachment
    subtype = imghdr.what(None, img_data)
    email_message.add_attachment(img_data, maintype='image', subtype=subtype, filename=f'image.{subtype}')
    return email_message

# send_message_via_aiosmtpd(message_with_image_attachment())
# send_message_via_isp(message_with_image_attachment())
# send_message_via_gmail(message_with_image_attachment())

# Task 11: Send an html email
def html_table_of_unicode_digits():
    dict_for_group = collections.defaultdict(dict)
    for i in range(7258):
        c = chr(i)
        if unicodedata.category(c) == "Nd":
            unicode_name = unicodedata.name(c)
            try:
                idx = unicode_name.index("DIGIT") + 5
            except ValueError:
                print(f"ValueError with i={i} c={c} unicode_name={unicode_name}. Doesn't contain 'DIGIT'")
            else:
                group_name = unicode_name[:idx]
                group_dict = dict_for_group[group_name]
                group_dict[int(c)] = c
    html = "
\n"
    for group, group_dict in dict_for_group.items():
        html += f"
{group}	"
        for k in range(10):
            html += f"{group_dict.get(k, ' ')}	"
        html += "
\n"
    html += "
"
    return html

def message_using_html():
    style = ""
    html = f"{style}\n"
    html += "
Our favourite numbers.
"
    html += html_table_of_unicode_digits()
    html += ""
    message = message_from_str("Task 11: Adding html to email")
    message.add_alternative(html, subtype='html')
    return message

# send_message_via_gmail(message_using_html())

# Task 12: Embed an image in html message
def message_using_html_with_embedded_image():
    style = """"""
    html = f"{style}\n"
    html += "
Our esteemed team.
"
    cid_image = make_msgid()
    html += f''
    html += "
My favourite numbers.
"
    html += html_table_of_unicode_digits()
    html += ""
    message = message_from_str("Task 12: Adding html to email")
    message.add_alternative(html, subtype='html')
    with open(IMAGE_FILE, "rb") as img:
        img_data = img.read()
    message.get_payload()[1].add_related(img_data, maintype='image', subtype=imghdr.what(None, img_data), cid=cid_image)
    return message

# send_message_via_gmail(message_using_html_with_embedded_image())