from gmusicapi import Mobileclient
from Initialize import sqliteread, sqlitewrite, openSocket, sendMessage,  createsongqueue, reconnect
from pytube import YouTube
import validators
import vlc
from Settings import *
import time
import urllib.request, urllib.parse, urllib.error
from shutil import copyfile
import sqlite3
from sqlite3 import Error
from importlib import reload
from unidecode import unidecode
import sys
reload(sys)

s = openSocket()
api = Mobileclient()
api.oauth_login(device_id=Mobileclient.FROM_MAC_ADDRESS, oauth_credentials="oauth.txt")
if Mobileclient.is_authenticated(api) == True:
    print("Logged into GPM successfully")
else:
    sendMessage(s, "Can't log into Google Play Music! Please check the console and follow the instructions!")
    api.perform_oauth(storage_filepath="oauth.txt")
    api.oauth_login(device_id=Mobileclient.FROM_MAC_ADDRESS, oauth_credentials="oauth.txt")

stream_url = ""

def writenowplaying(isPlaying, song_name):
    with open("Output/nowplaying.txt", "w") as f:
        if isPlaying == True:
            f.write(song_name)
        else:
            f.truncate()

def getytkey(url):
    if "youtube" in url.lower():
        return(url.split("=")[1][:11])
    elif "youtu.be" in url.lower():
        return(url.split("e/")[1][:11])
    else:
        return None

def songtitlefilter(song_name, redo):
    blacklist = BLACKLISTED_SONG_TITLE_CONTENTS[:]
    try:
        results = (Mobileclient.search(api, song_name, SONGBLSIZE)['song_hits'])[:SONGBLSIZE]
    except Exception as e:
        print(e)
        reconnect()
    songs = []

    for item in results:
        songs.append(item['track'])

    #Remove things from the blacklist if theyre explicitly requested
    for term in blacklist:
        if term.lower() in song_name.lower():
            blacklist.remove(term)

    #Iterate through the blacklisted contents, then the songs. Last song standing wins.
    for term in blacklist:
        if len(songs) == 1:
            break
        for song in reversed(songs):
            if len(songs) == 1:
                break
            if term.lower() in song['title'].lower():
                print((">Removed: " + song['title']))
                songs.remove(song)

    for item in songs:
        print((">>>Allowed: " + item['title']))
    print((">>>>>>Playing: " + songs[0]['title']))
    return songs[redo]

def sr_geturl(songkey):
    try:
        stream_url = Mobileclient.get_stream_url(api, songkey)
        return(stream_url)
    except Exception as e:
        print(e)
        reconnect()

def saveAlbumArt(songkey):
    if songkey[0] == "T": #If the key is from GPM - all GPM keys start with T.
        songinfo = Mobileclient.get_track_info(api, songkey)
        imgLink = songinfo['albumArtRef'][0]['url']
        f = open('Output/albumart.jpg', 'wb')
        f.write(urllib.request.urlopen(imgLink).read())
        f.close()
    else: #Otherwise just use the generic image.
        copyfile('generic_art.jpg', 'Output/albumart.jpg')

def removetopqueue():
    row = sqliteread('''SELECT id, name, song, key FROM songs ORDER BY id ASC''') #Pick the top song
    if row[1] == "BotPlaylist": #>>>>>> DO THIS STUFF IF THE LIST IS EMPTY!
        sqlitewrite(('''DELETE FROM songs WHERE id={0}''').format(int(row[0]))) #Delete the top song
        return
    return False

def getnewentry():
    result = sqliteread('SELECT id FROM songs ORDER BY id DESC LIMIT 1')
    return(str(result[0]))

def playfromplaylist():
    row = sqliteread('''SELECT id, song, key FROM playlist ORDER BY id ASC''') #Pick the top song
    if row == None: #>>>>>> DO THIS STUFF IF THE LIST IS EMPTY!
        return
    try:
        songtitle = row[1]
        songkey = row[2]
    except:
        return

    #Delete the top result
    row = sqliteread('SELECT id FROM playlist ORDER BY id ASC LIMIT 1')
    sqlitewrite(('''DELETE FROM playlist WHERE id={0}''').format(int(row[0]))) #Delete the top song
    sqlitewrite(('''INSERT INTO playlist(song, key) VALUES("{song_name}", "{key}");''').format(song_name=songtitle, key=songkey))
    sqlitewrite(('''INSERT INTO songs(name, song, key) VALUES("BotPlaylist", "{song_name}", "{key}");''').format(song_name=songtitle, key=songkey))

class SRcontrol:
    def __init__(self):
        self.msg = None
        self.songtitle = ""

    def playsong(self):
        global skiprequests, skipusers
        row = sqliteread('''SELECT id, name, song, key FROM songs ORDER BY id ASC''') # Pick the top song
        try:
            self.songtitle = row[2]
            songkey = row[3]
        except Exception as e:
            time.sleep(0.4)
            return
        sqlitewrite(('''DELETE FROM songs WHERE id={0}''').format(row[0]))  # Delete the top song

        if validators.url(self.songtitle) == True: # TEST IF THE REQUEST IS A LINK
            if "youtu" in self.songtitle:  # IS IT A YOUTUBE LINK?
                try:
                    yt = YouTube(self.songtitle)
                    playurl = yt.streams.filter(only_audio=True).order_by('abr').first().url
                    self.songtitle = yt.title
                except Exception as e:
                    print("Pytube Error:")
                    print(e)
                writenowplaying(True, self.songtitle)
            else:  # If not YT link, play normal music file.
                playurl = self.songtitle
                self.songtitle = "Online Music File"
                writenowplaying(True, self.songtitle)
        else:  # Otherwise it's GPM
            playurl = sr_geturl(songkey)
            writenowplaying(True, self.songtitle)
        self.instance = vlc.Instance()
        self.p = self.instance.media_player_new(playurl)  # Play the music
        self.p.play()
        saveAlbumArt(songkey)
        writenowplaying(True, self.songtitle)
        createsongqueue()
        skiprequests = 0
        skipusers = []
        return True

    def songover(self):
        print("Song is over!")
        time.sleep(DELAY_BETWEEN_SONGS)
        self.p.stop()
        return False

    def gettime(self):
        return int(self.p.get_time())

    #-------------------------SONG REQUEST COMMANDS----------------------------------

    def volume(self, vol, user):
        try:
            if vol == None:
                return "Current volume: " + str(self.p.audio_get_volume())
            if (vol > 100) or (vol < 0):
                return "Invalid volume level. Must be between 0-100."
            self.p.audio_set_volume(vol)
            return "Music volume set to: " + str(vol)
        except AttributeError:
            return "Music needs to be playing before adjusting the volume."

    def volumeup(self, vol, user):
        try:
            if not vol:
                vol = VOL_INCREMENT
            currentvolume = self.p.audio_get_volume()
            if (currentvolume + vol) > 100:
                self.p.audio_set_volume(100)
                print ("Raised the volume to: 100")
                return "Raised the volume to: 100"
            self.p.audio_set_volume(currentvolume + vol)
            self.msg = "Raised the volume to: " + str(currentvolume + vol)
            print((self.msg))
            return self.msg
        except AttributeError:
            return "Music needs to be playing before adjusting the volume."

    def volumedown(self, vol, user):
        try:
            if not vol:
                vol = VOL_INCREMENT
            currentvolume = self.p.audio_get_volume()
            if (currentvolume - vol) < 0:
                self.p.audio_set_volume(0)
                print ("Lowered the volume to: 0")
                return "Lowered the volume to: 0"
            self.p.audio_set_volume(currentvolume - vol)
            self.msg = "Lowered the volume to: " + str(currentvolume - vol)
            print((self.msg))
            return self.msg
        except AttributeError:
            return "Music needs to be playing before adjusting the volume."

    def play(self):
        print ("Resumed the music")
        writenowplaying(True, self.songtitle)
        self.p.set_pause(False)

    def pause(self):
        print ("Paused the music")
        writenowplaying(False, "")
        self.p.set_pause(True)

class SRcommands:
    def __init__(self):
        self.db = None
        self.video = None
        global skiprequests, skipusers
        skiprequests = 0
        skipusers = []

    '''--------------------SONG REQUEST--------------------'''

    def songrequest(self, request, user):
        if request == "\r":  # Send a message if they request nothing
            return user + " >> " + DEFAULT_SR_MSG
        # Check for songs already in the queue
        if sqliteread('''SELECT count(*) FROM songs WHERE name="{0}"'''.format(user))[0] > (MAX_REQUESTS_USER - 1):
            return user + " >> You already have " + str(MAX_REQUESTS_USER) + " songs in the queue."

        request = request.replace("\r", "")[1:]
        # LINKS
        # DETERMINE LINK TYPE
        if validators.url(request):
            if "youtu" in request:
                key = getytkey(request)
                if not key: return "Something is wrong with your Youtube link."

                # Check the queue to see if the song is already in there.
                self.db = sqliteread('''SELECT id, count(*) FROM songs WHERE key="{0}"'''.format(key))

                if self.db[1] > (MAX_DUPLICATE_SONGS - 1):
                    return user + " >> That song is already in the queue."

                try:
                    self.video = YouTube(request)
                except:
                    return user + " >> That video is unavailable, it's probably age restricted."

                songtime = self.getsongtime(request, key)
                if songtime > (MAXTIME * 60000):
                    return user + " >> That song exceeds the maximum length of " + str(MAXTIME) + " minutes."

                title = self.video.title
                sqlitewrite('''INSERT INTO songs(name, song, key, time) VALUES("{user}", "{request}", "{key}", "{time}");'''.format(user=user, request=(request.replace('"', "'")), key=(key.replace('"', "'")), time=songtime))
                removetopqueue()
                return user + " >> Added: " + title + " to the queue (YT). ID: " + getnewentry()
            else:  # OTHER MP3 REQUESTS <<<<<<<
                if not MEDIA_FILE_ENABLE:
                    return user + " >> Online Media Links are disabled by the streamer, you'll need to request something else."

                songtime = self.getsongtime("Online", request)
                if songtime > (MAXTIME * 60000):
                    return user + " >> That song exceeds the maximum length of " + str(MAXTIME) + " minutes."

                sqlitewrite('''INSERT INTO songs(name, song, key, time) VALUES("{user}", "{request}", "{request}", "{time}");'''.format(user=user, request=(request.replace('"', "'")), time=songtime))
                removetopqueue()

                return user + " >> Added that link to the queue. ID: " + getnewentry()

        elif GPM_ENABLE:  # GOOGLE PLAY MUSIC STUFF
            try:
                top_song_result = songtitlefilter(request, 0)
                key = top_song_result['storeId']
                songtitle = str(top_song_result['artist'] + " - " + top_song_result['title'])
            # If theres an error (its unable to find the song) then announce it, otherwise write the song data to the db
            except IndexError:
                if YT_IF_NO_RESULT:
                    return self.youtubesr(request, user)
                else:
                    return user + " >> No results found for that song. Please try a different one."
            else:
                # Test if the song is already in the queue
                self.db = sqliteread('''SELECT id, count(*) FROM songs WHERE key="{0}"'''.format(key))
                if self.db[1] > (MAX_DUPLICATE_SONGS - 1):
                    return user + " >> That song is already in the queue."
                songtime = self.getsongtime(None, key)

                if songtime > (MAXTIME * 60000):
                    return user + " >> That song exceeds the maximum length of " + str(MAXTIME) + " minutes."

                # Add song to the queue
                sqlitewrite('''INSERT INTO songs(name, song, key, time) VALUES("{user}", "{request}", "{key}", "{time}");'''.format(user=user, request=(songtitle.replace('"', "'")), key=(key.replace('"', "'")), time=songtime))
                removetopqueue()
                return user + " >> Added: " + songtitle + " to the queue. ID: " + getnewentry()
        else:
            return self.youtubesr(request, user)

    def youtubesr(self, request, user):
        request = unidecode(request)
        try:
            results = (Mobileclient.search(api, request, SONGBLSIZE)['video_hits'])
            top_result = results[0]['youtube_video']
            video_url = "https://www.youtube.com/watch?v=" + top_result['id']
            key = top_result['id']
            title = top_result['title']
        except IndexError:
            try:
                self.video = YouTube("https://www.youtube.com/watch?v=" + request)
                return self.songrequest(" https://www.youtube.com/watch?v=" + request, user)
            except:
                return "No results at all"

        try:
            self.video = YouTube(video_url)
        except:
            return user + " >> That video is unavailable, it's probably age restricted."
        # Check the queue to see if the song is already in there.
        self.db = sqliteread('''SELECT id, count(*) FROM songs WHERE key="{0}"'''.format(key))
        if self.db[1] > (MAX_DUPLICATE_SONGS - 1):
            return user + " >> That song is already in the queue."
        songtime = self.getsongtime(video_url, key)
        if songtime > (MAXTIME * 60000):
            return user + " >> That song exceeds the maximum length of " + str(MAXTIME) + " minutes."

        sqlitewrite('''INSERT INTO songs(name, song, key, time) VALUES("{user}", "{request}", "{key}", "{time}");'''.format(user=user, request=(video_url.replace('"', "'")), key=(key.replace('"', "'")), time=songtime))
        removetopqueue()
        return user + " >> Added: " + title + " to the queue (YT). ID: " + getnewentry()

    '''--------------------QUEUE CONTROL--------------------'''

    def wrongsong(self, songid, user):
        if not songid:
            try:
                result = sqliteread('SELECT id, song FROM songs WHERE name="{0}"  ORDER BY id DESC LIMIT 1'.format(user))
                sqlitewrite('DELETE FROM songs WHERE id={0}'.format(str(result[0])))
                return user + ' >> Removed your request: "' + str(result[1]) + '" from the queue.'
            except Error as e:
                raise e
            except:
                return user + " >> Couldn't find your most recent request."
        else:
            try:
                result = sqliteread('SELECT song, name FROM songs WHERE id={0}'.format(songid))
                if user in result[1]:
                    sqlitewrite('DELETE FROM songs WHERE id={0}'.format(songid))
                    return user + ' >> Removed your request: "' + str(result[0]) + '" from the queue.'
                else:
                    return user + " >> You didn't request that song, you can't delete it!"
            except Error as e:
                raise e
            except:
                return user + " >> Couldn't find that request."

    def clearsong(self, songid, user):
        if not songid:
            try:
                result = sqliteread('SELECT id, song, name FROM songs ORDER BY id DESC LIMIT 1')
                sqlitewrite('DELETE FROM songs WHERE id={0}'.format(str(result[0])))
                return user + ' >> Removed the request: "' + str(result[1]) + '" requested by ' + str(result[2]) + " from the queue."
            except Error as e:
                raise e
            except:
                return "Something messed up. Is the queue empty?"
        else:
            try:
                result = sqliteread('SELECT song, name FROM songs WHERE id={0}'.format(songid))
                sqlitewrite('DELETE FROM songs WHERE id={0}'.format(songid))
                return user + ' >> Removed the request: "' + str(result[0]) + '" requested by ' + str(result[1]) +" from the queue."
            except Error as e:
                raise e
            except:
                return user + " >> Couldn't find that request."

    def queuetime(self, id, user):
        data = []
        db = sqlite3.connect('songqueue.db')
        try:
            cursor = db.cursor()
            if not id:  # If there's no ID, get the total song
                cursor.execute('''SELECT time FROM songs''')
            else:  # Get up to that song
                cursor.execute('''SELECT time FROM songs WHERE id < {0}'''.format(id))
            data = cursor.fetchall()
            if (not data) or (data[0][0] == None):
                if id:
                    return user + " >> That ID is not in the queue."
                else:
                    return user + " >> There are currently no songs in the queue."
            totaltime = 0
            for item in data:
                totaltime += int(item[0])
            seconds=(totaltime/1000)%60
            minutes=(totaltime/(1000*60))%60
            hours=(totaltime/(1000*60*60))%24
            db.close()
            return user + " >> There is about " + str(hours) + "h " + str(minutes) + "m " + str(seconds) + "s of songs in the queue."
        except Error as e:
            db.rollback()
            print ("QUEUETIME ERROR:")
            print (e)

    def skip(self, user, x):
        global skiprequests, skipusers
        from Run import veto

        if user in skipusers:
            return user + " >> You've already requested to skip this song."
        #Do the stuff to process the skip
        skipusers.append(user)
        skiprequests += 1

        if skiprequests >= VOTES_TO_SKIP:
            veto(None, None)
            return user + " >> Your vote to skip was enough to skip the song."

    '''--------------------BACKUP PL CONTROL--------------------'''

    def plsongrequest(self, request, user):
        request = request.replace("\r", "")[1:]
        # LINKS
        # DETERMINE LINK TYPE
        if validators.url(request):
            if "youtu" in request:
                try:
                    title = YouTube(request).title
                except Exception: return user + " >> Unable to use that video for some reason."
                key = getytkey(request)
                if not key: return user + " >> Something is wrong with your Youtube link."

                # Check the queue to see if the song is already in there.
                self.db = sqliteread('''SELECT id, count(*) FROM playlist WHERE key="{0}"'''.format(key))
                if self.db[1] > (MAX_DUPLICATE_SONGS - 1):
                    return user + " >> That song is already in the playlist. ID: " + str(self.db[0])
                sqlitewrite('''INSERT INTO playlist(song, key) VALUES("{request}", "{key}");'''.format(request=(request.replace('"', "'")), key=(key.replace('"', "'"))))
                return user + " >> Added: " + title + " to the playlist (YT). ID: " + str(sqliteread('SELECT id FROM playlist ORDER BY id DESC LIMIT 1')[0])
            else:  # OTHER MP3 REQUESTS <<<<<<<
                sqlitewrite('''INSERT INTO playlist(song, key) VALUES("{request}", "{request}");'''.format(request=(request.replace('"', "'"))))
                return user + " >> Added that link to the playlist. ID: " + str(sqliteread('SELECT id FROM playlist ORDER BY id DESC LIMIT 1')[0])
        else:  # GOOGLE PLAY MUSIC STUFF
            try:
                top_song_result = songtitlefilter(request, 0)
                key = top_song_result['storeId']
                songtitle = str(top_song_result['artist'] + " - " + top_song_result['title'])
            # If theres an error (its unable to find the song) then announce it, otherwise write the song data to the db
            except IndexError:
                return user + " >> No results found for that song. Please try a different one."
            else:
                # Test if the song is already in the playlist
                self.db = sqliteread('''SELECT id, count(*) FROM playlist WHERE key="{0}"'''.format(key))
                if self.db[1] > (MAX_DUPLICATE_SONGS - 1):
                    return user + " >> That song is already in the playlist. ID: " + str(self.db[0])
                # Add song to the playlist
                sqlitewrite('''INSERT INTO playlist(song, key) VALUES("{request}", "{key}");'''.format(request=(songtitle.replace('"', "'")), key=(key.replace('"', "'"))))
                return user + " >> Added: " + songtitle + " to the playlist. ID: " + str(sqliteread('SELECT id FROM playlist ORDER BY id DESC LIMIT 1')[0])

    def plclearsong(self, songid, user):
        if not songid:
            try:
                result = sqliteread('SELECT id, song FROM playlist ORDER BY id DESC LIMIT 1')
                sqlitewrite('DELETE FROM playlist WHERE id={0}'.format(str(result[0])))
                return user + ' >> Removed your request: "' + str(result[1]) + '" from the backup playlist.'
            except Exception as e:
                print (e)
                return user + " >> Couldn't find the most recent request."
        else:
            try:
                result = sqliteread('SELECT song FROM playlist WHERE id={0}'.format(songid))
                sqlitewrite('DELETE FROM playlist WHERE id={0}'.format(songid))
                return user + ' >> Removed the song: "' + str(result[0]) + " from the queue."
            except Error as e:
                raise e
            except:
                return user + " >> Couldn't find that request."

    '''--------------------MISC--------------------'''

    def getnowplaying(self, x, user):
        with open("Output/nowplaying.txt", "r") as f:
            returnnp = f.readlines()
        if not returnnp:
            sendMessage(s, (user + " >> The music is currently paused."))
        else:
            sendMessage(s, (user + " >> " + returnnp[0]))

    def clearqueue(self, x, y):
        try:
            sqlitewrite('DELETE FROM songs')
            return "Cleared the current songrequest queue"
        except:
            return "There was some sort of issue clearing the queue."

    def queuelink(self, user, x):
        return user + " >> " + QUEUE_LINK

    def getsongtime(self, title, key):
        songtime = -1
        try:
            if title:
                if title == "Online":
                    songurl = key
                else:
                    songurl = self.video.streams.filter(only_audio=True).order_by('abr').first().url
            else:  # Otherwise it's GPM
                songurl = sr_geturl(key)
            instance = vlc.Instance()
            media = instance.media_new(songurl)
            player = instance.media_player_new()
            player.set_media(media)
            #Start the parser
            media.parse_with_options(1,0)
            cycle = 0
            while True:
                cycle += 1
                if str(media.get_parsed_status()) == 'MediaParsedStatus.done':
                    break
                if cycle > 99999999:
                    print ("CRITICAL ERROR - GETSONGTIME IS BROKEN!")
                    break
            songtime = media.get_duration()
        # Let it be known to whatever brave adventurer is exploring my code, that this is the place that
        # Grant's sanity died for nearly two weeks straight.
        except Exception as e:
            print ("GETSONGTIME ISSUE")
            print (e)
            return
        return (songtime - 2000) #Most songs have a short offset.


# OPENING FILE

file_object = open("code sample beginners/test.txt", "r")

lines = []
for line in file_object:
    lines.append(line)
file_object.close()

print(lines)

"""
We can name the file_object any other name, the text.txt is the file
and it is located in the same path as our file.py file.
The r is telling the interpreter we are reading the file.
"""


from hamcrest import assert_that, equal_to

from nodestream.pipeline.value_providers import StringFormattingValueProvider

from ...stubs import StubbedValueProvider

def test_string_format(blank_context):
    subject = StringFormattingValueProvider(
        fmt="{a}{b}", a=StubbedValueProvider(["a"]), b=StubbedValueProvider(["b"])
    )
    assert_that(subject.single_value(blank_context), equal_to("ab"))

def test_string_format_many(blank_context):
    subject = StringFormattingValueProvider(
        fmt="{a}{b}", a=StubbedValueProvider(["a"]), b=StubbedValueProvider(["b"])
    )
    assert_that(subject.many_values(blank_context), equal_to(["ab"]))


from tkinter import *
from tkinter import filedialog
from tkinter import messagebox

root = Tk()
root.title('Untitled - Notepad')

cut_copy = None
file_name = None

def new(event):
    text.delete(1.0, END)
    root.title('Untitled - Notepad')
    status_bar.configure(text='Unsaved    ')

def open_file(event):
    global file_name
    file_name = filedialog.askopenfilename(filetypes=(('Python Files', '*.py'), ('Text Files', '*.txt'), ('All Files', '*.*')))
    if file_name:
        text.delete(1.0, END)
        name = file_name.split('/')[-1]
        root.title(f'{name} - Notepad')
        with open(file_name, 'r') as file:
            text.insert(END, file.read())
        status_bar.configure(text='Saved    ')

def save_as(event):
    global file_name
    file_name = filedialog.asksaveasfilename(filetypes=(('Python Files', '*.py'), ('Text Files', '*.txt'), ('All Files', '*.*')))
    if file_name:
        name = file_name.split('/')[-1]
        root.title(f'{name} - Notepad')
        with open(file_name, 'w') as file:
            file.write(text.get(1.0, END)[:-1])
        status_bar.configure(text='Saved    ')

def save(event):
    if root.title() == 'Untitled - Notepad':
        save_as(None)
    else:
        with open(file_name, 'w') as file:
            file.write(text.get(1.0, END)[:-1])
    status_bar.configure(text='Saved    ')

def cut(event):
    global cut_copy
    if event:
        cut_copy = root.clipboard_get()
    elif text.selection_get():
        cut_copy = text.selection_get()
        root.clipboard_clear()
        root.clipboard_append(cut_copy)
        text.delete('sel.first', 'sel.last')

def copy(event):
    global cut_copy
    if event:
        cut_copy = root.clipboard_get()
    elif text.selection_get():
        cut_copy = text.selection_get()
        root.clipboard_clear()
        root.clipboard_append(cut_copy)

def paste(event):
    global cut_copy
    if event:
        cut_copy = root.clipboard_get()
    elif cut_copy:
        pos = text.index(INSERT)
        text.insert(pos, cut_copy)

def select_all():
    text.tag_add('sel', '1.0', 'end')

def dark_mode(event):
    text.configure(bg='#1f1d1d', fg='white', insertbackground='white', selectbackground='white', selectforeground='black')
    file_menu.configure(bg='#1f1d1d', fg='white')
    edit_menu.configure(bg='#1f1d1d', fg='white')
    selection_menu.configure(bg='#1f1d1d', fg='white')
    view_menu.configure(bg='#1f1d1d', fg='white')
    help_menu.configure(bg='#1f1d1d', fg='white')

def light_mode(event):
    text.configure(bg='white', fg='black', insertbackground='black', selectbackground='black', selectforeground='white')
    file_menu.configure(bg='SystemButtonFace', fg='black')
    edit_menu.configure(bg='SystemButtonFace', fg='black')
    selection_menu.configure(bg='SystemButtonFace', fg='black')
    view_menu.configure(bg='SystemButtonFace', fg='black')
    help_menu.configure(bg='SystemButtonFace', fg='black')

def about():
    messagebox.showinfo('About', 'Notepad by Har0106')

def refresh_status():
    if file_name:
        with open(file_name, 'r') as file:
            if file.read() == text.get(1.0, 'end-1c'):
                status_bar.configure(text='Saved    ')
            else:
                status_bar.configure(text='Unsaved    ')
    root.after(1000, refresh_status)

frame = Frame(root)
frame.pack()

text_scroll_y = Scrollbar(frame)
text_scroll_x = Scrollbar(frame, orient='horizontal')
text_scroll_y.pack(fill='y', side='right')
text_scroll_x.pack(fill='x', side='bottom')
text = Text(frame, font='Consolas 15', undo=True, yscrollcommand=text_scroll_y.set, xscrollcommand=text_scroll_x.set, height=22, width=82, selectbackground='black', selectforeground='white', wrap='none')
text.pack()
text_scroll_y.configure(command=text.yview)
text_scroll_x.configure(command=text.xview)

status_bar = Label(root, text='Unsaved    ', relief='groove', anchor='e', bg='#808080')
status_bar.pack(fill='x', side='bottom')

menu = Menu(frame)
root.configure(menu=menu)

file_menu = Menu(menu, tearoff=False, fg='black')
menu.add_cascade(label='File', menu=file_menu)
file_menu.add_command(label='New', accelerator='Ctrl+N', command=lambda: new(None))
root.bind('<Control-n>', new)
file_menu.add_command(label='Open', accelerator='Ctrl+O', command=lambda: open_file(None))
root.bind('<Control-o>', open_file)
file_menu.add_separator()
file_menu.add_command(label='Save', accelerator='Ctrl+S', command=lambda: save(None))
root.bind('<Control-s>', save)
file_menu.add_command(label='Save As        ', accelerator='Ctrl+Shift+S', command=lambda: save_as(None))
root.bind('<Control-Shift-S>', save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', command=root.destroy)

edit_menu = Menu(menu, tearoff=False, fg='black')
menu.add_cascade(label='Edit', menu=edit_menu)
edit_menu.add_command(label='Undo       ', accelerator='Ctrl+Z')
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y')
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X', command=lambda: cut(None))
root.bind('<Control-x>', cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C', command=lambda: copy(None))
root.bind('<Control-c>', copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V', command=lambda: paste(None))
root.bind('<Control-v>', paste)

selection_menu = Menu(menu, tearoff=False, fg='black')
menu.add_cascade(label='Selection', menu=selection_menu)
selection_menu.add_command(label='Select All       ', accelerator='Ctrl+A', command=select_all)

view_menu = Menu(menu, tearoff=False, fg='black')
menu.add_cascade(label='View', menu=view_menu)
view_menu.add_command(label='Dark Mode       ', accelerator='Ctrl+Alt+D', command=lambda: dark_mode(None))
root.bind('<Control-Alt-d>', dark_mode)
view_menu.add_command(label='Light Mode       ', accelerator='Ctrl+Alt+L', command=lambda: light_mode(None))
root.bind('<Control-Alt-l>', light_mode)

help_menu = Menu(menu, tearoff=False, fg='black')
menu.add_cascade(label='Help', menu=help_menu)
help_menu.add_command(label='About       ', command=about)

refresh_status()
root.mainloop()


import os, time, sys

arraySize = 0
incrementSize = 5000
arrayMax = 1000000
testLanguage = sys.argv[1]

if testLanguage == "":
    print("\n*** Gotta enter a language ***")
    sys.exit(0)

#it will test the language from 0 to arrayMax
while arraySize <= arrayMax:
    print("\n*** TESTING %s WITH ARRAY SIZE %s ***" % (testLanguage.upper(), str(arraySize).upper()))
    os.system("test 1 " + str(arraySize) + " " + testLanguage)
    arraySize += incrementSize


# Varun Shourie, CIS345, Tuesday/Thursday, 12:00PM-1:15PM, A8

from tkinter import *
from tkinter import font
from tkinter import messagebox
from socket import *
from threading import Thread

def validate_keypress(event):
    """Restricts the key presses the user can make when entering the ip address for the application."""
    valid_keys = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', '\b', '']

    if event.char not in valid_keys:
        return "break"

def connect():
    """Connects to the server located on the user provided IP address, port 49000, resizing the window to include the
    newly placed chat widgets like the listbox, entry, and send button. Furthermore, a thread is started to handle
    receiving all messages for the chat client."""
    global sock, ip_address, screen_name, toggle_connection_button, window, chat_frame, PORT
    ip_addr = ip_address.get()
    scrn_name = screen_name.get()

    # IP address name should be at minimum '0.0.0.0' (7 chars) and the screen name should not be blank.
    if len(ip_addr) > 6 and scrn_name != '':
        try:
            addr = (ip_addr, PORT)
            sock = socket(AF_INET, SOCK_STREAM)
            sock.connect(addr)
            sock.send(scrn_name.encode())
        except:
            sock.close()
            sock = None
        else:
            x = Thread(target=receive_message, daemon=True)
            x.start()

        window.geometry('450x455')
        toggle_connection_button.config(bg='gold', text='Disconnect', command=disconnect)
        chat_frame.grid(row=3, column=0, columnspan=2, sticky=N+S+W+E, padx=10)
    else:
        messagebox.showinfo(title='Error', message='Please enter both an IP address with four numbers between 0 to 255 '
                                                   + 'separated by a period (.) and at least one character for your '
                                                   + 'desired screen name.')

def disconnect():
    """Whenever the user presses the disconnect button while in an active chat session, the client sends an exit
    sequence to the server to signal it is closing; the window is resized to exclude the chat section, and the
    disconnect button is toggled to "connect" to signal the GUI is not connected to the localhost server."""
    global sock, ip_address, screen_name, toggle_connection_button, window, chat_frame, EXIT

    try:
        if sock:
            sock.send(EXIT.encode())
    except:
        pass
    finally:
        if sock:
            sock.close()
        sock = None

    toggle_connection_button.config(bg='SystemButtonFace', text='Connect', command=connect)
    chat_frame.grid_forget()
    window.geometry('450x100')
    ip_address.set('')
    screen_name.set('')

def receive_message():
    """Handles receiving all messages for one chat client by inserting them into the listbox as they are received
    from other clients through the server. If there is no message from the server, the chat client will disconnect
    from the server."""
    global sock, screen_name, msg_listbox, BUFSIZE

    while True:
        try:
            received_msg = sock.recv(BUFSIZE)
        except OSError:
            received_msg = None
            break
        if not received_msg:
            disconnect()
            break
        msg_listbox.insert(END, received_msg.decode())

def send_message():
    """If the user's message is not blank, the function sends the user's message from the chat client to the server,
    which will distribute it to other clients. If the user types the exit sequence, the chat client will cease."""
    global sock, message, EXIT
    msg = message.get()
    if msg == EXIT:
        disconnect()
    elif msg != '':
        try:
            if sock:
                sock.send(msg.encode())
        except OSError:
            disconnect()
    message.set('')

def window_closing():
    """Disconnects the socket if not done already before closing the window."""
    global sock
    if sock:
        disconnect()
    window.quit()

PORT = 49000
EXIT = '[Q]'
BUFSIZE = 1024

# Variables used to display, send, and receive chat data throughout the entire application.
sock = socket(AF_INET, SOCK_STREAM)
window = Tk()
window.geometry('450x100')
window.title('CIS IM Client')
app_font = font.Font(family='Arial', size=12)
ip_address = StringVar()
screen_name = StringVar()
message = StringVar()

# Widgets used to intake server IP address and the user's screen name.
ip_label = Label(window, text='Server IP:', font=app_font)
ip_label.grid(row=0, column=0, sticky=W, padx=10)
screen_name_label = Label(window, text='Screen Name:', font=app_font)
screen_name_label.grid(row=1, column=0, sticky=W, padx=10)
ip_textbox = Entry(window, textvariable=ip_address, font=app_font, width=33)
ip_textbox.grid(row=0, column=1, sticky=E, padx=10)
ip_textbox.bind('<Key>', validate_keypress)
screen_textbox = Entry(window, textvariable=screen_name, font=app_font, width=33)
screen_textbox.grid(row=1, column=1, sticky=E, padx=10)

# Toggles between connection/disconnection from the chat server.
toggle_connection_button = Button(window, text='Connect', font=app_font, width=46, command=connect)
toggle_connection_button.grid(row=2, column=0, columnspan=2, pady=5)

# Section of the chat client which contains all messages from the user and other users present in the chat.
chat_frame = Frame(window, width=435, background='maroon')
msg_frame = Frame(chat_frame, width=408, height=300, background='maroon')
msg_frame.grid(row=0, column=0, columnspan=2, padx=10, pady=10)
msg_frame.pack_propagate(0)
scrollbar = Scrollbar(msg_frame)
msg_listbox = Listbox(msg_frame, yscrollcommand=scrollbar.set, font=app_font, width=43)
msg_listbox.pack(fill=BOTH, side=LEFT)
scrollbar.config(command=msg_listbox.yview)
scrollbar.pack(fill=Y, side=RIGHT)

# Widgets used to compose and send messages to other users on the chat hosted by the server.
msg_textbox = Entry(chat_frame, textvariable=message, width=37, font=app_font)
msg_textbox.grid(row=1, column=0, sticky=W, padx=10, pady=10)
send_button = Button(chat_frame, text='Send', font=app_font, command=send_message, bg='gold')
send_button.grid(row=1, column=1, sticky=E, padx=10)

window.protocol('WM_DELETE_WINDOW', window_closing)
window.mainloop()


############################################
#Treatment
############################################

import arcpy

##T1##
#SA of 300m was identified from existing TX, given they do not reach injection TX. If they reach an injection TX, the SA stops.

#Set local variables
district = "NAME OF DISTRICT"
LV_lines = "PATH TO LV LINES"
Existing_TX = "PATH TO EXISTING TX LAYER"
Injection_TX = "PATH TO INJECTION TX LAYER"
Feeders = "PATH TO FEEDERS LAYER"
network = "PATH TO NETWORK DATASET OF DISTRICT"
distance_from_line = "25"
district_siteID_range = 200

#existing TX service area
Existing_TX_SA = arcpy.na.MakeServiceAreaLayer (network, "Existing_TX Service Area", "Length", "TRAVEL_FROM", "300" , "DETAILED_POLYS", "MERGE" , "DISKS", "NO_LINES" , "NON_OVERLAP", "NO_SPLIT", Feeders , "", "", "", "TRIM_POLYS", distance_from_line)
Existing_TX_SA = Existing_TX_SA.getOutput(0)

#Load Elements
arcpy.na.AddLocations (Existing_TX_SA, "Facilities", Existing_TX, "field mapping", "25 Meters")
arcpy.na.AddLocations (Existing_TX_SA, "Point Barriers", Injection_TX, "field mapping", "25 Meters")

#Solve
arcpy.na.Solve(Existing_TX_SA,"SKIP")
#CHECK FOR ERRORS

#Export polygon layer
Existing_TX_Polygons = arcpy.SelectData_management (Existing_TX_SA, "Polygons")

##T2##
#SA of 200m was drawn from the injection TX sites.
#Setting existing TX SA as a barrier prevents the SA made in the previous step from being crossed or considered as a valid injection TX SA.
#This method allows to include LV lines that extend from the injection TX, are terminal,
#and can be most directly attributed to the injection TX to be prioritized as treatment sites.

Treatment_SA = arcpy.na.MakeServiceAreaLayer (network, district+"_Treatment_SA", "Length", "TRAVEL_FROM", "200" , "DETAILED_POLYS", "NO_MERGE" , "DISKS", "NO_LINES" , "NON_OVERLAP", "NO_SPLIT", Feeders , "", "", "", "TRIM_POLYS", distance_from_line)
Treatment_SA = Treatment_SA.getOutput(0)

#Load Elements
arcpy.na.AddLocations (Treatment_SA, "Facilities", Injection_TX, "", "25 Meters")
arcpy.na.AddLocations (Treatment_SA, "Polygon Barriers", Existing_TX_Polygons, "", "25 Meters")

#Solve
arcpy.na.Solve(Treatment_SA,"SKIP")
#CHECK FOR ERRORS

#Save Injection transformers which were restricted by existing transformers
Injection_TX_restricted = arcpy.SelectData_management (Treatment_SA, "Facilities")
Injection_TX_restricted = arcpy.SelectLayerByAttribute_management (Injection_TX_restricted, "NEW_SELECTION",'"Status"= 3' )
arcpy.MakeFeatureLayer_management(Injection_TX_restricted,"Injection_TX_restricted")

#Export polygon layer
Treatment_Polygons = arcpy.SelectData_management (Treatment_SA, "Polygons")
Treatment_Polygons = Treatment_Polygons.getOutput(0)
Treatment_Polygons_withArea = arcpy.CalculateAreas_stats (Treatment_Polygons, "Treatment_Polygons")

#arcpy.MakeFeatureLayer_management(Treatment_Polygons_withArea,"Treatment_Polygons_Standard",'"F_AREA" >= 10000' )
arcpy.MakeFeatureLayer_management(Treatment_Polygons_withArea,"Treatment_Polygons_Small",'"F_AREA" <= 10000' )

##T3##
#It is possible that the resulting polygon from the previous step is <10,000 sq meters or
#if an injection TX is completely engulfed in existing TX SA.
#In this case, a new SA is drawn extending 150m from the injection TX in all possible directions.
#This was the case with 3 treatment sites in Dansoman.

if arcpy.management.GetCount('Treatment_Polygons_Small')[0] > "0":
	Injection_TX_Alt = arcpy.SelectLayerByLocation_management (Injection_TX, "INTERSECT", 'Treatment_Polygons_Small', "15 Meters")
	arcpy.MakeFeatureLayer_management(Injection_TX_Alt,"Injection_TX_Alt")
	#Injection_TX_Alt = Injection_TX_Alt.getOutput(0)
	Treatment_Alt_SA = arcpy.na.MakeServiceAreaLayer (network, district+"_Treatment_Alt_SA", "Length", "TRAVEL_FROM", "150" , "DETAILED_POLYS", "NO_MERGE" , "DISKS", "NO_LINES" , "NON_OVERLAP", "NO_SPLIT", Feeders , "", "", "", "TRIM_POLYS", distance_from_line)
	#Treatment_Alt_SA = Treatment_Alt_SA.getOutput(0)
	arcpy.na.AddLocations (Treatment_Alt_SA, "Facilities", Injection_TX_Alt, "", "25 Meters")
	arcpy.na.AddLocations (Treatment_Alt_SA, "Facilities", Injection_TX_restricted, "", "25 Meters")
	arcpy.na.Solve(Treatment_Alt_SA,"SKIP", "CONTINUE")
	#CHECK FOR ERRORS
	Treatment_Polygons_Alt = arcpy.SelectData_management (Treatment_SA, "Polygons")
	Treatment_Polygons_Alt = arcpy.MakeFeatureLayer_management(Treatment_Polygons_Alt, "Treatment_Polygons_Alt")
	#arcpy.SaveToLayerFile_management (Treatment_Polygons_Alt, "Treatment_Polygons_Alt")

else:
	Treatment_Polygons_Standard = arcpy.MakeFeatureLayer_management(Treatment_Polygons_withArea,"Treatment_Polygons_Standard",'"F_AREA" >= 10000' )

##T4##
#The result is area outlines either containing or directly adjacent to an Injection TX.
#Centroid coordinates are given to each site for feild staff to locate each site

#Collect all sites into 1 layer
arcpy.Merge_management ([Treatment_Polygons_Standard, Treatment_Polygons_Alt], "Treatment_Sites")

##Visually Inspect Results. Check To Make Sure all requirements are met. If not, then create polygons of outliers mannually

#Calculate site centroids
arcpy.AddGeometryAttributes_management('Treatment_Sites',"CENTROID")

#Adding Site IDs may be done mannually
#arcpy.AddField_management('Treatment_Sites',"Site_ID", "TEXT","" ,"",50,"","","","")
#arcpy.CalculateField_management('Treatment_Sites',"Site_ID", '!OBJECTID' + district_siteID_range, "PYTHON","")

arcpy.FeatureClassToShapefile('Treatment_Sites', "C:/PATH/folder")

###########END##########


import config
import telebot
import logic
import time
from telebot import types

bot = telebot.TeleBot(config.token)
chats = {}
logic.load_sentences()

markup = types.ReplyKeyboardMarkup()

btn1 = types.KeyboardButton('Ваш сном?')
btn2 = types.KeyboardButton('Нет время сна.')
btn3 = types.KeyboardButton('У меня солидный.')

markup.add(btn1, btn2, btn3)

u_menya_solidnyi = logic.normalize_sentence("Life является странным")

@bot.message_handler(content_types=["text"])
def handle_text_message(message):

    chat_id = message.chat.id

    normalized_message_text = logic.normalize_sentence(message.text)

    if u_menya_solidnyi <= normalized_message_text:
        bot.send_message(chat_id, 'Выберите возвращение, которое отражает их слова на них:', reply_markup=markup)
        return

    if chat_id not in chats:
        chats[chat_id] = {}

    logic.add_sentence(message.text)
    answer = logic.get_random_answer(message.text)

    if "previous_text" in chats[chat_id]:
        if chats[chat_id]["previous_user"] != message.from_user.id:

            previous_text = chats[chat_id]["previous_text"]
            logic.add_answer(previous_text, message.text)

    if answer:
        bot.send_message(chat_id, answer)
        chats[chat_id]["previous_text"] = answer
        chats[chat_id]["previous_user"] = 'yarkiybot'
    else:
        chats[chat_id]["previous_text"] = message.text
        chats[chat_id]["previous_user"] = message.from_user.id

if __name__ == '__main__':
     while True:
        try:
            bot.polling(none_stop=True)
        except Exception as e:
            print(e)
            time.sleep(5)
        finally:
            logic.dump_sentences()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 14 12:10:29 2022

@author: Elie
"""

import re

##############################################
#                                            #
#  Module d'entrées sortie au format dimacs  #
#                                            #
##############################################

"""
    Méthode qui lit un fichier dimacs contenant une CNF l'ensemble des clauses
    Renvoie un couple dont
          le premier élément est le nombre de variables distinctes
          le deuxième élément est une liste de clauses
"""
def lireCNFDimacs(nom_fichier):
    # Ouverture du fichier
    f = open(nom_fichier, 'r')

    # on saute les lignes de commentaires
    line = f.readline()
    while line[0] == 'c':
        line = f.readline()

    # On lit la déclaration du formalise
    expr = re.search("p cnf ([0-9]*) ([0-9]*)", line)
    nb_variables = int(expr.group(1))
    nb_clauses   = int(expr.group(2))

    # lectures des clauses
    clauses = []

    # Pour chaque ligne représentant une clause
    for _ in range(nb_clauses):
        line = f.readline()                       # On lit la ligne
        clause = re.findall("(-?[0-9]+) ", line)  # On recupère tous les entiers
        clause = list(map(lambda x: int(x), clause)) # STR -> INT
        clauses.append(clause)                    # On ajoute la clause

    # Fermeture du fichier
    f.close()

    # le retour
    return (nb_variables, clauses)

"""
    Méthode qui lit un fichier dimacs contenant une solution SAT
    Renvoie un couple dont
          le premier élément est le nombre de variables distinctes
          le deuxième élément est une liste de de littéraux
"""
def lireSAT(nom_fichier):
    # Ouverture du fichier
    f = open(nom_fichier, 'r')

    # on saute les lignes de commentaires
    line = f.readline()
    while line[0] != 'v':
        line = f.readline()

    # on recupère les littéraux et on convertit
    litteraux = re.findall("(-?[0-9]+) ", line)
    litteraux = list(map(lambda x: int(x), litteraux))

    # Fermeture du fichier
    f.close()

    # le retour
    return litteraux

"""
    Méthode qui écrit dans le fichier indiqué l'ensemble des clauses fournies
    au format DICMACS (CNF)
"""
def ecrireCNFDimacs(nb_var, clauses, nom_fichier):
    # Ouverture du fichier
    f = open(nom_fichier, 'w')

    # ENTETE COMMENTAIRES
    f.write("c \n")
    f.write("c TAKUZU PB\n")
    f.write("c E.C. L.D.M. A.K\n")
    f.write("c " + nom_fichier + "\n")
    f.write("c \n")

    # DECLARATION DU FORMALISME
    nb_clauses = len(clauses)  # nb de clauses
    f.write("p cnf " + str(nb_var) + " " + str(nb_clauses) + "\n")

    # ECRITURE DES CLAUSES MODELISANTS LES REGLES
    for clause in clauses:       # Pour chaque clause
        for lit in clause:
            f.write(str(lit) + " ")   # On écrit chaque littéral
        f.write("0\n")                # Et on ferme la clause

    # Fermeture du fichier
    f.close()

"""
    Méthode qui écrit les nb_litt premiers littéraux de l'ensemble fournis
    dans le fichier indiqué
"""
def ecrireSAT(nom_fichier, litteraux, nb_litt = -1):
    # Ouverture du fichier
    f = open(nom_fichier, 'w')

    # ENTETE COMMENTAIRES
    f.write("c \n")
    f.write("c TAKUZU SOL\n")
    f.write("c E.C. L.D.M. A.K\n")
    f.write("c " + nom_fichier + "\n")
    f.write("c \n")

    # declaration du fichier
    f.write("s SATISFIABLE\n")
    f.write("v ")

    # On affiche tous les littéraux
    if nb_litt == -1:
        nb_litt = len(litteraux)

    # On ecrit chaque littéral
    for i in range(nb_litt):
        f.write(str(litteraux[i]) + " ")

    # Et on ferme la solution
    f.write("0\n")

    # Fermeture du fichier
    f.close()


import tkinter as tk
from tkinter import *

class book_page:
    def __init__(self,root):
        self.root=Frame(root,width=1360,height=768).pack()

        self.b=PhotoImage(file = "lib.png")
        self.label=Label(self.root,image=self.b).place(x=0,y=0)

        self.c=PhotoImage(file = "book3.png")
        self.B=Button(self.root,image=self.c).place(x=250,y=300)

        self.d=PhotoImage(file = "update2.png")
        self.B1=Button(self.root,image=self.d).place(x=600,y=300)

        self.e=PhotoImage(file = "search1.png")
        self.B2=Button(self.root,image=self.e,command=self.click2).place(x=950,y=300)

        self.w=PhotoImage(file = "home1.png")
        self.label=Button(self.root,image=self.w,text='DAWN LIBRARY',command=self.click1).place(x=0,y=0)
    def click(self):
        import lib_m2
        return
    def click1(self):
        import Home_page
        return
    def click2(self):
        import book_search
        return

root=Frame(height=768,width=1360).pack()
d=book_page(root)


from picamera import PiCamera
from time import sleep

my_camera=PiCamera()
my_camera.resolution(1920,1080)
my_camera.vflip=True
my_camera.hflip=True

print('taking 5 photos...')

for i in range(5):
    print(i)
    sleep(2)
    my_camera.capture('image{0:03d}.jpg'.format(i))

print('done')


# 10804. 문자열의 거울상 D3
mirror = {
    'b': 'd', 'd': 'b', 'p': 'q', 'q': 'p'
}
T = int(input())
for tc in range(1, 1 + T):
    quest = input()
    answer = ''
# 문자열을 거꾸로 돌면서 딕셔너리 해당 값을 answer에 추가
    for i in range(len(quest)):
        answer += mirror[quest[-1-i]]
    print(f'#{tc} {answer}')


"""
Datos de entrada
edad del paciente  = edad = int
sexo del paciente = sexo_paciente = int

Datos de salida
Resultado positivo o negativo acerca de si el paciente tiene anemia = resultado = str

"""
# Entradas
edad_paciente=int(input("Inserte la edad del paciente en su equivalente de años a meses "))
sexo_paciente=str(input("Inserte su sexo de la siguiente manera , femenino (F) o masculino (M) "))
nivel_hemoglobina=float(input("Inserte cual fue el resultado del nivel de hemoglobina en la sangre "))
sexo= sexo_paciente[0] # Es la posicion del caracter que quiero que tome

# Caja Negra

resultado=''
if (nivel_hemoglobina>=13 and nivel_hemoglobina<=26) and(edad_paciente>=0 and edad_paciente<=1):
    resultado=(" El resultado es Negativo")
elif(nivel_hemoglobina>=10 and nivel_hemoglobina<=18)and(edad_paciente>1 and edad_paciente<=6):
    resultado=(" El resultado es Negativo")
elif(nivel_hemoglobina>=11 and nivel_hemoglobina<=15)and(edad_paciente>6 and edad_paciente<=12):
    resultado=(" El resultado es Negativo")
elif (nivel_hemoglobina>=11.5 and nivel_hemoglobina<=15) and (edad_paciente>12 and edad_paciente<=60): # Equivalencia entre 1 año y 5 años en meses
    resultado=(" El resultado es Negativo")
elif (nivel_hemoglobina>=12.6 and nivel_hemoglobina<=15.5) and (edad_paciente>60 and edad_paciente<=120): # Equivalencia entre 5 años y 10 años en meses
    resultado=(" El resultado es Negativo")
elif (nivel_hemoglobina>=13 and nivel_hemoglobina<=15.5) and(edad_paciente>120 and edad_paciente<=180): # Equivalencia entre 10 año y 15 años en meses
    resultado=(" El resultado es Negativo")
elif (nivel_hemoglobina>=12 and nivel_hemoglobina<=16 ) and (edad_paciente>180 and sexo=="F"): # Equivalencia de 15 a meses
    resultado=(" El resultado es Negativo")
elif (nivel_hemoglobina>=14 and nivel_hemoglobina<=18) and (edad_paciente>180 and sexo=="M"): # Equivalencia de 15
    resultado=(" El resultado es Negativo")
else:
    resultado= "El resultado es positivo"

#Salidas

print(resultado)


import operator
import inspect

import pytest

from ftrack_api.event.expression import (
    Expression, All, Any, Not, Condition, Parser
)
from ftrack_api.exception import ParseError

@pytest.fixture()
def candidate():
    '''Return common candidate to test expressions against.'''
    return {
        'id': 10,
        'name': 'value',
        'change': {
            'name': 'value',
            'new_value': 10
        }
    }

@pytest.mark.parametrize('expression, expected', [
    pytest.mark.xfail(('', Expression())),
    ('invalid', ParseError),
    ('key=value nor other=value', ParseError),
    ('key=value', Condition('key', operator.eq, 'value')),
    ('key="value"', Condition('key', operator.eq, 'value')),
    (
        'a=b and ((c=d or e!=f) and not g.h > 10)',
        All([
            Condition('a', operator.eq, 'b'),
            All([
                Any([
                    Condition('c', operator.eq, 'd'),
                    Condition('e', operator.ne, 'f')
                ]),
                Not(
                    Condition('g.h', operator.gt, 10)
                )
            ])
        ])
    )
], ids=[
    'empty expression',
    'invalid expression',
    'invalid conjunction',
    'basic condition',
    'basic quoted condition',
    'complex condition'
])
def test_parser_parse(expression, expected):
    '''Parse expression into Expression instances.'''
    parser = Parser()

    if inspect.isclass(expected)and issubclass(expected, Exception):
        with pytest.raises(expected):
            parser.parse(expression)
    else:
        assert str(parser.parse(expression)) == str(expected)

@pytest.mark.parametrize('expression, expected', [
    (Expression(), '<Expression>'),
    (All([Expression(), Expression()]), '<All [<Expression> <Expression>]>'),
    (Any([Expression(), Expression()]), '<Any [<Expression> <Expression>]>'),
    (Not(Expression()), '<Not <Expression>>'),
    (Condition('key', '=', 'value'), '<Condition key=value>')
], ids=[
    'Expression',
    'All',
    'Any',
    'Not',
    'Condition'
])
def test_string_representation(expression, expected):
    '''String representation of expression.'''
    assert str(expression) == expected

@pytest.mark.parametrize('expression, expected', [
    # Expression
    (Expression(), True),

    # All
    (All(), True),
    (All([Expression(), Expression()]), True),
    (All([Expression(), Condition('test', operator.eq, 'value')]), False),

    # Any
    (Any(), False),
    (Any([Expression(), Condition('test', operator.eq, 'value')]), True),
    (Any([
        Condition('test', operator.eq, 'value'),
        Condition('other', operator.eq, 'value')
    ]), False),

    # Not
    (Not(Expression()), False),
    (Not(Not(Expression())), True)
], ids=[
    'Expression-always matches',

    'All-no expressions always matches',
    'All-all match',
    'All-not all match',

    'Any-no expressions never matches',
    'Any-some match',
    'Any-none match',

    'Not-invert positive match',
    'Not-double negative is positive match'
])
def test_match(expression, candidate, expected):
    '''Determine if candidate matches expression.'''
    assert expression.match(candidate) is expected

def parametrize_test_condition_match(metafunc):
    '''Parametrize condition_match tests.'''
    identifiers = []
    data = []

    matrix = {
        # Operator, match, no match
        operator.eq: {
            'match': 10, 'no-match': 20,
            'wildcard-match': 'valu*', 'wildcard-no-match': 'values*'
        },
        operator.ne: {'match': 20, 'no-match': 10},
        operator.ge: {'match': 10, 'no-match': 20},
        operator.le: {'match': 10, 'no-match': 0},
        operator.gt: {'match': 0, 'no-match': 10},
        operator.lt: {'match': 20, 'no-match': 10}
    }

    for operator_function, values in matrix.items():
        for value_label, value in values.items():
            if value_label.startswith('wildcard'):
                key_options = {
                    'plain': 'name',
                    'nested': 'change.name'
                }
            else:
                key_options = {
                    'plain': 'id',
                    'nested': 'change.new_value'
                }

            for key_label, key in key_options.items():
                identifiers.append('{} operator {} key {}'.format(
                    operator_function.__name__, key_label, value_label
                ))

                data.append((
                    key, operator_function, value,
                    'no-match' not in value_label
                ))

    metafunc.parametrize(
        'key, operator, value, expected', data, ids=identifiers
    )

def test_condition_match(key, operator, value, candidate, expected):
    '''Determine if candidate matches condition expression.'''
    condition = Condition(key, operator, value)
    assert condition.match(candidate) is expected


from __future__ import absolute_import
from __future__ import print_function
from __future__ import division

import torch

from reid.data.samplers import build_train_sampler
from reid.data.transforms import build_transforms
from reid.data.datasets import init_image_dataset

class DataManager(object):
    r"""Base data manager.

    Args:
        sources (str or list): source dataset(s).
        targets (str or list, optional): target dataset(s). If not given,
            it equals to ``sources``.
        height (int, optional): target image height. Default is 256.
        width (int, optional): target image width. Default is 128.
        transforms (str or list of str, optional): transformations applied to model training.
            Default is 'random_flip'.
        norm_mean (list or None, optional): data mean. Default is None (use imagenet mean).
        norm_std (list or None, optional): data std. Default is None (use imagenet std).
        use_gpu (bool, optional): use gpu. Default is True.
    """

    def __init__(self, sources=None, targets=None, height=256, width=128, transforms='random_flip', padding=10, norm_mean=None, norm_std=None, use_gpu=False):
        self.sources = sources
        self.targets = targets
        self.height = height
        self.width = width

        if self.sources is None:
            raise ValueError('sources must not be None')

        if isinstance(self.sources, str):
            self.sources = [self.sources]

        if self.targets is None:
            self.targets = self.sources

        if isinstance(self.targets, str):
            self.targets = [self.targets]

        self.transform_tr, self.transform_te = build_transforms(
            self.height, self.width, transforms=transforms,
            norm_mean=norm_mean, norm_std=norm_std, padding=padding,
        )

        self.use_gpu = (torch.cuda.is_available() and use_gpu)

    @property
    def num_train_pids(self):
        """Returns the number of training person identities."""
        return self._num_train_pids

    @property
    def num_train_cams(self):
        """Returns the number of training cameras."""
        return self._num_train_cams

    def return_dataloaders(self):
        """Returns trainloader and testloader."""
        return self.trainloader, self.testloader

    def return_testdataset_by_name(self, name):
        """Returns query and gallery of a test dataset, each containing
        tuples of (img_path(s), pid, camid).

        Args:
            name (str): dataset name.
        """
        return self.testdataset[name]['query'], self.testdataset[name]['gallery']

class ImageDataManager(DataManager):
    r"""Image data manager.

    Args:
        root (str): root path to datasets.
        sources (str or list): source dataset(s).
        targets (str or list, optional): target dataset(s). If not given,
            it equals to ``sources``.
        height (int, optional): target image height. Default is 256.
        width (int, optional): target image width. Default is 128.
        transforms (str or list of str, optional): transformations applied to model training.
            Default is 'random_flip'.
        norm_mean (list or None, optional): data mean. Default is None (use imagenet mean).
        norm_std (list or None, optional): data std. Default is None (use imagenet std).
        use_gpu (bool, optional): use gpu. Default is True.
        split_id (int, optional): split id (*0-based*). Default is 0.
        combineall (bool, optional): combine train, query and gallery in a dataset for
            training. Default is False.
        batch_size_train (int, optional): number of images in a training batch. Default is 32.
        batch_size_test (int, optional): number of images in a test batch. Default is 32.
        workers (int, optional): number of workers. Default is 4.
        num_instances (int, optional): number of instances per identity in a batch.
            Default is 4.
        train_sampler (str, optional): sampler. Default is empty (``RandomSampler``).
        cuhk03_labeled (bool, optional): use cuhk03 labeled images.
            Default is False (defaul is to use detected images).
        cuhk03_classic_split (bool, optional): use the classic split in cuhk03.
            Default is False.
        market1501_500k (bool, optional): add 500K distractors to the gallery
            set in market1501. Default is False.

    Examples::

        datamanager = torchreid.data.ImageDataManager(
            root='path/to/reid-data',
            sources='market1501',
            height=256,
            width=128,
            batch_size_train=32,
            batch_size_test=100
        )
    """
    data_type = 'image'

    def __init__(self, root='', sources=None, targets=None, height=256, width=128, transforms='random_flip', padding=10,
                 norm_mean=None, norm_std=None, use_gpu=True, split_id=0, combineall=False,
                 batch_size_train=32, batch_size_test=32, workers=4, num_instances=4, train_sampler='',
                 cuhk03_labeled=False, cuhk03_classic_split=False, market1501_500k=False, naic2019_phase='train', naic2019_total=False):

        super(ImageDataManager, self).__init__(sources=sources, targets=targets, height=height, width=width,
                                               transforms=transforms, padding=padding, norm_mean=norm_mean, norm_std=norm_std,
                                               use_gpu=use_gpu)

        print('=> Loading train (source) dataset')
        trainset = []
        for name in self.sources:
            trainset_ = init_image_dataset(
                name,
                transform=self.transform_tr,
                mode='train',
                combineall=combineall,
                root=root,
                split_id=split_id,
                cuhk03_labeled=cuhk03_labeled,
                cuhk03_classic_split=cuhk03_classic_split,
                market1501_500k=market1501_500k,
                naic2019_phase=naic2019_phase,
                naic2019_total=naic2019_total,
            )
            trainset.append(trainset_)
        trainset = sum(trainset)

        self._num_train_pids = trainset.num_train_pids
        self._num_train_cams = trainset.num_train_cams

        train_sampler = build_train_sampler(
            trainset.train, train_sampler,
            batch_size=batch_size_train,
            num_instances=num_instances
        )

        self.trainloader = torch.utils.data.DataLoader(
            trainset,
            sampler=train_sampler,
            batch_size=batch_size_train,
            shuffle=False,
            num_workers=workers,
            pin_memory=self.use_gpu,
            drop_last=True
        )

        print('=> Loading test (target) dataset')
        self.testloader = {name: {'query': None, 'gallery': None}
                           for name in self.targets}
        self.testdataset = {name: {'query': None, 'gallery': None}
                            for name in self.targets}

        for name in self.targets:
            # build query loader
            queryset = init_image_dataset(
                name,
                transform=self.transform_te,
                mode='query',
                combineall=combineall,
                root=root,
                split_id=split_id,
                cuhk03_labeled=cuhk03_labeled,
                cuhk03_classic_split=cuhk03_classic_split,
                market1501_500k=market1501_500k,
                naic2019_phase=naic2019_phase,
                naic2019_total=naic2019_total,
            )
            self.testloader[name]['query'] = torch.utils.data.DataLoader(
                queryset,
                batch_size=batch_size_test,
                shuffle=False,
                num_workers=workers,
                pin_memory=self.use_gpu,
                drop_last=False
            )

            # build gallery loader
            galleryset = init_image_dataset(
                name,
                transform=self.transform_te,
                mode='gallery',
                combineall=combineall,
                verbose=False,
                root=root,
                split_id=split_id,
                cuhk03_labeled=cuhk03_labeled,
                cuhk03_classic_split=cuhk03_classic_split,
                market1501_500k=market1501_500k,
                naic2019_phase=naic2019_phase,
                naic2019_total=naic2019_total,
            )
            self.testloader[name]['gallery'] = torch.utils.data.DataLoader(
                galleryset,
                batch_size=batch_size_test,
                shuffle=False,
                num_workers=workers,
                pin_memory=self.use_gpu,
                drop_last=False
            )

            self.testdataset[name]['query'] = queryset.query
            self.testdataset[name]['gallery'] = galleryset.gallery

        print('\n')
        print('  **************** Summary ****************')
        print('  train            : {}'.format(self.sources))
        print('  # train datasets : {}'.format(len(self.sources)))
        print('  # train ids      : {}'.format(self.num_train_pids))
        print('  # train images   : {}'.format(len(trainset)))
        print('  # train cameras  : {}'.format(self.num_train_cams))
        print('  test             : {}'.format(self.targets))
        print('  *****************************************')
        print('\n')


# Write a Python function to calculate the factorial of a number (a non- negative integer).
# The function accepts the number as argument

from functools import reduce

def Factorial(n):
    l = list(range(2, (n+1)))
    return reduce(lambda x, y: x*y, l)

print("Factorial :", Factorial(5))

BCA Programs/#98 Factorial using function.py


""" A collection of classes and functions to reproject data.

Todo:
    * Rewrite using cartopy
    * Can some of this be merged with :any:`~evac.utils.gis_tools`?
    * These classes need to be put in their own file.
    * Long term, we probably need a new directory, 'geog' or 'reproj',
        which deals with reprojection, and gathers a lot of functions
        and classes that are scattered around evac.
    * Rewrite without any WEM imports.
"""
import os
import pdb

from scipy.interpolate import griddata
from mpl_toolkits.basemap import Basemap
import numpy as N

from evac.datafiles.wrfout import WRFOut
from evac.datafiles.hrrr import HRRR

class VerifGrid:
    """
    The verification grid should be inside the 1 km domain.

    Roughly 5 km res?

    W is the 1 km WRFOut instance
    """
    def __init__(self,W,nx,ny,xy1D=True):
        self.proj = 'lcc'
        # These are urcrnrlon etc
        self.Nlim = W.kwargs['urcrnrlat']
        self.Elim = W.kwargs['urcrnrlon']
        self.Slim = W.kwargs['llcrnrlat']
        self.Wlim = W.kwargs['llcrnrlon']

        self.nx = nx
        self.ny = ny
        self.cen_lat = W.kwargs['lat_0']
        self.cen_lon = W.kwargs['lon_0']
        self.tlat1 = W.kwargs['lat_1']
        self.tlat2 = W.kwargs['lat_2']

        self.m, self.lons, self.lats, self.xx, self.yy = create_new_grid(Nlim=self.Nlim,
                        Elim=self.Elim,Slim=self.Slim,Wlim=self.Wlim,nx=self.nx,ny=self.ny,proj=self.proj,
                        tlat1=self.tlat1,tlat2=self.tlat2,cen_lat=self.cen_lat,cen_lon=self.cen_lon)
        # if xy1D:
            # self.xx = self.xx[0,:]
            # self.yy = self.yy[:,0]

        # Aliases
        self.lat_0 = self.cen_lat
        self.lon_0 = self.cen_lon
        return

class WRF_native_grid:
    def __init__(self,fpath,resolution='i',xy1D=True):
        """Generates a basemap object for a WRF file's domain.

        """
        # keyword arguments to basemap generation
        self.kwargs = {'resolution':resolution}

        self.load_wrfout(fpath)
        self.load_attrs()
        self.load_corners()
        self.generate_basemap()

        if xy1D:
            self.xx = self.xx[0,:]
            self.yy = self.yy[:,0]

        self.combine_scopes()

    def load_wrfout(self,fpath):
        self.W = WRFOut(fpath)
        return

    def load_attrs(self,):
        self.kwargs['lat_0'] = self.W.nc.CEN_LAT
        self.kwargs['lon_0'] = self.W.nc.CEN_LON
        self.kwargs['lat_1'] = self.W.nc.TRUELAT1
        self.kwargs['lat_2'] = self.W.nc.TRUELAT2

    def load_corners(self):
        self.kwargs['llcrnrlon'] = self.W.lons[0,0]
        self.kwargs['llcrnrlat'] = self.W.lats[0,0]
        self.kwargs['urcrnrlon'] = self.W.lons[-1,-1]
        self.kwargs['urcrnrlat'] = self.W.lats[-1,-1]

    def generate_basemap(self):
        self.m = Basemap(projection='lcc',**self.kwargs)
        self.lons, self.lats, self.xx, self.yy = self.m.makegrid(
                        self.W.lons.shape[1],self.W.lons.shape[0],returnxy=True)

    def combine_scopes(self):
        """
        Put kwargs dictionary into self's namespace
        """
        self.__dict__ = dict(self.__dict__,**self.kwargs)

        # Alias of domain limits
        self.Wlim = self.llcrnrlon
        self.Slim = self.llcrnrlat
        self.Nlim = self.urcrnrlat
        self.Elim = self.urcrnrlon

class HRRR_native_grid(WRF_native_grid):
    """AS WRF_native_grid, but with some info about operational HRRR.
    """
    def __init__(self,fpath):
        super(HRRR_native_grid,self).__init__(fpath)

    def load_wrfout(self,fpath):
        """Over-riden from parent.
        """
        self.W = HRRR(fpath)

    def load_attrs(self,):
        """Over-riden from parent.

        TODO: get rid of this and just load from HRRR object.
        """
        self.kwargs['lat_0'] = 38.5
        self.kwargs['lon_0'] = -97.5
        self.kwargs['lat_1'] = 38.5
        self.kwargs['lat_2'] = 38.5

def create_new_grid(Nlim=None,Elim=None,Slim=None,Wlim=None,proj='merc',
                    lat_ts=None,resolution='i',nx=None,ny=None,
                    tlat1=30.0,tlat2=60.0,cen_lat=None,cen_lon=None,
                    lats=None,lons=None,dx=None):
                    # lllon=None,lllat=None,urlat=None,urlon=None):
    """Create new domain for interpolating to, for instance.

    The following are mandatory arguments for mercator ('merc'):
    Nlim,Elim,Slim,Wlim = lat/lon/lat/lon limits for north/east/south/west respectively
    lat_ts = latitude of true scale?
    nx,ny = number of points in the x/y direction respectively
    """
    if proj == 'merc':
        if nx is None:
            assert dx
        if None in (Nlim,Elim,Slim,Wlim,lat_ts):
            print("Check non-optional arguments.")
            raise Exception
        m = Basemap(projection=proj,llcrnrlat=Slim,llcrnrlon=Wlim,
                    urcrnrlat=Nlim,urcrnrlon=Elim,lat_ts=lat_ts,resolution=resolution)
        if dx:
            # llcrnr
            xW, yS = m(Wlim, Slim)
            # urcrnr
            xE, yN = m(Elim, Nlim)

            # km difference in x (lon) direction
            xdiff_km = abs(xE-xW)/1000
            # and in y (lat) direction
            ydiff_km = abs(yS-yN)/1000

            # nx needed to give dx requested
            nx = int(N.floor(xdiff_km/dx))
            # assume dx=dy
            ny = int(N.floor(ydiff_km/dx))

    elif proj == 'lcc':
        # if None in (tlat1,tlat2,cen_lat,cen_lon,lllon,lllat,urlon,urlat,nx,ny):
        if None in (tlat1,tlat2,cen_lat,cen_lon,Nlim,Elim,Slim,Wlim,nx,ny):
            print("Check non-optional arguments.")
            raise Exception
        m = Basemap(projection='lcc',lat_1=tlat1,lat_2=tlat2,lat_0=cen_lat,
                            lon_0=cen_lon,llcrnrlon=Wlim,llcrnrlat=Slim,
                            urcrnrlon=Elim,urcrnrlat=Nlim,resolution='h')

    lons, lats, xx, yy = m.makegrid(nx,ny,returnxy=True)
    # pdb.set_trace()
    return m, lons, lats, xx, yy

def create_WRFgrid(f):
    """Constructs an instance of WRF_native_grid to return the vitals.

    f   -   absolute path to wrfout file.
    """
    W = WRF_native_grid(f)
    xx = W.xx
    yy = W.yy
    lons = W.lons
    lats = W.lats
    m = W.m
    return xx,yy,lats,lons,m

def reproject(data_orig,xx_orig=False,yy_orig=False,lats_orig=False,lons_orig=False,newgrid=False,
                    xx_new=False,yy_new=False,method='linear',debug=False):
    """
    data_orig               -   N.ndarray of original data (2D?)
    xx_orig,yy_orig         -   x-/y-axis indices of original data straight out a m(lons,lats)
    lats_orig,lons_orig     -   lats/lons of original data (shape?)
    newgrid                 -   basemap class classobject
    """
    # xx_new,yy_new = newgrid(lons_orig,lats_orig)
    # pdb.set_trace()
    assert len(xx_orig.shape) == 2
    if len(xx_new.shape) == 1:
        xx_new_dim = len(xx_new)
        yy_new_dim = len(yy_new)
        # mx,my = N.meshgrid(xx_new,yy_new)
        my, mx = N.meshgrid(yy_new,xx_new)
    elif len(xx_new.shape)== 2:
        xx_new_dim = len(xx_new[:,0])
        # xx_new_dim = len(xx_new[0,:])
        yy_new_dim = len(yy_new[0,:])
        # yy_new_dim = len(yy_new[:,0])
        mx,my = xx_new, yy_new
    else:
        raise Exception("Dimensions of xx_new and yy_new are too large.")

    # data_new = griddata((xx_orig.flat,yy_orig.flat),data_orig.flat,(xx_new.flat,
        # yy_new.flat)).reshape(xx_new_dim,yy_new_dim)
    # pdb.set_trace()
    if debug:
        print("Starting reprojection...")

    if type(xx_orig) == N.ma.core.MaskedArray:
        xx_orig = xx_orig.data
    if type(yy_orig) == N.ma.core.MaskedArray:
        yy_orig = yy_orig.data
    if type(data_orig) == N.ma.core.MaskedArray:
        data_orig = data_orig.data
    if type(mx) == N.ma.core.MaskedArray:
        mx = mx.data
    if type(my) == N.ma.core.MaskedArray:
        my = my.data

    data_new = griddata((xx_orig.flat,yy_orig.flat),
                            data_orig.flat,(mx.flat,my.flat),
                            method=method).reshape(xx_new_dim,yy_new_dim)
                        # (mx.flat,my.flat),method=method)
    if debug:
        print("Completed reprojection.")
    return data_new


"""

Any person in the queue can bribe the person directly in front of them to swap
positions. If two people swap positions, they still wear the same sticker
denoting their original places in line. One person can bribe at most two others.
For example, if n=8 and Person 5 bribes Person 4, the queue will look like this:1,2,3,5,4,6,7,8.

Print an integer denoting the minimum number of bribes needed to get the queue
into its final state. Print Too chaotic if the state is invalid,
i.e. it requires a person to have bribed more than  people.

eg: Input:
2
5
2 1 5 3 4
5
2 5 1 3 4

Output:
3
Too chaotic

***Logic is to apply Simple bubble Sort implementation
"""

def minimumBribes(Q):

    swap = 0
    swaped = False
    for i,P in enumerate(Q):
        if P - (i+1) > 2:
            print("Too chaotic")
            return
    for i in range(len(Q)-1):
        for j in range(len(Q)-1):
            if Q[j] >Q[j+1]:
                Q[j],Q[j+1]=Q[j+1], Q[j]
                swap+=1
                swaped = True
        if swaped:
            swaped = False
        else:
            break
    return swap

n = int(input())

for i in range(n):
    q = int(input())
    series = list(map(int, input().rstrip().split()))
    print(minimumBribes(series))


def binarySearch(alist, item):
    first = 0
    last = len(alist) - 1
    found = False

    while first <= last and not found:
        midpoint = (first + last) // 2
        if alist[midpoint] == item:
            found = True
        else:
            if item < alist[midpoint]:
                last = midpoint - 1
            else:
                first = midpoint + 1

    if found:
        print("The number %d is found at position %d " % (item, midpoint))
    else:
        print("The number", num , "is not found in the list")

myList = [12, 23, 43, 54]
num = int(input("Input the number "))
binarySearch(myList, num)


import os
from pathlib import Path
from typing import Optional

import alembic.command
import alembic.config

# Unused netcdf4 import to suppress a warning from numpy/xarray/netcdf4
# https://github.com/pydata/xarray/issues/7259
import netCDF4  # type: ignore # noqa: F401 # This needs to be imported before numpy
import numpy as np
import pytest
import sqlalchemy
import xarray as xr
from sqlalchemy.orm import Session

try:
    from dotenv import load_dotenv

    load_dotenv()
except ImportError:
    pass

test_db_user = os.environ.get("TEST_DB_USER", "postgres")
test_db_pass = os.environ.get("TEST_DB_PASS", "postgres")
test_db_host = os.environ.get("TEST_DB_HOST", "localhost:5432")

@pytest.fixture(scope="session")
def db_name():
    return "test_unified_graphics"

@pytest.fixture(scope="session")
def test_db(db_name):
    autocommit_engine = sqlalchemy.create_engine(
        f"postgresql+psycopg://{test_db_user}:{test_db_pass}@{test_db_host}/postgres",
        isolation_level="AUTOCOMMIT",
    )
    with autocommit_engine.connect() as conn:
        conn.execute(sqlalchemy.text(f"DROP DATABASE IF EXISTS {db_name}"))
        conn.execute(sqlalchemy.text(f"CREATE DATABASE {db_name}"))

    url = f"postgresql+psycopg://{test_db_user}:{test_db_pass}@{test_db_host}/{db_name}"

    config = alembic.config.Config("alembic.ini")
    config.set_main_option("sqlalchemy.url", url)
    alembic.command.upgrade(config, revision="head")

    yield url

    with autocommit_engine.connect() as conn:
        # Disconnect all users from the database we are dropping. I'm unsure why this is
        # necessary, as I think all fo the connections created for our tests should be
        # cleaned up by now.
        #
        # Copied from:
        # https://sqlalchemy-utils.readthedocs.io/en/latest/_modules/sqlalchemy_utils/functions/database.html#drop_database
        version = conn.dialect.server_version_info
        pid_column = "pid" if (version >= (9, 2)) else "procpid"
        conn.execute(
            sqlalchemy.text(
                f"""SELECT pg_terminate_backend(pg_stat_activity.{pid_column})
        FROM pg_stat_activity
        WHERE pg_stat_activity.datname = '{db_name}'
        AND {pid_column} <> pg_backend_pid();
        """
            )
        )
        conn.execute(sqlalchemy.text(f"DROP DATABASE {db_name}"))

    autocommit_engine.dispose()

@pytest.fixture(scope="session")
def engine(test_db):
    _engine = sqlalchemy.create_engine(test_db)
    yield _engine
    _engine.dispose()

@pytest.fixture(scope="class")
def session(engine):
    with Session(engine) as s:
        yield s
        s.rollback()

# FIXME: Replace diag_dataset with this fixture
@pytest.fixture(scope="class")
def test_dataset():
    def factory(
        *,
        model: str = "RTMA",
        system: str = "WCOSS",
        domain: str = "CONUS",
        background: str = "HRRR",
        frequency: str = "REALTIME",
        initialization_time: str = "2022-05-16T04:00",
        variable: str = "ps",
        loop: str = "ges",
        longitude: list[float] = [90, 91],
        latitude: list[float] = [22, 23],
        is_used: list[bool] = [True, False],
        observation: list[float] = [1, 0],
        forecast_unadjusted: list[float] = [0, 1],
        forecast_adjusted: Optional[list[float]] = None,
        **kwargs,
    ):
        assert len(observation) == len(forecast_unadjusted)
        if forecast_adjusted:
            assert len(forecast_adjusted) == len(forecast_unadjusted)

        dims = ["nobs", *kwargs.keys()]

        obs = np.array(observation, dtype=np.float64)
        unadj = np.array(forecast_unadjusted, dtype=np.float64)
        adj = np.array(forecast_adjusted or forecast_unadjusted, dtype=np.float64)

        return xr.Dataset(
            {
                "observation": (dims, obs),
                "forecast_unadjusted": (dims, unadj),
                "forecast_adjusted": (dims, adj),
                "obs_minus_forecast_unadjusted": (dims, obs - unadj),
                "obs_minus_forecast_adjusted": (dims, obs - adj),
            },
            coords=dict(
                longitude=(["nobs"], np.array(longitude, dtype=np.float64)),
                latitude=(["nobs"], np.array(latitude, dtype=np.float64)),
                is_used=(["nobs"], np.array(is_used)),
                **kwargs,
            ),
            attrs={
                "name": variable,
                "loop": loop,
                "initialization_time": initialization_time,
                "model": model,
                "system": system,
                "domain": domain,
                "frequency": frequency,
                "background": background,
            },
        )

    return factory

@pytest.fixture
def diag_parquet(tmp_path):
    def factory(
        ds: xr.Dataset,
    ) -> Path:
        parquet_file = (
            tmp_path
            / "_".join((ds.model, ds.background, ds.system, ds.domain, ds.frequency))
            / ds.name
        )
        df = ds.to_dataframe()
        df["loop"] = ds.loop
        df["initialization_time"] = ds.initialization_time

        df.to_parquet(
            parquet_file, partition_cols=["loop"], index=True, engine="pyarrow"
        )

        return parquet_file

    return factory


import torch
t = torch
import numpy as np
nn = t.nn
F = t.nn.functional
from transformers import BertJapaneseTokenizer, BertForMaskedLM
import datetime
from itertools import chain
from reader import read_data, read_regular_ds_zip
from sklearn.metrics import precision_recall_fscore_support as score
from sklearn.metrics import f1_score, precision_score, recall_score
import types

def create_model(learning_rate = 1e-5):
    res = types.SimpleNamespace()
    # NOTE
    res.bert = BertForMaskedLM.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
    res.toker = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
    res.opter = torch.optim.AdamW(res.bert.parameters(), learning_rate)
    res.bert.cuda()
    res.bert.train()
    return res

def verbalize(label):
    if label == 0:
        return 'いえ'
    elif label == 1:
        return 'はい'

def deverbalize(word):
    if word == 'いえ':
        return 0
    elif word == 'はい':
        return 1
    else:
        print(f'Bad word: {word}')
        return 0
        # return word

def patterned(left, right, strategy = 0):
    if strategy == 0:
        return f'「{left}」は「{right}」より上品ですか？[MASK]。'
    elif strategy == 1:
        return f'{left}は{right}よりも上品ですか？[MASK]。'
    elif strategy == 2:
        return f'「{left}」は「{right}」よりも格調高いですか？[MASK]。'
    elif strategy == 3:
        return f'{left}は{right}よりも格調高いですか？[MASK]。'

def pattern_verbalized(left, right, label):
    text = patterned(left, right)
    return text.replace('[MASK]', verbalize(label))

# NOTE: create half fake datas
def create_inputs_and_labels_from_fewshot_set(ds, should_deverbalize = True, shuffle = True):
    results = []
    ds = ds.copy()
    if shuffle:
        np.random.shuffle(ds)
    half = int(len(ds) / 2)
    ds_true = ds[:half]
    ds_false = ds[half:]
    for left, right in ds_true:
        results.append((patterned(left, right), pattern_verbalized(left, right, 0) if should_deverbalize else 0))
    for left, right in ds_false:
        results.append((patterned(right, left), pattern_verbalized(right, left, 1) if should_deverbalize else 1))
    if shuffle:
        np.random.shuffle(results)
    return results

def step(x, y, m):
    tokenizer = m.toker
    model = m
    opter = m.opter
    inputs = tokenizer(x, return_tensors="pt", truncation=True)["input_ids"]
    labels = tokenizer(y, return_tensors="pt", truncation=True)["input_ids"]
    labels = torch.where(inputs == tokenizer.mask_token_id, labels, -100)
    inputs = inputs.cuda()
    labels = labels.cuda()
    outputs = model.bert(inputs, labels=labels)
    loss = outputs.loss
    loss.backward()

def run_full(m, ds, batch_size = 1):
    input_labels = create_inputs_and_labels_from_fewshot_set(ds)
    length = len(input_labels)
    first_time = datetime.datetime.now()
    for index, (x,y) in enumerate(input_labels):
        step(x, y, m)
        if (index + 1) % 32 == 0:
            print(f'{index + 1} / {length}')
        if (index + 1) % batch_size == 0:
            m.opter.step()
            m.opter.zero_grad()
    m.opter.step()
    m.opter.zero_grad()
    last_time = datetime.datetime.now()
    delta = last_time - first_time
    print(delta.seconds)

def get_predicted_word(tokenizer, model, text):
    inputs = tokenizer(text, return_tensors="pt", truncation=True)["input_ids"]
    inputs = inputs.cuda()
    with torch.no_grad():
        logits = model(inputs).logits
    mask_token_index = (inputs == tokenizer.mask_token_id)[0].nonzero(as_tuple=True)[0]
    predicted_token_id = logits[0, mask_token_index].argmax(axis=-1)
    word = tokenizer.decode(predicted_token_id)
    return word

def get_test_result(m, ds_test, should_deverbalize = True):
    tokenizer = m.toker
    model = m.bert
    pred_ys = []
    true_ys = []
    length = len(ds_test)
    input_labels = create_inputs_and_labels_from_fewshot_set(ds_test, should_deverbalize = False, shuffle = False)
    # for index, item in enumerate(test):
    for index, (text, label) in enumerate(input_labels):
        if index % 100 == 0:
            print(f'{index}/{length}')
        word = get_predicted_word(tokenizer, model, text)
        pred_y = deverbalize(word) if should_deverbalize else word
        pred_ys.append(pred_y)
        true_ys.append(label)
    return pred_ys, true_ys

def cal_scores(pred_ys, true_ys):
    precision, recall, fscore, support = score(true_ys, pred_ys)

def cal_prec_rec_f1_v2(results, targets):
    return f1_score(targets, results, average='macro')

def get_curve_regular():
    m = create_model()
    ds = read_regular_ds_zip()
    train_ds = ds[:227] # 227
    test_ds = ds[227:277] # 50
    fs = []
    precs = []
    recs = []
    for start in range(0, 224, 16): # [0, 16, 32, ..., 480]
        end = start + 16 # 16, 32, ..., 496
        fewshot = train_ds[start: end]
        run_full(m, fewshot, batch_size = 1)
        results, targets = get_test_result(m, test_ds)
        fs.append(f1_score(targets, results, average='macro'))
        precs.append(precision_score(targets, results, average='macro'))
        recs.append(recall_score(targets, results, average='macro'))
    return precs, recs, fs

def get_curve_regular(m, batch_size = 1):
    ds = read_regular_ds_zip()
    train_ds = ds[:227] # 227
    test_ds = ds[227:277] # 50
    # ds = read_data()
    # train_ds = ds[:496]
    # test_ds = ds[500:700]
    fs = []
    precs = []
    recs = []
    # for start in range(0, 496, 32): # [0, 16, 32, ..., 480]
    for start in range(0, 227, 32): # [0, 16, 32, ..., 480]
        end = start + 32 # 16, 32, ..., 496
        fewshot = train_ds[start: end]
        run_full(m, fewshot, batch_size = batch_size)
        results, targets = get_test_result(m, test_ds)
        fs.append(f1_score(targets, results, average='macro'))
        precs.append(precision_score(targets, results, average='macro'))
        recs.append(recall_score(targets, results, average='macro'))
    return precs, recs, fs

def get_curve(m, batch_size = 1):
    ds = read_data()
    train_ds = ds[:496]
    test_ds = ds[500:700]
    fs = []
    precs = []
    recs = []
    for start in range(0, 496, 32): # [0, 16, 32, ..., 480]
        end = start + 32 # 16, 32, ..., 496
        fewshot = train_ds[start: end]
        run_full(m, fewshot, batch_size = batch_size)
        results, targets = get_test_result(m, test_ds)
        fs.append(f1_score(targets, results, average='macro'))
        precs.append(precision_score(targets, results, average='macro'))
        recs.append(recall_score(targets, results, average='macro'))
    return precs, recs, fs

def stop_when_f_score_exceed(limit = 0.57):
    m = create_model()
    ds = read_data()
    train_ds = ds[:496]
    test_ds = ds[500:700]
    fs = []
    precs = []
    recs = []
    for start in range(0, 496, 16): # [0, 16, 32, ..., 480]
        end = start + 16 # 16, 32, ..., 496
        fewshot = train_ds[start: end]
        run_full(m, fewshot, batch_size = 1)
        results, targets = get_test_result(m, test_ds)
        f = f1_score(targets, results, average='macro')
        if f > limit:
            print(f'End at {start}, f {f}.')
            break
    return m

# ========================================

def train_model(data_points = 256, batch_size = 1):
    m = create_model()
    ds = read_data()
    assert data_points < 500
    train_ds = ds[:data_points]
    test_ds = ds[500:700]
    print('Training...')
    run_full(m, train_ds, batch_size = batch_size)
    print('Testing...')
    results, targets = get_test_result(m, test_ds)
    f = f1_score(targets, results, average='macro')
    prec = precision_score(targets, results, average='macro')
    rec = recall_score(targets, results, average='macro')
    print(f'Results: f {f}, precision {prec}, recall {rec}.')
    return m

def get_predicted_word_by_word_pair(m, left, right):
    text = patterned(left, right)
    return get_predicted_word(m.toker, m.bert, text)

def run_test(m, test_ds):
    results, targets = get_test_result(m, test_ds)
    print(f1_score(targets, results, average='macro'))


# IMPORT SELENIUM DEPENDENCIES
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.webdriver import WebDriver
from webdriver_manager.chrome import ChromeDriverManager

# CONFIGURE HEADLESS BROWSER OPTIONS
opt_headless = Options()
opt_headless.add_argument("--headless")

# CREATE HEADLESS BROWSER INSTANCE FOR BOTS
def init_browser_headless() -> WebDriver:
    browser: WebDriver = webdriver.Chrome(
        executable_path=ChromeDriverManager().install(),
        chrome_options=opt_headless,
    )
    return browser

# CREATE HEADFUL BROWSER INSTANCE FOR BOTS
def init_browser_headful() -> WebDriver:
    browser: WebDriver = webdriver.Chrome(
        executable_path=ChromeDriverManager().install()
    )
    return browser


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

from itertools import product
import os

import numpy as np

PATH = os.environ.get("PSS_PATH", "..")

def pss_block(
    seed, k, case, i1, block_id, m=2_000_000, t=1_000, save=True, path="./"
):
    file_name = f"pss-k-{k}-case-{case}-i1-{i1}-block-{block_id}.npz"
    file_name = os.path.join(path, file_name)
    if save and os.path.exists(file_name):
        return
    rs = np.random.default_rng(seed)
    const = np.ones(t - 1)
    tau = np.arange(1, t).astype(float)
    f = np.empty(m)
    for j in range(m):
        u = rs.standard_normal((k + 1, t))
        y = np.cumsum(u[0])
        if i1:
            x = np.cumsum(u[1:], axis=1).T
        else:
            x = u[1:].T
        lhs = np.diff(y)
        rhv = [y[:-1], x[:-1]]
        if case == 2:
            rhv.append(const)
        elif case == 4:
            rhv.append(tau)
        if case >= 3:
            rhv.append(const)
        if case == 5:
            rhv.append(tau)
        rest = k + 1
        if case in (2, 4):
            rest += 1
        rhs = np.column_stack(rhv)
        b = np.linalg.lstsq(rhs, lhs, rcond=None)[0]
        u = lhs - rhs @ b
        s2 = u.T @ u / (u.shape[0] - rhs.shape[1])
        xpx = rhs.T @ rhs
        vcv = np.linalg.inv(xpx) * s2
        r = np.eye(rest, rhs.shape[1])
        rvcvr = r @ vcv @ r.T
        rb = r @ b
        f[j] = rb.T @ np.linalg.inv(rvcvr) @ rb / rest
    percentiles = [0.05]
    percentiles += [i / 10 for i in range(1, 10)]
    percentiles += [1 + i / 2 for i in range(18)]
    percentiles += [i for i in range(10, 51)]
    percentiles += [100 - v for v in percentiles]
    percentiles = sorted(set(percentiles))
    percentiles = np.asarray(percentiles)
    q = np.percentile(f, percentiles)
    if save:
        np.savez(file_name, q=q, percentiles=percentiles)
    return q

seed = [
    3957597042,
    2709280948,
    499296859,
    1555610991,
    2390531900,
    2160388094,
    4098495866,
    47221919,
]
ss = np.random.SeedSequence(seed)
k = list(range(1, 11))
case = list(range(1, 6))
i1 = [True, False]
block_id = list(range(32))
params = list(product(k, case, i1, block_id))
seeds = ss.generate_state(8 * len(params)).reshape((-1, 8)).tolist()
configs = []
for _s, (_k, _case, _i1, _block_id) in zip(seeds, params):
    configs.append(
        {
            "seed": _s,
            "k": _k,
            "case": _case,
            "i1": _i1,
            "block_id": _block_id,
            "path": PATH,
        }
    )

if __name__ == "__main__":
    from joblib import Parallel, delayed

    Parallel(n_jobs=10)(delayed(pss_block)(**c) for c in configs)