import dataclasses
import config
import logging
from telegram.ext import Updater
from telegram.ext import Updater, CommandHandler, MessageHandler
from telegram.ext import MessageHandler, Filters
from models import ReceiptInfo, ReceiptResult
from receipts_api import request_receipt_details
import spread_sheet
from util import save_in_json

TMP_IMG_FILE = "./last_qr_photo.jpg"
DATA_PATH = "./data"

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)

def start(update, context):
    context.bot.send_message(
        chat_id=update.effective_chat.id, text="Send photos of your receipts here")

def photo_handler(update, context):
    """ handles receipt with qr code """
    newFile = update.message.effective_attachment[-1].get_file()
    newFile.download(TMP_IMG_FILE)
    try:
        receipt_result = get_details(TMP_IMG_FILE)
        if (receipt_result.is_ok):
            persist_receipt(receipt_result.receipt)
            context.bot.send_message(
                chat_id=update.effective_chat.id, text="✅ Qr saved!")
        else:
            context.bot.send_message(chat_id=update.effective_chat.id,
                                     text="Failed to process Qr with error: " + receipt_result.errror_msg)
    except Exception as e:
        logger.error(e)
        context.bot.send_message(chat_id=update.effective_chat.id,
                                 text="Failed to process Qr with error: " + str(e))

def get_details(path: str) -> ReceiptResult:
    with open(path, "rb") as f:
        return request_receipt_details(f)

def persist_receipt(receipt_info: ReceiptInfo):
    goods = list(map(lambda o: o.__dict__, receipt_info.goods))
    metadata_values = list(dataclasses.asdict(receipt_info.metadata).values())
    save_in_json(DATA_PATH, goods)
    rows = [metadata_values + list(good.values()) for good in goods]
    spread_sheet.add_rows(rows)

def main():
    updater = Updater(token=config.BOT_TOKEN, use_context=True)
    dispatcher = updater.dispatcher
    updater.dispatcher.add_handler(CommandHandler('start', start))
    dispatcher.add_handler(MessageHandler(Filters.photo, photo_handler))
    updater.start_polling()

if __name__ == '__main__':
    main()


# Cylinder Gadget (based on Amazon example code & Scott's original cylinder light)

import logging
import sys
import time
import board
import neopixel
import random
import threading
import dateutil.parser
import traceback
import json
import color_constants

from agt import AlexaGadget

logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logger = logging.getLogger(__name__)

# Choose an open pin connected to the Data In of the NeoPixel strip, i.e. board.D18
# NeoPixels must be connected to D10, D12, D18 or D21 to work.
pixel_pin = board.D18

# The number of NeoPixels
num_pixels = 484
rows=10
cols=44

# The order of the pixel colors - RGB or GRB. Some NeoPixels have red and green reversed!
# For RGBW NeoPixels, simply change the ORDER to RGBW or GRBW.
ORDER = neopixel.GRB

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.2, auto_write=False,
                           pixel_order=ORDER)

colors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,255,255),(255,0,255),(255,255,255),(255,0,0),(0,255,0),(0,0,255),(255,255,0)]

font_data = [0x00, 0x00, 0x00, 0x00, 0x00, # ''
0x00, 0x00, 0x17, 0x00, 0x00, # '!'
0x00, 0x03, 0x00, 0x03, 0x00, # '"'
0x0a, 0x1f, 0x0a, 0x1f, 0x0a, # '#'
0x12, 0x15, 0x1f, 0x15, 0x09, # '$'
0x13, 0x0b, 0x04, 0x1a, 0x19, # '%'
0x0d, 0x12, 0x15, 0x08, 0x14, # '&'
0x00, 0x00, 0x03, 0x00, 0x00, # '''
0x00, 0x0e, 0x11, 0x00, 0x00, # '('
0x00, 0x00, 0x11, 0x0e, 0x00, # ')'
0x00, 0x05, 0x02, 0x05, 0x00, # '*'
0x04, 0x04, 0x1f, 0x04, 0x04, # '+'
0x00, 0x10, 0x08, 0x00, 0x00, # ','
0x04, 0x04, 0x04, 0x04, 0x04, # '-'
0x00, 0x18, 0x18, 0x00, 0x00, # '.'
0x10, 0x08, 0x04, 0x02, 0x01, # '/'
0x0e, 0x11, 0x15, 0x11, 0x0e, # '0'
0x00, 0x12, 0x1f, 0x10, 0x00, # '1'
0x00, 0x1d, 0x15, 0x15, 0x17, # '2'
0x00, 0x11, 0x15, 0x15, 0x0e, # '3'
0x00, 0x07, 0x04, 0x04, 0x1f, # '4'
0x00, 0x17, 0x15, 0x15, 0x09, # '5'
0x00, 0x1f, 0x15, 0x15, 0x1d, # '6'
0x00, 0x03, 0x19, 0x05, 0x03, # '7'
0x00, 0x0a, 0x15, 0x15, 0x0a, # '8'
0x00, 0x02, 0x15, 0x15, 0x0e, # '9'
0x00, 0x00, 0x12, 0x00, 0x00, # ':'
0x00, 0x08, 0x1a, 0x00, 0x00, # ';'
0x00, 0x04, 0x0a, 0x11, 0x00, # '<'
0x00, 0x0a, 0x0a, 0x0a, 0x0a, # '='
0x00, 0x11, 0x0a, 0x04, 0x00, # '>'
0x00, 0x01, 0x15, 0x05, 0x02, # '?'
0x0e, 0x11, 0x15, 0x05, 0x06, # '@'
0x00, 0x1f, 0x05, 0x05, 0x1f, # 'A'
0x00, 0x1f, 0x15, 0x15, 0x0e, # 'B'
0x00, 0x0e, 0x11, 0x11, 0x0a, # 'C'
0x00, 0x1f, 0x11, 0x11, 0x0e, # 'D'
0x00, 0x1f, 0x15, 0x15, 0x11, # 'E'
0x00, 0x1f, 0x05, 0x05, 0x01, # 'F'
0x00, 0x0e, 0x11, 0x15, 0x1d, # 'G'
0x00, 0x1f, 0x04, 0x04, 0x1f, # 'H'
0x00, 0x11, 0x1f, 0x11, 0x00, # 'I'
0x00, 0x18, 0x10, 0x10, 0x1f, # 'J'
0x00, 0x1f, 0x04, 0x0a, 0x11, # 'K'
0x00, 0x1f, 0x10, 0x10, 0x10, # 'L'
0x1f, 0x02, 0x0c, 0x02, 0x1f, # 'M'
0x00, 0x1f, 0x06, 0x0c, 0x1f, # 'N'
0x00, 0x0e, 0x11, 0x11, 0x0e, # 'O'
0x00, 0x1f, 0x05, 0x05, 0x02, # 'P'
0x00, 0x0e, 0x15, 0x19, 0x1e, # 'Q'
0x00, 0x1f, 0x05, 0x0d, 0x12, # 'R'
0x00, 0x12, 0x15, 0x15, 0x09, # 'S'
0x01, 0x01, 0x1f, 0x01, 0x01, # 'T'
0x00, 0x0f, 0x10, 0x10, 0x0f, # 'U'
0x03, 0x0c, 0x10, 0x0c, 0x03, # 'V'
0x0f, 0x10, 0x0c, 0x10, 0x0f, # 'W'
0x11, 0x0a, 0x04, 0x0a, 0x11, # 'X'
0x01, 0x02, 0x1c, 0x02, 0x01, # 'Y'
0x00, 0x19, 0x15, 0x13, 0x11, # 'Z'
0x00, 0x1f, 0x11, 0x11, 0x00, # '['
0x01, 0x02, 0x04, 0x08, 0x10, # '\'
0x00, 0x11, 0x11, 0x1f, 0x00, # ']'
0x00, 0x02, 0x01, 0x02, 0x00, # '^'
0x10, 0x10, 0x10, 0x10, 0x10, # '_'
0x00, 0x01, 0x02, 0x00, 0x00, # '`'
0x00, 0x08, 0x1a, 0x1a, 0x1c, # 'a'
0x00, 0x1f, 0x14, 0x14, 0x08, # 'b'
0x00, 0x0c, 0x12, 0x12, 0x12, # 'c'
0x00, 0x08, 0x14, 0x14, 0x1f, # 'd'
0x00, 0x0c, 0x16, 0x16, 0x14, # 'e'
0x00, 0x04, 0x1e, 0x05, 0x01, # 'f'
0x00, 0x0c, 0x12, 0x1a, 0x08, # 'g'
0x00, 0x1f, 0x04, 0x04, 0x18, # 'h'
0x00, 0x14, 0x14, 0x1d, 0x10, # 'i'
0x00, 0x18, 0x10, 0x10, 0x1d, # 'j'
0x00, 0x1f, 0x08, 0x0c, 0x10, # 'k'
0x00, 0x11, 0x1f, 0x10, 0x00, # 'l'
0x1e, 0x02, 0x1e, 0x02, 0x1c, # 'm'
0x00, 0x1e, 0x02, 0x02, 0x1c, # 'n'
0x00, 0x0c, 0x12, 0x12, 0x0c, # 'o'
0x00, 0x1e, 0x0a, 0x0a, 0x04, # 'p'
0x00, 0x04, 0x0a, 0x0a, 0x1e, # 'q'
0x00, 0x1c, 0x02, 0x02, 0x02, # 'r'
0x00, 0x14, 0x1e, 0x1a, 0x0a, # 's'
0x00, 0x04, 0x0f, 0x14, 0x10, # 't'
0x00, 0x0e, 0x10, 0x10, 0x1e, # 'u'
0x00, 0x06, 0x18, 0x18, 0x06, # 'v'
0x0e, 0x10, 0x0e, 0x10, 0x0e, # 'w'
0x00, 0x12, 0x0c, 0x0c, 0x12, # 'x'
0x00, 0x02, 0x14, 0x1c, 0x02, # 'y'
0x00, 0x12, 0x1a, 0x16, 0x12, # 'z'
0x00, 0x04, 0x1f, 0x11, 0x11, # '{'
0x00, 0x00, 0x1f, 0x00, 0x00, # '|'
0x00, 0x11, 0x11, 0x1f, 0x04, # '}'
0x00, 0x01, 0x03, 0x02, 0x02] # '~'

class CylinderGadget(AlexaGadget):

    def __init__(self):
        super().__init__()
        self.lock = threading.Lock()
        self.main_thread = threading.Thread(target=self.main_loop)
        self.main_thread.start()
        self.wake=False
        self.indicate=False
        self.timer_end_time=None
        self.timer_token=None
        self.timer_active=False
        self.timer_ringing=False
        self.scroll_text=None
        self.scroll_time=False
        self.fcolor=(0,255,0)
        self.fcolor0=(0,255,0)
        self.bcolor=(0,0,0)
        self.bcolor0=(0,0,0)

    def get_color(self,name):
        c=color_constants.colors[name]
        return(c[0],c[1],c[2])

    def on_custom_cylinderlightgadget_message(self, directive):
        payload = json.loads(directive.payload.decode("utf-8"))
        print(payload)
        if 'message' in payload:
            if payload['message'].upper()=='TIME':
                self.scroll_time=True
                self.start_scroll(self.get_time(),self.fcolor,10)
            else:
                self.start_scroll(payload['message'].upper(),self.fcolor,10)
        if 'clear' in payload:
            try:
                self.scroll_text=None
                self.scroll_time=False
            except:
                pass
        if 'next' in payload:
            try:
                print("next TBD")
            except:
                pass
        if 'fcolor' in payload:
            try:
                self.fcolor=self.get_color(payload['fcolor'])
                print("fcolor="+self.fcolor)
            except:
                pass
        if 'bcolor' in payload:
            try:
                self.bcolor=self.get_color(payload['bcolor'])
                print("bcolor="+self.bcolor)
            except:
                pass

    def on_connected(self, device_addr):
        print("Connected")

    def on_disconnected(self, device_addr):
        self.timer_ringing=False
        print("Disconnected")

    def on_alexa_gadget_statelistener_stateupdate(self, directive):
        for state in directive.payload.states:
            if state.name == 'wakeword':
                if state.value == 'active':
                    self.wake=True
                elif state.value == 'cleared':
                    self.wake=False

    def on_notifications_setindicator(self, directive):
        self.indicate=True
        print("Set Notification Indicator")

    def on_notifications_clearindicator(self, directive):
        self.indicate=False
        print("Clear Notification Indicator")

    def on_alexa_gadget_speechdata_speechmarks(self, directive):
        #print("Got speechmarks")
        pass

    def on_alexa_gadget_musicdata_tempo(self, directive):
        print("Got tempo")

    def on_alerts_setalert(self, directive):
        if directive.payload.type != 'TIMER':
            print("Skipping non timer alerts")
            return
        t = dateutil.parser.parse(directive.payload.scheduledTime).timestamp()
        print("t="+str(t))
        if t<=0:
            return
        if self.timer_token==directive.payload.token:
            self.timer_end_time=t #adjustment to end time
            print("Adjust timer to "+str(t))
            return
        if self.timer_active:
            print("Timer already active -- only supporting one for now")
            return
        self.timer_end_time = t
        self.timer_token = directive.payload.token
        self.timer_active = True
        print("Starting timer for "+str(t))

    def on_alerts_deletealert(self, directive):
        if self.timer_token != directive.payload.token:
            print("Skipping delete alert for non-active timer")
            return
        print("Turning off timer")
        self.timer_active=False
        self.timer_token=None

    def render_char(self, s,c,col):
        offset=(ord(c)-32)*5
        w=0
        k=0
        c2=0
        for i in range(5):
            c2=font_data[offset+i]
            if (c2!=0 or c==' '):
                w=w+1
                mask=0x10
                for j in range(5):
                    if (c2&mask)!=0:
                        if ((s+i)>=0 and (s+i)<44):
                            pixels[self.pix(4-j+3,s+k)]=col
                    mask=mask>>1
                k=k+1
        return(w)

    def render_string(self,start,string,color):
        i=0
        while(start<44 and i<len(string)):
            w=self.render_char(start,string[i],color)
            start=start+w+1
            i=i+1

    def scroll_string(self,string,color,num):
        for i in range(num):
            p=43
            while(p>(-6*len(string))):
                for i in range(num_pixels):
                    pixels[i]=self.bcolor
                self.render_string(p,string,color)
                pixels.show()
                #time.sleep(0.01)
                p=p-1

    def start_scroll(self,string,color,num):
        self.p=43
        self.scroll_text=string
        self.scroll_color=color
        self.scroll_count=num

    def scroll_step(self):
        if(self.p>(-6*len(self.scroll_text))):
            #for i in range(num_pixels):
            #    pixels[i]=self.bcolor
            self.render_string(self.p,self.scroll_text,self.scroll_color)
            #pixels.show()
            self.p=self.p-1
        else:
            self.p=43 #change to scroll forever until cleared
            if self.scroll_time:
                self.scroll_text=self.get_time()

    def get_time(self):
        t=time.strftime("%I:%M")
        if t[0]=='0':
            t=t[1:]
        return(t)

    def show_time(self,color):
        t=time.strftime("%I:%M")
        if t[0]=='0':
            t=t[1:]
        self.scroll_string(t,(255,0,0),3)

    def wheel(self,pos):
        # Input a value 0 to 255 to get a color value.
        # The colours are a transition r - g - b - back to r.
        if pos < 0 or pos > 255:
            r = g = b = 0
        elif pos < 85:
            r = int(pos * 3)
            g = int(255 - pos*3)
            b = 0
        elif pos < 170:
            pos -= 85
            r = int(255 - pos*3)
            g = 0
            b = int(pos*3)
        else:
            pos -= 170
            r = 0
            g = int(pos*3)
            b = int(255 - pos*3)
        return (r, g, b) if ORDER == neopixel.RGB or ORDER == neopixel.GRB else (r, g, b, 0)

    def rainbow_cycle(self,wait):
        for j in range(255):
            for i in range(num_pixels):
                pixel_index = (i * 256 // num_pixels) + j
                pixels[i] = wheel(pixel_index & 255)
            pixels.show()
            #time.sleep(wait)

    def pixel_test(self):
        for i in range(num_pixels):
            pixels[i]=(255,0,0)
            pixels.show()
            #time.sleep(0.1)

    def blank(self):
        for i in range(num_pixels):
            pixels[i]=self.bcolor
        pixels.show()

    def vertical_sweep(self):
        for i in range(500):
            s=i%20
            for i in range(num_pixels):
                pixels[i]=self.bcolor
            for i in range(5):
                pixels[s*5+i]=(0,255,0)
            pixels.show()
            time.sleep(0.01)

    def ring(self,color):
        for c in range(cols):
            pixels[self.pix(0,c)]=color

    def multi_color(self):
        temp=[0,0,0,0,0,0,0,0,0,0,0]
        for i in range(num_pixels):
            pixels[i]=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
        for j in range(num_pixels*5):
            for i in range(11):
                temp[i]=pixels[self.pix(i,0)]
            for i in range(11):
                for k in range(43):
                    pixels[self.pix(i,k)]=pixels[self.pix(i,k+1)]
        for i in range(11):
            pixels[self.pix(i,43)]=temp[i]
        pixels.show()
        time.sleep(0.05)

    def multi_color2(self):
        self.blank()
        for i in range(500):
            for i in range(5):
                pixels[i]=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
            for i in range(19):
                for j in range(5):
                    pixels[5+(18-i)*5+j]=pixels[5+((18-i)-1)*5+j]
            pixels.show()
            time.sleep(0.5)

    def pix(self,row,col):
        return(row*44+(row%2)*(43-col)+(1-row%2)*col)

    def spin(self,delay,steps):
        temp=[0,0,0,0,0,0,0,0,0,0,0]
        for j in range(steps):
            for i in range(11):
                temp[i]=pixels[self.pix(i,0)]
            for i in range(11):
                for k in range(43):
                    pixels[self.pix(i,k)]=pixels[self.pix(i,k+1)]
            for i in range(11):
                pixels[self.pix(i,43)]=temp[i]
            pixels.show()
            #time.sleep(delay)

    def stripes(self,step,r,w):
        for row in range(rows):
            for col in range(cols):
                if ((col+row)%step==0):
                    pixels[self.pix(row,col)]=r#colors[(col+row)%11]
                else:
                    pixels[self.pix(row,col)]=w
        pixels.show()

    def rect(self):
        self.blank()
        for i in range(20):
            pixels[self.pix(0,i)]=(255,0,0)
            pixels[self.pix(4,i)]=(255,0,0)
        for i in range(5):
            pixels[self.pix(i,0)]=(0,255,0)
            pixels[self.pix(i,19)]=(0,0,255)
        pixels.show()
        time.sleep(30)

    def zigzag(self):
        f=True
        c=(255,0,0)
        for i in range(500):
            if (i%20)==0:
                c=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
            if (i%5)==0:
                f=not f
            row=i%5
            if f:
                row=4-row
            pixels[self.pix(row,i%20)]=c
            pixels.show()
            time.sleep(0.1)

    def countdown(self,height):
        #print("height="+str(height))
        for c in range(cols):
            for r in range(10-height):
                pixels[self.pix(r+1,c)]=self.bcolor #paint black at the top
            for r in range(height):
                pixels[self.pix(10-r,c)]=(255,0,0) #and red at the bottom

    def main_loop(self):
        self.fcolor=(0,255,0)
        self.fcolor0=(0,255,0)
        self.bcolor=(0,0,0)
        self.bcolor0=(0,0,0)
        self.blank()
        cnt=0
        lit=True
        while True:
            cnt=cnt+1
            try:
                if self.bcolor!=self.bcolor0: #if background color changed
                    for i in range(num_pixels):
                        if (i>=44):
                            pixels[i]=self.bcolor #color all background
                        else:
                            pixels[i]=(0,0,0)
                    self.bcolor0=self.bcolor
                if self.fcolor!=self.fcolor0: #if foreground color changed
                    self.scroll_color=self.fcolor #set it for scrolling
                    self.fcolor0=self.fcolor
                for i in range(num_pixels): #fill the background
                    if (i>=44):
                        pixels[i]=self.bcolor #color all background
                    else:
                        pixels[i]=(0,0,0)
                if self.timer_ringing and not self.timer_active:
                    self.countdown(0)
                    self.timer_ringing=False
                if self.timer_active:
                    rem=self.timer_end_time-time.time() #calculate second remaining
                    self.time_remaining=int(rem)
                    #print("time remaining = "+str(self.time_remaining))
                    if rem<=0 and not self.timer_ringing: #if our timer went off set it inactive
                        print("Timer ringing")
                        self.timer_ringing=True
                    if self.timer_ringing:
                        if lit:
                            self.countdown(10)
                        else:
                            self.countdown(0)
                        if cnt%10==0:
                            lit=not lit
                    elif self.time_remaining<11: #check if we're in the final 10 seconds
                        self.countdown(self.time_remaining) #illustrate the countdown
                    else:
                        pass #consider displaying time remaining in seconds in digits or something
                if (self.scroll_text!=None): #draw any scrolling text
                    self.scroll_step()
                if (self.wake):
                    self.ring((0,0,255)) #blue for wakeword
                else:
                    if (self.indicate):
                        self.ring((255,255,0)) #yellow for notification
                pixels.show()
            except:
                traceback.print_exc()
            #self.blank()
            #self.stripes(4,(255,0,0),(0,0,0))
            #self.spin(0.0,40)
            #self.stripes(4,(0,0,255),(0,0,0))
            #self.spin(0.0,40)
            #self.stripes(4,(0,255,0),(0,0,0))
            #self.spin(0.0,40)
            #self.show_time((255,0,0))
            #self.scroll_string("DO YOU LIKE THE CYLINDER LIGHT?",(0,255,0),1)

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


import pygame
import sys
import lcm
import lasvegas

    # #################### #
    # Parámetros del juego #
    # #################### #

SCREEN_W = 20
SCREEN_H = 20
# Tamaño del pixel
SIZE = 40
# Tamaño max del túnel
MAX_T_SIZE = 8
# Tamaño número de túneles
MAX_T_NUM = 72
# Densidad de enemigos
D = 0.02
# Densidad de recompensas
D2 = 0.01
# Densidad de árboles
DT = 0.2
# Densidad de suelos
DG = 0.2

    # ############################################### #
    # Inicializacion del Mapa en array biddimesional  #
    # ############################################### #

def initMap(W, H):
    fila = [0] * W
    map = []
    for i in range(H):
        map.append(fila[:])
    return map

    # ###################################### #
    # Print del Mapa en array biddimesional  #
    # ###################################### #

def printMap(map, xPj, yPj):
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_W * SIZE, SCREEN_H * SIZE))
    pygame.display.set_caption("Practica2")

    # ################ #
    # Carga de Assets  #
    # ################ #

    resources = dict()
    resources['tree'] = pygame.image.load("resources/p2/tree.png").convert()
    resources['tree'] = pygame.transform.scale(resources['tree'], (SIZE, SIZE))
    resources['tree2'] = pygame.image.load("resources/p2/tree2.png").convert()
    resources['tree2'] = pygame.transform.scale(resources['tree2'], (SIZE, SIZE))
    resources['grass'] = pygame.image.load("resources/p2/grass.png").convert()
    resources['grass'] = pygame.transform.scale(resources['grass'], (SIZE, SIZE))
    resources['grass2'] = pygame.image.load("resources/p2/grass2.png").convert()
    resources['grass2'] = pygame.transform.scale(resources['grass2'], (SIZE, SIZE))
    resources['pj'] = pygame.image.load("resources/p2/pj.png").convert()
    resources['pj'] = pygame.transform.scale(resources['pj'], (SIZE, SIZE))
    resources['e1'] = pygame.image.load("resources/p2/suicune.png").convert()
    resources['e1'] = pygame.transform.scale(resources['e1'], (SIZE, SIZE))
    resources['e2'] = pygame.image.load("resources/p2/entei.png").convert()
    resources['e2'] = pygame.transform.scale(resources['e2'], (SIZE, SIZE))
    resources['e3'] = pygame.image.load("resources/p2/raikou.png").convert()
    resources['e3'] = pygame.transform.scale(resources['e3'], (SIZE, SIZE))
    resources['poke'] = pygame.image.load("resources/p2/poke.png").convert()
    resources['poke'] = pygame.transform.scale(resources['poke'], (SIZE, SIZE))

    # Recorremos el mapa y elegimos si pintar suelo o pared
    # Si es suele elegimos aleatoriamente si enemigo, recompensa o los tipos de suelo
    # Si es pared elegimos aleatoriamente que tipo de pared
    # Finalmente colocamos el personaje

    for i in range(len(map)):
        for j in range(len(map[0])):
            if(map[i][j] == 1):
                if lcm.randomLCM(lcm.c) / lcm.c['M'] < D:
                    r = int(lasvegas.randomLasVegas(0,3))
                    if(r == 0):
                        screen.blit(resources['e1'], (i * SIZE, j * SIZE))
                    elif(r == 1):
                        screen.blit(resources['e2'], (i * SIZE, j * SIZE))
                    else:
                        screen.blit(resources['e3'], (i * SIZE, j * SIZE))
                elif lcm.randomLCM(lcm.c) / lcm.c['M'] < D2:
                    screen.blit(resources['poke'], (i * SIZE, j * SIZE))
                else:
                    if lcm.randomLCM(lcm.c) / lcm.c['M'] < DG:
                        screen.blit(resources['grass2'], (i * SIZE, j * SIZE))
                    else:
                        screen.blit(resources['grass'], (i * SIZE, j * SIZE))
            else:
                if lcm.randomLCM(lcm.c) / lcm.c['M'] < DT:
                    screen.blit(resources['tree2'], (i * SIZE, j * SIZE))
                else:
                    screen.blit(resources['tree'], (i * SIZE, j * SIZE))
    screen.blit(resources['pj'], (xPj * SIZE, yPj * SIZE))

def randomWalk(W, H, T, L, map):

    # Elijo posicion inicial
    x = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * W)
    y = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * H)
    xPj = x
    yPj = y
    #print(x)
    #print(y)

    # En cada iteración guardo el movimiento anterior, para no poder repetirlo.
    # También guardo si me he chocado con una pared para no ir ni a la dirección anterior
    # ni a la que me sacaría del mapa.
    # Si al crear un túnel me salgo del mapa, genero el túnel la distancia que me quepa dentro del mismo
    # y continúo generando otro túnel que no vaya hacia atrás ni se salga del mapa.

    last = [-1, -1]
    for i in range(T):
        check = True
        l = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * L + 1)
        g = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * 4)
        if last[0] == 0:
            while (g == 1 or g == last[1]):
                g = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * 4)
        elif last[0] == 1:
            while (g == 0 or g == last[1]):
                g = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * 4)
        elif last[0] == 2:
            while (g == 3 or g == last[1]):
                g = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * 4)
        elif last[0] == 3:
            while (g == 2 or g == last[1]):
                g = int(lcm.randomLCM(lcm.c) / lcm.c['M'] * 4)

        #print("giro ",g)
        #print("tamaño ", l)

        # Derecha
        if (g == 0):
            if (x + l < W):
                for j in range(0, l):
                    map[x+1+j][y] = 1
                x += l
                last[0] = g
            else:
                for j in range(0, W - x - 1):
                    map[x+1+j][y] = 1
                x = W - 1
                last[1] = g
        # Izq
        elif (g == 1):
            if (x - l >= 0):
                for j in range(0, l):
                    map[x - 1 - j][y] = 1
                x -= l
                last[0] = g
            else:
                for j in range(0, x):
                    map[x - 1 - j][y] = 1
                x = 0
                last[1] = g

        # Arriba
        elif (g == 2):
            if (y - l >= 0):
                for j in range(0, l):
                    map[x][y - 1 - j] = 1
                y -= l
                last[0] = g
            else:
                for j in range(0, y):
                    map[x][y - 1 - j] = 1
                y = 0
                last[1] = g
        # Abajo
        elif (g == 3):
            if (y + l < H):
                for j in range(0, l):
                    map[x][y + 1 + j] = 1
                y += l
                last[0] = g
            else:
                for j in range(0, H - y - 1):
                    map[x][y + 1 + j] = 1
                y = H - 1
                last[1] = g
        #print(x)
        #print(y)
    return [map, xPj, yPj]

def main():
    map = initMap(SCREEN_W, SCREEN_H)
    map, xPj, yPj = randomWalk(SCREEN_W, SCREEN_H, MAX_T_NUM, MAX_T_SIZE, map)

    printMap(map, xPj, yPj)

    pygame.display.flip()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

if __name__ == '__main__':
    main()


# coding: utf-8

import time
import socket
import struct
from bencode import bencode, bdecode
from random import randint
from threading import Thread, Timer, Lock

BOOTSTRAP_ADDR = ("router.bittorrent.com", 6881)
# BOOTSTRAP_ADDR = ("dht.transmissionbt.com", 6881)

def btih2info_hash(btih):
    info_hash = ''
    for i in range(0, len(btih), 2):
        info_hash += chr(int(btih[i:i + 2], 16))
    return info_hash

def random_bytes(n):
    return ''.join((list(chr(randint(0, 255)) for _ in range(n))))

def random_nid():
    return random_bytes(20)

def random_tid():
    return random_bytes(2)

def random_token():
    return random_bytes(8)

def distance(s1, s2):
    return sum(bin(ord(a) ^ ord(b)).count('1') for a, b in zip(s1, s2))

def create_socket(ip, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.bind((ip, port))
    return s

class Node:

    def __init__(self, nid, ip, port):
        self.nid = nid
        self.ip = ip
        self.port = port
        self.queried = 0

    def __hash__(self):
        return hash(self.nid)

    def __eq__(self, other):
        return self.nid == other.nid

    def __str__(self):
        self.__repr__()

    def __repr__(self):
        return "node<nid: %s, ip: %s, port: %d, queried: " % (self.nid, self.ip, self.port) + str(self.queried) + ">"

class Peer:

    def __init__(self, ip, port):
        self.addr = (ip, port)
        self.asked = False

    def __hash__(self):
        return hash(self.addr)

    def __eq__(self, other):
        return self.addr == other.addr

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        ip, port = self.addr
        return "peer<ip: %s, port: %d, asked: %s>" % (ip, port, self.asked)

class MsgMaker:

    def __init__(self):
        pass

    def form_krpc_msg(self, y, msg_content, tid=None):
        if not tid:
            tid = random_tid()
        msg = {
            't': tid,
            'y': y
        }
        msg.update(msg_content)
        return msg

    def form_query_get_peers(self, nid, info_hash):
        query = {
            'q': 'get_peers',
            'a': {
                'id': nid,
                'info_hash': info_hash
            }
        }
        return self.form_krpc_msg('q', query)

    def form_response_get_peers(self, nid, tid):
        response = {
            'r': {
                'id': nid,
                'token': random_token(),
                'nodes': ''
            }
        }
        return self.form_krpc_msg('r', response, tid)

    def form_response_announce_peer(self, nid, tid):
        response = {
            'r': {
                'id': nid
            }
        }
        return self.form_krpc_msg('r', response, tid)

    def form_response_ping(self, nid, tid):
        response = {
            'r': {
                'id': nid
            }
        }
        return self.form_krpc_msg('r', response, tid)

class DHTProtocolHandler:

    def __init__(self):
        self.mm = MsgMaker()
        self.s = create_socket("0.0.0.0", 6882)

        self.info_hash = None
        self.nid = random_nid()

        self.nodes_lock = Lock()
        self.nodes = set()

        self.peers_lock = Lock()
        self.peers = set()

        self.tids = list()

    def send_msg(self, msg, dst):
        self.s.sendto(bencode(msg), dst)

    def bootstrap(self):
        if self.nodes == set():
            self.send_get_peers(BOOTSTRAP_ADDR)
            Timer(3, self.bootstrap).start()
        else:
            pass

    def get_torrent(self, info_hash):
        self.info_hash = info_hash
        self.bootstrap()

    def send_get_peers(self, address):
        msg = self.mm.form_query_get_peers(self.nid, self.info_hash)
        self.tids.append(msg['t'])
        self.send_msg(msg, address)

    def recv_msg(self):
        while True:
            try:
                msg_bencode, addr = self.s.recvfrom(65536)
                break
            except Exception:
                pass
        return bdecode(msg_bencode), addr

    def on_query(self, tid, q, addr):
        print('query received: %s' % q)
        if q == 'find_node':
            pass
        elif q == 'get_peers':
            self.on_query_get_peers(tid, addr)
        elif q == 'announce_peer':
            self.on_query_announce_peer(tid, addr)
        elif q == 'ping':
            self.on_query_ping(tid, addr)
        else:
            pass

    def on_query_get_peers(self, tid, addr):
        msg = self.mm.form_response_get_peers(self.nid, tid)
        self.send_msg(msg, addr)

    def on_query_announce_peer(self, tid, addr):
        msg = self.mm.form_response_announce_peer(self.nid, tid)
        self.send_msg(msg, addr)

    def on_query_ping(self, tid, addr):
        msg = self.mm.form_response_ping(self.nid, tid)
        self.send_msg(msg, addr)

    def on_response(self, tid, response):
        if tid in self.tids:
            self.on_response_get_peers(response)
            self.tids.remove(tid)
        else:
            print('tid=%s not exist.' % str(tid))

    def on_response_get_peers(self, response):
        if response.has_key('values'):
            self.decode_peers(response['values'])
        if response.has_key('nodes'):
            self.decode_nodes(response['nodes'])

    def decode_peers(self, peers):
        for peer in peers:
            ip = socket.inet_ntoa(peer[:4])
            port, = struct.unpack('>H', peer[4:])
            self.peers_lock.acquire()
            self.peers.add(Peer(ip, port))
            self.peers_lock.release()

    def decode_nodes(self, nodes):
        for i in range(0, len(nodes), 26):
            nid = nodes[i:i + 20]
            ip = socket.inet_ntoa(nodes[i + 20:i + 24])
            port, = struct.unpack('>H', nodes[i + 24:i + 26])
            node = Node(nid, ip, port)
            self.nodes_lock.acquire()
            self.nodes.add(node)
            self.nodes_lock.release()

    def msg_listener(self):
        while True:
            msg, addr = self.recv_msg()
            try:
                y = msg['y']
                if y == 'q':
                    self.on_query(msg['t'], msg['q'], addr)
                elif y == 'r':
                    self.on_response(msg['t'], msg['r'])
                elif y == 'e':
                    print(msg['e'])
                else:
                    pass
            except:
                print("no dht msg recved -> ", msg)

    def auto_get_peers(self):
        while True:
            send_count = 0
            self.nodes_lock.acquire()
            for node in self.nodes:
                if send_count >= 300:
                    break
                if node.queried < 3:
                    self.send_get_peers((node.ip, node.port))
                    node.queried += 1
                    send_count += 1
            self.nodes_lock.release()
            time.sleep(1)

    def auto_get_metadata(self):
        md = MetadataDownloader()
        while True:
            self.peers_lock.acquire()
            peers = self.peers.copy()
            self.peers_lock.release()
            for peer in peers:
                if peer.asked == True:
                    continue
                print('try to get metadata from (%s, %d)' %peer.addr)
                metadata = md.get_metadata(self.info_hash, peer.addr)
                peer.asked = True
                if metadata != None:
                    # todo metadata got
                    return
            if len(peers) == len(self.peers):
                for peer in peers:
                    peer.asked = False
            time.sleep(1)

    def run(self):
        auto_get_peers_thread = Thread(target=self.auto_get_peers)
        auto_get_metadata_thread = Thread(target=self.auto_get_metadata)
        msg_listener_thread = Thread(target=self.msg_listener)
        auto_get_peers_thread.start()
        auto_get_metadata_thread.start()
        msg_listener_thread.start()

class MetadataDownloader:

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.settimeout(5)
        self.peerid = random_nid()
        self.info_hash = None

    def get_metadata(self, info_hash, remote_peer):
        self.info_hash = info_hash
        try:
            self.s.connect(remote_peer)
            print('connect remote peer (%s, %d) succeed.' %remote_peer)
            self.send_peer_handshake()
            msg = self.recv_msg()
            print(msg)
        except:
            print('connect remote peer (%s, %d) error.' %remote_peer)
            self.s.close()
            self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.s.settimeout(5)
            return

    def send_msg(self, msg):
        self.s.send(msg)

    def recv_msg(self):
        return self.s.recv(65535)

    def send_peer_handshake(self):
        msg = ''
        msg += '\x13BitTorrent protocol'
        msg += '\x00\x00\x00\x00\x00\x10\x00\x00'
        msg += info_hash
        msg += self.peerid
        self.send_msg(msg)

if __name__ == "__main__":
    from sys import argv
    if len(argv) != 2:
        print('Only a 40 bytes infohash is required as an argument.')
        exit(0)
    info_hash = btih2info_hash(argv[1])

    dht = DHTProtocolHandler()
    dht.run()
    dht.get_torrent(info_hash)


from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import DynamicTemplateData, Mail

from ..config.settings import settings
from ..schemas.userSchema import User

sg = SendGridAPIClient(settings.sendgrid_key)
SENDER_EMAIL = "emekaallison4@gmail.com"

async def send_email(
    recipient: User, message: str, subject: str, action: str = None, url: str = None
):
    msg = Mail(
        from_email=(SENDER_EMAIL, "BizzBuzz Notification"),
        to_emails=recipient.email,
        subject=subject,
    )

    msg.template_id = "d-0a5bc2da6d9d41fdb734d78525c9e20e"

    message_action = action or "Continue to BizzBuzz"
    message_url = url or "https://bizzbuzz.com"

    msg.dynamic_template_data = {
        "name": recipient.first_name,
        "message": message,
        "action": message_action,
        "url": message_url,
    }

    try:
        sg.send(msg)
    except Exception as e:
        print(e)


from nes_py.wrappers import JoypadSpace
import gym_super_mario_bros
from gym_super_mario_bros.actions import SIMPLE_MOVEMENT
from gym.wrappers import FrameStack, GrayScaleObservation
from stable_baselines3.common.vec_env import VecFrameStack, DummyVecEnv
from make_env import make_env
from matplotlib import pyplot as plt
import os
import sys
import time
from stable_baselines3 import PPO
#reloaded base callback for saving models
from stable_baselines3.common.callbacks import BaseCallback
import torch
from model import *
from model_utility import init_weights, plot_average, model_plays

game = sys.argv[1]
if game == 'Mario':
    env = gym_super_mario_bros.make('SuperMarioBros-v3')
    env = JoypadSpace(env, SIMPLE_MOVEMENT)

    #grayscale
    env = GrayScaleObservation(env, keep_dim=True)

    #wrap it inside dummyENV
    # env = DummyVecEnv([lambda: env])

    # #Stack the Frames
    # env = VecFrameStack(env, 4, channels_order = 'last')

else:
    env = make_env(game)

state = env.reset()
print(state.shape)

# Load model
state_dict = torch.load(f'{game}_final_experiment/latest_model.pt')
# setup models
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
action_size = env.action_space.n
image_size = env.observation_space.shape[:2]

train_model = DQN(image_size, action_size).to(device)
train_model.apply(init_weights)
train_model.load_state_dict(state_dict['train_model'])

target_model = DQN(image_size, action_size).to(device)
target_model.apply(init_weights)
target_model.load_state_dict(state_dict['target_model'])
print(type(state_dict['train_model']))
# optimizer = torch.optim.Adam(train_model.parameters(), lr=1e-2)
# optimizer = optimizer.load_state_dict(state_dict['optimizer'])

# Start the game
state = env.reset()
state = state.transpose((2, 0, 1))
state = torch.autograd.Variable(torch.from_numpy(state).float().unsqueeze(0))
state = state.to(device)
Agent = DQNAgent(train_model, target_model, env, device)

# Loop through the game

for epoch in range(5000):
    Agent.eps = 0
    action = Agent.generate_action(state)
    new_state, reward, done, info = env.step(action.item())
    env.render()
    new_state = new_state.transpose((2, 0, 1))
    new_state = torch.autograd.Variable(torch.from_numpy(new_state).float().unsqueeze(0))
    state = new_state.to(device)
    time.sleep(0.1)
    if done:
        break

# while True:
#     action, _ = model.predict(state)
#     state, reward, done, info = env.step(action)
#     env.render()


# -*- coding: utf-8 -*-
import click
import os
import signal

from gunicorn import util
from pyft import __version__, settings

@click.group()
def cli():
    pass

@cli.command('run', help='Run worker server.')
@click.option('--env', '-e', default='dev', help='Run as a daemon.')
def run(env):
    """ 웹서버를 실행한다.

    웹서버 환경은 dev, prod 로 구분되고 프로세스 개수는 환경에 따라 다르다.

    dev 모드는 무조건 1개로 고정하고 prod 모드는 settings.SERVER_PROCESS 값만큼 결정된다.

    """
    from pyft.app import App

    options = {
        'bind': '%s:%s' % (settings.SERVER_HOST, settings.SERVER_PORT),
        'timeout': settings.SERVER_TIMEOUT,
        'pidfile': settings.SERVER_PID_FILE,
        'loglevel': 'debug' if settings.DEBUG else 'error',
        'proc_name': settings.SERVER_PROCESS_NAME,
        'limit_request_lint': settings.LIMIT_REQUEST_LINE,
        'limit_request_fields': settings.LIMIT_REQUEST_FIELDS,
        'limit_request_field_size': settings.LIMIT_REQUEST_FIELD_SIZE,
    }

    if env == 'prod':
        util.daemonize(False)
        options['workers'] = int(settings.SERVER_PROCESS)

    App(options).run()

@cli.command('shutdown', help='Shutdown running servers.')
@click.option('--now', '-n', is_flag=True, help='Shutdown now.')
def shutdown(now):
    """ 웹서버를 종료한다."""
    try:
        if settings.SERVER_PID_FILE:
            pidfile = settings.SERVER_PID_FILE
            if os.path.exists(pidfile):
                with open(pidfile) as f:
                    pid = int(f.read().strip())
                os.kill(pid, signal.SIGKILL if now else signal.SIGTERM)
                click.echo(pid)
    except ProcessLookupError as e:
        click.echo(e)

@cli.command(help='Print version string.')
def version():
    click.echo(__version__)

def main():
    cli()


from datetime import datetime
import json
import re

def date_format(date):
    d = date.split('/')

    year = f'20{d[2]}'
    month = d[0] if len(d[0]) == 2 else f'0{d[0]}'
    day = d[1]

    return f'{year}-{month}-{day}'

def remove_countries(countries):
    del_idx = []
    for idx, country in enumerate(countries['series']):
        # remove countries without data
        if len(country['values']) <= 0:
            del_idx.append(idx)
            continue

        # sort values by date
        country['values'] = sorted(country['values'], key=lambda value: value['date'])

        stats = country['values'][-1]

        # remove countries with less than 1000 cases
        if stats['cases'] < 1000:
            del_idx.append(idx)
            continue

        country['stats'] = {
            'cases': stats['cases'],
            'deaths': stats['deaths'],
            'recovered': stats['recovered'],
            'largest_increase': country['stats']['largest_increase']}

    for idx in sorted(del_idx, reverse=True):
        del countries['series'][idx]

    return countries

def get_largest_increase(values):
    li = {
        'date': None,
        'increase': 0
    }

    prev = 0
    for value in values:
        increase = value['cases'] - prev

        if increase > li['increase']:
            li['increase'] = increase
            li['date'] = value['date']

        prev = value['cases']

    return li

def get_country_data():
    countries = {
        'dates': [],
        'series': []
    }

    dates = []

    with open('lookup.json', 'r') as f:
        lookup = json.loads(f.read())

    with open('countries.json', 'r') as f:
        data = json.loads(f.read())['data']

    for d_country in data:
        if d_country['countrycode'] not in lookup:
            continue

        d_country['name'] = lookup[d_country['countrycode']]
        d_country['date'] = date_format(d_country['date'])
        dates.append(d_country['date'])

        found = False
        for country in countries['series']:
            if d_country['name'] != country['name']:
                continue

            recovered = d_country['recovered']

            try:
                recovered = int(recovered)
            except:
                continue

            found = True
            country['values'].append({
                'cases': int(d_country['cases']),
                'deaths': int(d_country['deaths']),
                'recovered': recovered,
                'date': d_country['date'],
            })

        if not found:
            countries['series'].append({
                'name': d_country['name'],
                'stats': {
                    'cases': 0,
                    'deaths': 0,
                    'recovered': 0,
                    'largest_increase': {
                        'prev': 0,
                        'date': None,
                        'increase': 0
                    }
                },
                'values': []
            })

    countries = remove_countries(countries)

    for country in countries['series']:
        country['stats']['largest_increase'] = get_largest_increase(country['values'])

    countries['dates'] = sorted(list(set(dates)))
    countries['series'] = sorted(countries['series'], key=lambda country: country['stats']['cases'], reverse=True)

    return countries

def str_to_int(s):
    s = re.sub(r'[\D]', '', s)
    return int(s.encode('ascii', 'ignore'))

def get_states():
    states = {
        'dates': [],
        'series': []
    }

    with open('states.json', 'r') as f:
        response = json.loads(f.read())

    dates = []

    for idx, i in enumerate(response):
        date = str(i['date'])
        response[idx]['date'] = f'{date[:4]}-{date[4:6]}-{date[-2:]}'

        dates.append(i['date'])

        if 'positive' not in i or i['positive'] is None:
            i['positive'] = 0

        found = False
        for state in states['series']:
            if state['name'] != i['state']:
                continue

            found = True
            state['values'].insert(0, i)

            if 'positiveIncrease' not in i or i['positiveIncrease'] is None:
                continue

            if state['stats']['largest_increase']['increase'] < i['positiveIncrease']:
                state['stats']['largest_increase']['increase'] = i['positiveIncrease']
                state['stats']['largest_increase']['date'] = i['date']

        if not found:
            states['series'].append({
                'name': i['state'],
                'stats': {**i,
                          'largest_increase': {
                              'increase': i['positiveIncrease'],
                              'date': i['date']
                          }
                          },
                'values': [i]
            })

    states['dates'] = sorted(list(set(dates)))
    states['series'] = sorted(states['series'], key=lambda state: state['stats']['positive'], reverse=True)

    return states

print('const UPDATED = "%s";' % str(datetime.utcnow()))
print('const DATA = %s;' % json.dumps(get_country_data()).replace('", "', '","'))
print('const STATES = %s;' % json.dumps(get_states()).replace('", "', '","'))


from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import svm
from sklearn.feature_selection import VarianceThreshold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
from sklearn.naive_bayes import BernoulliNB
from sklearn.neural_network import MLPClassifier
from sklearn.svm import LinearSVC
import numpy as np
import sys

#put the data in the correct format in order to use scikit
def setData( temp, max_coln ):
    data = np.zeros(shape=(1842, int(max_coln + 1)))

    for x in temp:
        row = int(x[0]) - 1
        col = int(x[1])
        data[row,col] = x[2]

    return data

#put the data in the correct format in order to use scikit
def setTestingData(temp, max_column):
    data = np.zeros(shape=(952, int(max_column + 1)))

    for x in temp:
        row = int(x[0]) - 1
        col = int(x[1])
        data[row,col] = x[2]

    return data

# extract features selected in feature reduction process and use the same for the test data
def reduce_test_data(indexes_to_keep, test_data):
    reduced_test_data = np.zeros(shape=(952, indexes_to_keep.size))
    for element_index in range(0, 952):
        feature_count = 0
        for idx in indexes_to_keep:
            reduced_test_data[element_index][feature_count] = test_data[element_index][idx]
            feature_count = feature_count + 1

    return reduced_test_data

def getDataSets():
    training_file = 'DataFiles/training.txt'
    training_labels_file = 'DataFiles/label_training.txt'
    testing_file = 'DataFiles/testing.txt'

    class_labels = np.genfromtxt(training_labels_file)
    temp_training_data = np.genfromtxt(training_file)
    training_set = setData(temp_training_data, temp_training_data.max())
    temp_test_data = np.genfromtxt(testing_file)
    test_data = setTestingData(temp_test_data, temp_test_data.max())

    return training_set, class_labels, test_data

def main():
    # get data sets in numpy array to run scikit algorithms on
    data_set, data_labels, test_data = getDataSets()

    # Reduce features based off feature variance.
    sel = VarianceThreshold(threshold=(.05))
    feature_reduced_data_set = sel.fit_transform(data_set)
    indexes_selected = sel.get_support(indices=True)
    reduced_test_data = reduce_test_data(indexes_selected, test_data)

    # train various classifiers
    neigh = KNeighborsClassifier(n_neighbors=50)
    k_neighbor_scores = cross_val_score(neigh, feature_reduced_data_set, data_labels, cv=5)
    ann = MLPClassifier(solver='lbfgs', alpha=1e-5, hidden_layer_sizes=(5, 2), random_state=1)
    ann_scores = cross_val_score(ann, feature_reduced_data_set, data_labels, cv=5)
    svm = LinearSVC()
    svm_scores = cross_val_score(svm, feature_reduced_data_set, data_labels, cv=5)

    # print accuracy Score of KNeighbor
    print("K_N Accuracy: %0.2f (+/- %0.2f)" % (k_neighbor_scores.mean(), k_neighbor_scores.std() * 2))
    print("ANN Accuracy: %0.2f (+/- %0.2f)" % (ann_scores.mean(), ann_scores.std() * 2))
    print("SVM Accuracy Score: %0.2f (+/- %0.2f)" % (svm_scores.mean(), svm_scores.std() * 2))

    # SVM was best algorithm, so label test data through classifer and write to file
    svm.fit(feature_reduced_data_set, data_labels)
    label_training_list = svm.predict(reduced_test_data)
    f = open('label_test.txt', 'w')
    for label in label_training_list:
        f.write(str(int(label)))
        f.write('\n')
    print('SVM Classifer used! Test labels written to label_test.txt')

if __name__ == '__main__':
    main()


from .base_settings import *

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('DEVELOPMENT_SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'

MEDIA_URL = 'media/'
MEDIA_ROOT = BASE_DIR / 'media'

print('using development settings')


import matplotlib.pyplot as plt
import numpy as np

snr_per_bit_dB = np.linspace(-20, 40, 10000)  # dB
c = np.log2(1 + 10 ** (snr_per_bit_dB / 10))  # remember to do the foruma in linear
'''
# Work backwards
c = np.linspace(0.1, 10, 1000)
snr_per_bit = (2**c - 1)
snr_per_bit_dB = 10.0*np.log10(snr_per_bit)
'''
fig, ax = plt.subplots(figsize=(7, 4))

# actual signal
ax.plot(snr_per_bit_dB, c, 'r--')

ax.axis([-20, 30, 0, 10])
# ax.grid(True)

ax.set_xlabel('SNR [dB]')
ax.set_ylabel('Shannon Limit [bits/s/Hz]')

# set the x-spine (see below for more info on `set_position`)
ax.spines['left'].set_position('zero')

# turn off the right spine/ticks
ax.spines['right'].set_color('none')
ax.yaxis.tick_left()

# set the y-spine
ax.spines['bottom'].set_position('zero')

# turn off the top spine/ticks
ax.spines['top'].set_color('none')
ax.xaxis.tick_bottom()

# Turn off tick numbering/labels
# ax.set_xticklabels([])
# ax.set_yticklabels([])

plt.show()

fig.savefig('../_static/shannon_limit.svg', bbox_inches='tight')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" calisphere extent stats """

import sys
import argparse
import re
from datetime import date
import itertools
import json
import xlsxwriter
import requests
from pprint import pprint as pp
import ConfigParser
import time

FACETS = [
    'title_ss',
    'alternative_title_ss',
    'contributor_ss',
    'coverage_ss',
    'creator_ss',
    'date_ss',
    'description_ss',
    'extent_ss',
    'format_ss',
    'genre_ss',
    'language_ss',
    'location_ss',
    'publisher_ss',
    'relation_ss',
    'rights_ss',
    'rights_holder_ss',
    'rights_note_ss',
    'source_ss',
    'subject_ss',
    'temporal_ss',
]

def main(argv=None):
    parser = argparse.ArgumentParser()
    parser.add_argument('--pynuxrc')
    parser.add_argument('--reportrc')

    if argv is None:
        argv = parser.parse_args()

    #calisphere_extent =

    calisphere_data = parse_calisphere(argv.reportrc)

def parse_calisphere(reportrc=None):
    config = ConfigParser.SafeConfigParser()
    config.read('report.ini')
    solr_url = config.get('calisphere', 'solrUrl')
    solr_auth = { 'X-Authentication-Token': config.get('calisphere', 'solrAuth') }
    base_query = {
        'facet': 'true',
        'rows': 0,
        'facet.limit': 10000,
    }

    # non_uc_query.update({'q': '-campus_url:*',})

    run = '{}'.format(time.ctime())

    # open the workbook
    workbook = xlsxwriter.Workbook('metadata_facets.xlsx')

    # formats
    header_format = workbook.add_format({'bold': True, })
    number_format = workbook.add_format()
    number_format.set_num_format('#,##0')

    for facet in FACETS:
        base_query.update({'facet.field': facet})
        start = json.loads(requests.get(solr_url,
                                        headers=solr_auth,
                                        params=base_query,
                                        verify=False).text)
        payload = start.get('facet_counts').get('facet_fields').get(facet)
        payload = zip(*[iter(payload)]*2)

        sheet = workbook.add_worksheet(facet)
        for row, val in enumerate(payload):
            sheet.write(row, 0, val[1], number_format)
            sheet.write(row, 1, val[0])

    workbook.close()

#def calisphere_stats():

"""

 * query

"""

# main() idiom for importing into REPL for debugging
if __name__ == "__main__":
    sys.exit(main())

"""
Copyright © 2016, Regents of the University of California
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
- Neither the name of the University of California nor the names of its
  contributors may be used to endorse or promote products derived from this
  software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
"""


'''내리막길'''
import sys
from collections import deque
input = sys.stdin.readline
sys.setrecursionlimit(100000)

dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

dp = []
visited = []

# sx, sy 위치에서 n-1, m-1 갈 수 있는 경로의 수 를 리턴 중
def dfs(graph, sx, sy):
    # 갈수 있어! sx, sy 위치 dp에 1 더해!
    if sx == n - 1 and sy == m - 1:
        return 1

    # 이미 방문해봤나봐 sx, sy 위치 dp값을 그냥 리턴해. 이미 끝까지 갈 수 있는지 확인해 봤을 거야
    if visited[sy][sx]:
        return dp[sy][sx]

    visited[sy][sx] = True
    dp[sy][sx] = 0
    for i in range(4):
        nx = sx + dx[i]
        ny = sy + dy[i]
        if 0 <= nx < n and 0 <= ny < m and graph[ny][nx] < graph[sy][sx]:
            # 각 위치로 부터 dfs를 다시 시작해서 도착지까지 갈 수 있는 경로를 구해 오기
            dp[sy][sx] += dfs(graph, nx, ny)

    return dp[sy][sx]

m, n = map(int, input().split())
graph = []
dp = [[0 for col in range(n)] for row in range(m)]
visited = [[False for col in range(n)] for row in range(m)]
for i in range(m):
    graph.append(list(map(int, input().split())))

print(dfs(graph, 0, 0))
for i in dp:
    print(i)

for i in graph:
    print(i)


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from collections import defaultdict

from aif360.datasets import StandardDataset
from aif360.metrics import BinaryLabelDatasetMetric
from aif360.metrics import ClassificationMetric
from aif360.explainers import MetricTextExplainer

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix,accuracy_score,recall_score,roc_auc_score,roc_curve

# Bias mitigation techniques
from aif360.algorithms.preprocessing import Reweighing
from aif360.algorithms.preprocessing import DisparateImpactRemover
from aif360.algorithms.inprocessing import PrejudiceRemover

from .utils import get_categorical_cols

class ClassificationStudy:
    def __init__(self,data,target,favorable_classes,protected_attribute_names,privileged_classes,split = 0.7,**kwargs):

        self.dataset = StandardDataset(
            data,
            label_name = target,
            favorable_classes = favorable_classes,
            protected_attribute_names=protected_attribute_names,
            privileged_classes=privileged_classes,
            categorical_features=get_categorical_cols(data,[*protected_attribute_names,target]),
            **kwargs
        )

    def compute_bias_metrics(self,dataset = None):

        if dataset is None:
            dataset = self.dataset

        cols = ['disparate_impact','statistical_parity_difference', ]
        obj_fairness = [[0,1]]

        fair_metrics = pd.DataFrame(data=obj_fairness, index=['objective'], columns=cols)

        for attr in dataset.protected_attribute_names:
            idx = dataset.protected_attribute_names.index(attr)
            privileged_groups =  [{attr:dataset.privileged_protected_attributes[idx][0]}]
            unprivileged_groups = [{attr:dataset.unprivileged_protected_attributes[idx][0]}]

            metric_pred = BinaryLabelDatasetMetric(
                dataset,
                unprivileged_groups=unprivileged_groups,
                privileged_groups=privileged_groups
            )

            row = pd.DataFrame([[
                metric_pred.disparate_impact(),
                metric_pred.mean_difference(),
                ]],
            columns  = cols,
            index = [attr]
            )
            fair_metrics = fair_metrics.append(row)

        fair_metrics = fair_metrics.replace([-np.inf, np.inf], 2)

        return fair_metrics

    def train_test_split(self,split = 0.7):
        return self.dataset.split([split],shuffle = True)

    def fit(self,dataset = None,method = "lr",model = None,**kwargs):

        assert method in ["lr","rf"]

        if dataset is None:
            dataset = self.dataset

        if model is None:
            if method == "lr":

                self.model = make_pipeline(
                    StandardScaler(),
                    LogisticRegression(solver = kwargs.get("solver","liblinear"),**kwargs)
                )

                fit_params = {'logisticregression__sample_weight': dataset.instance_weights}

            elif method == "rf":

                self.model = make_pipeline(
                    StandardScaler(),
                    RandomForestClassifier(
                        n_estimators = kwargs.get("n_estimators",100),
                        **kwargs
                    )
                )

                fit_params = {'randomforestclassifier__sample_weight': dataset.instance_weights}

            X = dataset.features
            y = dataset.labels.ravel()

            self.model.fit(X,y,**fit_params)
            return self.model

    def evaluate_performances(self,test,plot_roc_curve = True):

        pred = self.model.predict(test.features)
        probas = self.model.predict_proba(test.features)[:,1]
        true = test.labels.ravel()

        metrics = {}

        metrics["confusion_matrix"] = confusion_matrix(true,pred)
        metrics["accuracy"] = accuracy_score(true,pred)
        metrics["recall"] = recall_score(true,pred)
        metrics["roc_auc"] = roc_auc_score(true,pred)

        if plot_roc_curve:

            fpr,tpr,_ = roc_curve(true,probas)

            plt.figure(figsize = (5,5))
            lw = 2
            plt.plot(fpr, tpr, color='darkorange',
                    lw=lw, label='ROC curve (area = %0.2f)' % metrics["roc_auc"])
            plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
            plt.xlim([0.0, 1.0])
            plt.ylim([0.0, 1.05])
            plt.xlabel('False Positive Rate')
            plt.ylabel('True Positive Rate')
            plt.title('Receiver operating characteristic example')
            plt.legend(loc="lower right")
            plt.show()

        return metrics

    def _make_groups(self,dataset = None):

        if dataset is None:
            dataset = self.dataset

        privileged_groups = {}
        unprivileged_groups = {}

        for feature in self.dataset.protected_attribute_names:
            idx = self.dataset.protected_attribute_names.index(feature)

            privileged_groups[feature] = self.dataset.privileged_protected_attributes[idx][0]
            unprivileged_groups[feature] = self.dataset.unprivileged_protected_attributes[idx][0]

        return [privileged_groups],[unprivileged_groups]

    def evaluate_bias(self,dataset = None,model = None):

        thresh_arr = np.linspace(0.01, 0.8, 100)

        if model is None:
            model = self.model

        if dataset is None:
            dataset = self.dataset

        privileged_groups,unprivileged_groups = self._make_groups(dataset)

        try:
            # sklearn classifier
            y_val_pred_prob = model.predict_proba(dataset.features)#[:,1]
            pos_ind = np.where(model.classes_ == dataset.favorable_label)[0][0]
        except AttributeError:
            # aif360 inprocessing algorithm
            y_val_pred_prob = model.predict(dataset).scores
            pos_ind = 0

        metric_arrs = defaultdict(list)
        for thresh in thresh_arr:
            y_val_pred = (y_val_pred_prob[:, pos_ind] > thresh).astype(np.float64)

            dataset_pred = dataset.copy()
            dataset_pred.labels = y_val_pred
            metric = ClassificationMetric(
                    dataset, dataset_pred,
                    unprivileged_groups=unprivileged_groups,
                    privileged_groups=privileged_groups)

            metric_arrs['balanced_accuracy'].append((metric.true_positive_rate()+metric.true_negative_rate()) / 2)
            metric_arrs['avg_odds_diff'].append(metric.average_odds_difference())
            metric_arrs['disparate_impact'].append(metric.disparate_impact())
            metric_arrs['stat_par_diff'].append(metric.statistical_parity_difference())
            metric_arrs['eq_opp_diff'].append(metric.equal_opportunity_difference())
            metric_arrs['theil_ind'].append(metric.theil_index())
            metric_arrs['true_positive_rate'].append(metric.true_negative_rate())
            metric_arrs['true_negative_rate'].append(metric.true_negative_rate())
            metric_arrs['recall'].append(metric.recall())
            metric_arrs['precision'].append(metric.precision())
            metric_arrs['f1_score'].append((2*metric.precision()*metric.recall()) / (metric.precision()+metric.recall()))

        disp_imp = np.array(metric_arrs["disparate_impact"])
        disp_imp_err = 1 - np.minimum(disp_imp, 1/disp_imp)
        metric_arrs["balanced_disparate_impact"] = disp_imp_err
        metric_arrs["thresholds"] = thresh_arr

        return metric_arrs

    def plot_bias_metrics(self,metrics,y_right = "balanced_disparate_impact",y_left = "balanced_accuracy",mitigated_metrics = None,labels = None):

        if not isinstance(metrics,list): metrics = [metrics]

        fig, ax1 = plt.subplots(figsize=(10,7))

        reds = ["red","salmon","lightcoral"]
        blues = ["blue","royalblue","cornflowerblue"]

        for i,metrics_set in enumerate(metrics):

            if len(metrics) == 1:
                label = ""
            else:
                if labels is None:
                    label = str(i)
                else:
                    label = labels[i]

            x = metrics_set["thresholds"]

            y_left_values = metrics_set[y_left]
            y_right_values = metrics_set[y_right]

            ax1.plot(x, y_left_values,c = blues[i],label = f"{y_left} {label}".strip())
            ax1.set_xlabel("Classification Threshold", fontsize=16, fontweight='bold')
            ax1.set_ylabel(y_left, color='b', fontsize=16, fontweight='bold')
            ax1.xaxis.set_tick_params(labelsize=14)
            ax1.yaxis.set_tick_params(labelsize=14)
            ax1.set_ylim(0.5, 0.8)

            ax1.legend(loc = "upper left")

            ax2 = ax1.twinx()
            ax2.plot(x, y_right_values, color = reds[i],label = f"{y_right} {label}".strip())
            ax2.set_ylabel(y_right, color='r', fontsize=16, fontweight='bold')
            if 'disparate' in y_right:
                ax2.set_ylim(0., 0.7)
            else:
                ax2.set_ylim(-0.25, 0.1)

            best_ind = np.argmax(y_left_values)

            if len(metrics) == 1:
                ax2.axvline(np.array(x)[best_ind], color='k', linestyle=':')

            ax2.yaxis.set_tick_params(labelsize=14)
            ax2.grid(True)
            ax2.legend(loc = "upper right")

    def pre_mitigate_reweighing(self,dataset):
        privileged_groups,unprivileged_groups = self._make_groups(dataset)
        rw = Reweighing(
            unprivileged_groups=unprivileged_groups,
            privileged_groups=privileged_groups
        )

        new_dataset = rw.fit_transform(dataset)
        return new_dataset

    def pre_mitigate_disparate_impact_remover(self,dataset):

        disp_remover = DisparateImpactRemover(repair_level=1.0)
        new_dataset = disp_remover.fit_transform(dataset)
        return new_dataset

    def in_mitigate_prejudice_remover(self,dataset,eta=25.0):

        #Training Prejudice Remover model

        sensitive_attr = self.dataset.protected_attribute_names

        model = PrejudiceRemover(sensitive_attr=sensitive_attr, eta=25.0)
        scaler = StandardScaler()

        new_dataset = dataset.copy()
        new_dataset.features = scaler.fit_transform(dataset.features)

        model.fit(new_dataset)

        return model


import os

hoehe = 3
breite = 3
spielfeld = [zahl + 1 for zahl in range(hoehe * breite)]

def zeige(spielfeld):
  for z in range(3):
    zeile = [str(feld) for feld in spielfeld[z * 3:z * 3 + 3]]
    print("|".join(zeile))

def sieg(spielfeld):
  for l in range(3):
    if len(set(spielfeld[l * 3:l * 3 + 3])) == 1:
      return True
    if len(set(spielfeld[l:l + 7:3])) == 1:
      return True
    if spielfeld[0] == spielfeld[4] and spielfeld[4] == spielfeld[8]:
      return True
    if spielfeld[2] == spielfeld[4] and spielfeld[4] == spielfeld[6]:
      return True
  return False

def unentschieden(spielfeld):
  return all(feld in ["X", "O"] for feld in spielfeld)

def spielzug(spielfeld):
  feld_ok = False
  while not feld_ok:
    feld = int(input("Feld eingeben: "))
    if feld >= 1 and feld <= 9 and spielfeld[feld - 1] not in ["X", "O"]:
      feld_ok = True
      spielfeld[feld - 1] = "X" if spieler == 1 else "O"
    else:
      print("Feld ungueltig!")

zu_ende = False
spieler = 1

while not zu_ende:
  os.system('clear')
  print("==== Tic Tac Toe ====")

  zeige(spielfeld)
  print(f"Spieler {spieler} ist dran.")
  spielzug(spielfeld)
  if sieg(spielfeld):
    print(f"Spieler {spieler} hat gewonnen:")
    zu_ende = True
  elif unentschieden(spielfeld):
    print("Unentschieden:")
    zu_ende = True
  else:
    if spieler == 1:
      spieler = 2
    elif spieler == 2:
      spieler = 1

zeige(spielfeld)


import re

refs = [
'abc_cmp_campaign1_xyz',
'abc_def_cmp_campaign2',
'cmp_campaign3-xyz',
'abcd-xyz-cmp-campaign4-',
'abccmpcampaign5-xyz',
]

results = []

for ref in refs:
    res = re.findall(r'.*cmp[_-]?([a-y0-9]+)', ref)
    results.extend(res)
print(results)


import os
from argparse import ArgumentParser

import pandas as pd
from tqdm import tqdm
import numpy as np

from medcat.cat import CAT
from medcat.utils.vocab import Vocab
from medcat.cdb import CDB

vocab = Vocab()
vocab.load_dict(os.environ["MEDCAT_VOCAB_FILE"])
print("Loaded Vocab")

# Load the cdb model you downloaded
cdb = CDB()
cdb.load_dict(os.environ["MEDCAT_CDB_FILE"])
print("Loaded CDB")

# create cat
cat = CAT(cdb=cdb, vocab=vocab)
cat.spacy_cat.TUI_FILTER = ['T047', 'T048', 'T184']

tqdm.pandas()

def get_entities(text) :
    doc = cat.get_entities(text)
    relevant_entities = []
    for ent in doc :
        if "icd10" in ent["info"] :
            ent_string = text[ent["start"]:ent['end']]
            if ent_string.lower() in ["ms", "mr", "mrs"] :
                continue
            cui = ent["cui"]
            icd_codes = tuple(sorted([x["chapter"] for x in ent["info"]["icd10"]]))
            if "R69" in icd_codes:
                continue
            relevant_entities.append((ent_string, cui, icd_codes))

    return list(set(relevant_entities))

def run(input_file, output_file, distributed: bool, args):
    notes_df = pd.read_csv(input_file).reset_index(drop=True)
    if distributed :
        notes_df = np.array_split(notes_df, args.n_jobs)[args.job_num]

    print(f"Loaded Data from CSV -- {len(notes_df)} -- {min(notes_df.index)} -- {max(notes_df.index)}")

    notes_df["CONDITIONS"] = notes_df["TEXT"].progress_apply(get_entities)

    notes_df = notes_df[["SUBJECT_ID", "CONDITIONS"]].sort_values(by="SUBJECT_ID")
    notes_df = notes_df.groupby("SUBJECT_ID")["CONDITIONS"].agg(lambda x : list(set([y for l in x for y in l]))).reset_index()

    if args.distributed :
        output_file = output_file + f".{args.n_jobs}.{args.job_num}"

    os.makedirs(os.path.dirname(output_file), exist_ok=True)
    notes_df.to_json(output_file, orient="records", lines=True)

parser = ArgumentParser()
parser.add_argument("--input-file", required=True)
parser.add_argument("--output-file", required=True)
parser.add_argument("--distributed", action="store_true")
parser.add_argument("--n-jobs", type=int)
parser.add_argument("--job-num", type=int)

if __name__ == "__main__":
    '''
    Usage:
        - python subject_id_to_name.py --input-file SUBJECT_ID_to_NOTES_original.csv --output-file SUBJECT_ID_to_Stanza.csv

    Output Format:
        SUBJECT_ID,Stanza_Code
        249,Code 1
        249,Code 2
        249,Code 3
        250,Code 1
        250,Code 2
    '''

    args = parser.parse_args()
    if args.distributed :
        assert "n_jobs" in args and "job_num" in args

    run(args.input_file, args.output_file, args.distributed, args)


from Village import Village
import mc_dictionary
from mcpi.minecraft import Minecraft

mc = Minecraft.create()

pos = mc.player.getTilePos()

mc.player.setPos(pos.x + 500, 100, pos.z + 500)

if __name__ == '__main__':
    mc = Minecraft.create()
    pos = mc.player.getTilePos()
    mc.player.setPos(pos.x + 1000, 100, pos.z + 1000)
    user_input = input('Would you like to generate your vilalge here? [y/n]: ')
    while user_input != 'y':
        pos = mc.player.getTilePos()
        mc.player.setPos(pos.x + 1000, 100, pos.z + 1000)
        user_input = input('Would you like to generate your vilalge here? [y/n]: ')
        break
    else:
        mc = Minecraft.create()
        village = Village(mc)
        village.foundation_generator(mc)
        village.road_generator(mc, 'row')
        village.road_generator(mc, 'column')
        village.spawn_houses(mc)


import re

finditer = re.compile(BR'''[^\012]+''').finditer
sub1 = re.compile(BR'''(?:\134\042|\134\134|\134\170[0-9a-f][0-9a-f])''').sub
sub2 = re.compile(BR'''[\134\042]''').sub

def main(raw_puzzle_input: bytes):
	puzzle_input = tuple(
		match[0]
		for match in finditer(raw_puzzle_input)
	)

	p1 = 0
	p2 = 0

	for line in puzzle_input:
		p1 += len(line) - len(sub1(b'\000', line)) + 2
		p2 += len(sub2(b'\000\000', line)) - len(line) + 2

	return p1, p2


import base64

base64_csp_prefixes = [
    'play.filters.headers.contentSecurityPolicy.base64',
]

csp_prefixes = [
    'play.filters.headers.contentSecurityPolicy.base64',
    'play.filters.headers.contentSecurityPolicy',
    'play.filters.headers.contentSecurity',
    'filters.headers.security.contentSecurityPolicy',
    'filters.headers.security.contentSecurity',
    # todo, better tests for this
    'filters.headers.contentSecurityPolicy',
    'filters.headers.contentSecurity',
    'headers.contentSecurityPolicy',

    # todo better tests for this
    'contentSecurityPolicy',
    'contentSecurity'
    ]

def extract_csp_part_from_java_like_entry(entry: str):
    if entry.startswith('-J') or entry.startswith('-j'):
        entry = entry[2:]

    sep = ''

    if entry.startswith('-d'):
        sep = '-d'
    elif entry.startswith('-D'):
        sep = '-D'
    else:
        # not sophisticated to handle it yet, mark for bad data
        return None

    sanitised_entry = None

    # do some clean up now
    entry = entry.rstrip(',').rstrip('"')

    parts = entry.split(sep)

    found = False

    for part in parts:
        if not found:
            part = part.strip()
            for prefix in csp_prefixes:
                if not found:
                    if part.startswith(prefix):
                        csp_parts = part.split('=')
                        sanitised_entry = csp_parts[1].strip("\'")
                        found == True
                else:
                    break
        else:
            break
    if is_base64_like(sanitised_entry):
        return f'base64: {sanitised_entry}'
    return sanitised_entry

def decode_base64_entry(entry: str):
    try:
        bytes = base64.b64decode(entry)
        return bytes.decode('utf-8')

    except Exception as e:
        return None

def is_base64_like(entry: str):
    return len(entry) > 30 and entry.find(' ') == -1

def extract_full_csp(entry: str):

    # handle -D flags more flexibly, the csp is not always the first in the line
    if '-D' in entry:
        index = entry.find('-D')
        entry = entry[index:]
    java_like_prefixes = ['-J' ,'-d' ,'-j', '-D']
    for j_prefix in java_like_prefixes:
        if entry.startswith(j_prefix):
            return extract_csp_part_from_java_like_entry(entry)

    entry = entry.strip().lstrip('#').lstrip('/').lstrip().strip('"')

    # for base64 in base64_csp_prefixes:
    #     if entry.startswith(base64):
    #         return 'base64'

    start_index = 0

    for prefix in csp_prefixes:
        if entry.startswith(prefix):
            start_index = len(prefix)
            break

    if start_index == 0:
        return None

    csp = entry[start_index:]
    csp = csp.strip().lstrip(':').lstrip().lstrip('=').lstrip().rstrip(',').strip('"')

    # could still be a base64 encoded string.
    # NAIVE check: check if it is longer than longest directive and contains no spaces
    if is_base64_like(csp):
        return f'base64: {csp}'

    return csp


from lib.helpers import *
from  lib.models import Category, Page

def write_category_to_mongo(category, parent_pageid):
    category['title'] = category['title'].replace('Category:','')
    if Category.objects(pageid=category['pageid']).count() == 0:
        this_category           = Category(pageid=category['pageid'],title=category['title'])
        this_category.save()

    this_category   = Category.objects(pageid=category['pageid']).first()

    if parent_pageid is not None:
        parent_category             = Category.objects(pageid=parent_pageid).first()
        this_category.parent_pageid = parent_pageid
        this_category.parent_title  = parent_category.title
        this_category.save()

    return this_category


# 1. **Anagram Check**: Write a Python function that checks whether two given words are anagrams.
#     - *Input*: "cinema", "iceman"
#     - *Output*: "True"
def anagramfun(str1, str2):
    dict1 = {}
    dict2 = {}

    for char in str1:
        dict1[char] = dict1.get(char, 0) + 1

    for char in str2:
        dict2[char] = dict2.get(char, 0) + 1

    return dict1==dict2
   #  if dict1 == dict2:
   #      return True
   #  else:
   #      return False

# Test the function
str1 = "cieman"
str2 = "iceman"
print(anagramfun(str1, str2))

# 2. **Bubble Sort**: Implement the bubble sort algorithm in Python.
#     - *Input*: [64, 34, 25, 12, 22, 11, 90]
#     - *Output*: "[11, 12, 22, 25, 34, 64, 90]"

def BubbleSort(Bublelist,n):
   for i in range(n-1):
      flag=0
      for j in range(0,n-i-1):
         if Bublelist[j]>Bublelist[j+1]:
               Bublelist[j],Bublelist[j+1]=Bublelist[j+1],Bublelist[j]
               flag=1
      if flag==0:
         break

   return Bublelist

print(BubbleSort([64, 34, 25, 12, 22, 11, 90],len([64, 34, 25, 12, 22, 11, 90])))

# 3. **Longest Common Prefix**: Given a list of strings, find the longest common prefix.
#     - *Input*: ["flower","flow","flight"]
#     - *Output*: "fl"

def longest_common_prefix(strs):
    if not strs:
        return ""  # If the list is empty, there is no common prefix.

    prefix = strs[0]  # Initialize the prefix with the first string.

    for s in strs[1:]:
        i = 0
        while i < len(prefix) and i < len(s) and prefix[i] == s[i]:
            i += 1
        prefix = prefix[:i]  # Update the prefix with the common part.

        if not prefix:
            break  # If the prefix becomes empty, no common prefix.

    return prefix

input_strings = ["flower", "flow", "flight"]
output = longest_common_prefix(input_strings)
print("Output:", output)

# 4. **String Permutations**: Write a Python function to calculate all permutations of a given string.
#     - *Input*: "abc"
#     - *Output*: "['abc', 'acb', 'bac', 'bca', 'cab', 'cba']"

from itertools import permutations

str1="abc"
li=[]
for perm in permutations(str1):
   li.append("".join(perm))

print(li)

# 5. **Implement Queue using Stack**: Use Python's stack data structure to implement a queue.
#     - *Input*: enqueue(1), enqueue(2), dequeue(), enqueue(3), dequeue(), dequeue()
#     - *Output*: "1, None, 3, None, None"

#  6. **Missing Number**: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.
#     - *Input*: [3, 0, 1]
#     - *Output*: "2"
# 7. **Climbing Stairs**: You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
#     - *Input*: 3
#     - *Output*: "3"
# 8. **Invert Binary Tree**: Invert a binary tree (mirroring it).
#     - *Input*: A binary tree
#     - *Output*: Inverted binary tree
# 9. **Power of Two**: Given an integer, write a function to determine if it is a power of two.
#     - *Input*: 16
#     - *Output*: "True"
# 10. **Contains Duplicate**: Given an array of integers, find if the array contains any duplicates.
#     - *Input*: [1, 2, 3, 1]
#     - *Output*: "True"
# 11. **Binary Search**: Write a function that implements binary search on a sorted array.
#     - *Input*: [1, 2, 3, 4, 5, 6], target = 4
#     - *Output*: "3"
# 12. **Depth First Search (DFS)**: Implement DFS for a graph in Python.
#     - *Input*: A graph
#     - *Output*: Vertices visited in DFS order
# 13. **Breadth First Search (BFS)**: Implement BFS for a graph in Python.
#     - *Input*: A graph
#     - *Output*: Vertices visited in BFS order
# 14. **Quick Sort**: Implement quick sort in Python.
#     - *Input*: [10, 7, 8, 9, 1, 5]
#     - *Output*: "[1, 5, 7, 8, 9, 10]"
# 15. **Single Number**: Given a non-empty array of integers, every element appears twice except for one. Find that single one.
#     - *Input*: [4,1,2,1,2]
#     - *Output*: "4"
# 16. **Palindrome Linked List**: Given a singly linked list, determine if it is a palindrome.
#     - *Input*: [1,2,2,1]
#     - *Output*: "True"
# 17. **Implement Trie (Prefix Tree)**: Implement a trie with insert, search, and startsWith methods.
#     - *Input*: insert("apple"), search("apple"), startsWith("app")
#     - *Output*: "True, True"
# 18. **Maximum Subarray**: Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
#     - *Input*: [-2, 1, -3, 4, -1, 2, 1, -5, 4]
#     - *Output*: "6"
# 19. **Implement Stack using Linked List**: Use Python's linked list data structure to implement a stack.
#     - *Input*: push(1), push(2), pop(), push(3), pop(), pop()
#     - *Output*: "1, None, 3, None, None"
# 20. **Basic Django Web App**: Create a basic web application using Django that has two routes, one that displays "Hello, World!" and one that displays "Goodbye, World!".
#     - *Input*: Visit "/", Visit "/goodbye"
#     - *Output*: "Hello, World!", "Goodbye, World!"