'''
Made by NEELANGSHU ROY
Student of B.Tech in Computer Science and Engineering at NIT Allahabad
Batch of 2021-25
'''
import sys
import random
import pygame
from pygame.locals import *

BACKGROUND = 'Game sprites/game background.png'
BASE = 'Game sprites/game_base.png'
PIPE = 'Game sprites/game_pillar.jpg'
SCREEN = pygame.display.set_mode((960,686))
BIRD = 'Game sprites/flappy_bird.png'
GAME_SPRITES,GAME_SOUNDS={},{}
FPS=30
def welcome():
    GAME_SOUNDS['welcomeMusic'].play()
    kk=GAME_SPRITES['play']
    mm=GAME_SPRITES['instruct']
    nn=GAME_SPRITES['exit']
    inst=GAME_SPRITES['instructions']
    bb=GAME_SPRITES['back']
    exi=GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k,n=0,0
    while True:
        SCREEN.blit(GAME_SPRITES['background'],(0,0))
        SCREEN.blit(GAME_SPRITES['gamename'],(272,15))
        SCREEN.blit(GAME_SPRITES['myname'],(225,114))

        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        SCREEN.blit(GAME_SPRITES['bird'],(80,300))

        if k==0 and n==0:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
        elif k==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        for event in pygame.event.get():
            change=0
            if event.type==QUIT:
                    pygame.quit()
                    sys.exit()
                    return False
            x,y=pygame.mouse.get_pos()
            clic=pygame.mouse.get_pressed()
            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 205<=y<=268) and k==0 and n==0):
                GAME_SOUNDS['click'].play()
                return True
            elif (332<=x<=628 and 205<=y<=268 and k==0 and n==0):
                kk=GAME_SPRITES['play_click']
            elif k==0 and n==0:
                kk=GAME_SPRITES['play']

            if event.type==MOUSEBUTTONDOWN and event.button==1 and (484<=x<=780 and 535<=y<=598) and k==1 and n==0:
                GAME_SOUNDS['click'].play()
                k=0
            elif (484<=x<=780 and 535<=y<=598) and k==1:
                bb=GAME_SPRITES['back_click']
            elif k==1:
                bb=GAME_SPRITES['back']

            if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 283<=y<=346) and k==0 and n==0:
                GAME_SOUNDS['click'].play()
                k=1
            elif (332<=x<=628 and 283<=y<=346 and k==0 and n==0):
                mm=GAME_SPRITES['instruct_click']
            elif k==0 and n==0:
                mm=GAME_SPRITES['instruct']

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and n==1 and k==0):
                n=0
                GAME_SOUNDS['click'].play()
                pygame.quit()
                sys.exit()
                return False
            elif (332<=x<=628 and 325<=y<=388) and n==1 and k==0:
                yes=GAME_SPRITES['yes_click']
            elif n==1 and k==0:
                yes=GAME_SPRITES['yes']

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 408<=y<=471) and n==1 and k==0):
                GAME_SOUNDS['click'].play()
                change=1
                n=0
            elif (332<=x<=628 and 408<=y<=471) and n==1 and k==0:
                no=GAME_SPRITES['no_click']
            elif n==1 and k==0:
                no=GAME_SPRITES['no']

            if change==1:
                continue

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=626 and 361<=y<=424) and k==0 and n==0):
                GAME_SOUNDS['click'].play()
                n=1
            elif (332<=x<=626 and 361<=y<=424 and k==0 and n==0):
                nn=GAME_SPRITES['exit_click']
            elif k==0 and n==0:
                nn=GAME_SPRITES['exit']

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def gameover():
    GAME_SOUNDS['die'].play()
    new=0
    nn=''
    with open('hs.txt') as f:
        nn=f.read()
    if nn[len(nn)-1]==' ':
        new=1
        nn=nn[:len(nn)-1]
        with open('hs.txt','w') as f:
            f.write(nn)
    ss=[int(x) for x in list(nn)]

    try_ag = GAME_SPRITES['retry']
    exi = GAME_SPRITES['exit']
    exit_p = GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k=0

    while True:
        SCREEN.blit(GAME_SPRITES['gameover'],(0,0))
        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        if k==0:
            SCREEN.blit(try_ag,(154,440))
            SCREEN.blit(exi,(510,440))
            width=435
            for item in ss:
                SCREEN.blit(GAME_SPRITES['digits'][item],(width,330))
                width+=45
            if new==1:
                SCREEN.blit(GAME_SPRITES['new'],(width+90,300))
        elif k==1:
            SCREEN.blit(exit_p,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
                return False
            x,y=pygame.mouse.get_pos()
            clic=pygame.mouse.get_pressed()

            if clic[0] and (332<=x<=628 and 325<=y<=388) and k==1:
                k=0
                GAME_SOUNDS['click'].play()
                pygame.quit()
                sys.exit()
                return 0
            elif (332<=x<=628 and 325<=y<=388) and k==1:
                yes=GAME_SPRITES['yes_click']
            elif k==1:
                yes=GAME_SPRITES['yes']

            if clic[0] and (332<=x<=629 and 408<=y<=471) and k==1:
                GAME_SOUNDS['click'].play()
                k=0
            elif (332<=x<=629 and 408<=y<=471) and k==1:
                no=GAME_SPRITES['no_click']
            elif k==1:
                no=GAME_SPRITES['no']

            if clic[0] and (154<=x<=450 and 440<=y<=503) and k==0:
                GAME_SOUNDS['click'].play()
                return True
            elif (154<=x<=450 and 440<=y<=503) and k==0:
                try_ag=GAME_SPRITES['retry_click']
            elif k==0:
                try_ag=GAME_SPRITES['retry']

            if clic[0] and (510<=x<=806 and 440<=y<=503) and k==0:
                k=1
                GAME_SOUNDS['click'].play()
            elif (510<=x<=806 and 440<=y<=503) and k==0:
                exi=GAME_SPRITES['exit_click']
            elif k==0:
                exi = GAME_SPRITES['exit']

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def roll():
    w=[960, 960+310, 960+620, 960+930]
    t=[
        random.randint(250,400),
        random.randint(250,400),
        random.randint(250,400),
        random.randint(250,400)
    ]
    # pattern of pipes will remain the same as values of t[0], t[1],
    # t[2] and t[3] remain fixed outside the loop

    t_coin=[
        random.randint(0,1),
        random.randint(0,1),
        random.randint(0,1),
        random.randint(0,1)
    ]

    pipeVel = [4,5,7,9,11,13,16]
    sp=[0, 26, 50]
    sc=[0, 10, 20, 30, 40, 50, 75]

    p=300
    score = 0

    playerPosX=80

    PAUSE=0

    kk=GAME_SPRITES['resume']
    mm=GAME_SPRITES['restart']
    nn=GAME_SPRITES['instruct']
    pp=GAME_SPRITES['exit']
    inst=GAME_SPRITES['instructions']
    bb=GAME_SPRITES['back']
    rest=GAME_SPRITES['restartpanel']
    exi=GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k1,k2,n=0,0,0

    while True:
        s=[int(x) for x in list(str(score))]
        s.reverse()
        width=GAME_SPRITES['digits'][4].get_width()

        SCREEN.blit(GAME_SPRITES['background'],(0,0))

        for i in range(4):
            SCREEN.blit(GAME_SPRITES['pipe'][0],(w[i],t[i]))
            i2=2
            for i1 in range(3):
                if 0==score:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[0]))
                    break
                if sc[i2-2]<score<=sc[i2]:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[i1]))
                    break
                elif sc[6]<score:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[2]))
                    break
                i2 += 2
            if t_coin[i]==1:
                k=2
                for j in range(3):
                    if score==0:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[0])/2 )) )
                    elif sc[k-2]<score<=sc[k]:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[j])/2 )) )
                        break
                    elif sc[6]<score:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[2])/2 )) )
                        break
                    k+=2

        # t[i] - 163 + int( (150-sp[j])/2) )

        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        SCREEN.blit(GAME_SPRITES['bird'],(playerPosX,p))

        for i in range(len(s)):
            SCREEN.blit(GAME_SPRITES['digits'][s[i]],(GAME_SPRITES['background'].get_width()-width,0))
            width+=GAME_SPRITES['digits'][4].get_width()
        SCREEN.blit(GAME_SPRITES['level'],(0,0))
        if 0<=score<=10:
            SCREEN.blit(GAME_SPRITES['digits'][1],(195,0))
        elif 10<score<=20:
            SCREEN.blit(GAME_SPRITES['digits'][2],(195,0))
        elif 20<score<=30:
            SCREEN.blit(GAME_SPRITES['digits'][3],(195,0))
        elif 30<score<=40:
            SCREEN.blit(GAME_SPRITES['digits'][4],(195,0))
        elif 40<score<=50:
            SCREEN.blit(GAME_SPRITES['digits'][5],(195,0))
        elif 50<score<=75:
            SCREEN.blit(GAME_SPRITES['digits'][6],(195,0))
        elif 75<score:
            SCREEN.blit(GAME_SPRITES['digits'][7],(195,0))

        if k1==0 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
            SCREEN.blit(pp,(332,439))
        elif k1==1 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(rest,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))
        elif k2==1 and k1==0 and n==0 and PAUSE==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1 and k1==0 and k2==0 and PAUSE==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        pygame.display.update()
        FPSCLOCK.tick(FPS)

        prev_score=score

        for i in range(4):
            a0=0

            k=2
            for j in range(3):
                if sc[k-2]<=score<sc[k]:
                    a0=t[i] - 13 - int( (150-sp[j])/2 )
                    break
                elif sc[6]<=score:
                    a0=t[i] - 13 - int( (150-sp[j])/2 )
                    break
                k+=2

            a1=a0+GAME_SPRITES['coin'].get_height()
            a2=p+GAME_SPRITES['bird'].get_height()
            a3=p+int(GAME_SPRITES['bird'].get_height()/2)
            a4=w[i]+50
            a5=playerPosX+GAME_SPRITES['bird'].get_width()
            a6=a4+GAME_SPRITES['coin'].get_width()+GAME_SPRITES['bird'].get_width()
            if (a4<=a5<a6 and (a0<=p<=a1 or a0<=a2<=a1 or a0<=a3<=a1) and t_coin[i]==1):
                score+=1
                GAME_SOUNDS['point'].play()
                t_coin[i]=0

        if prev_score<=10 and score>10:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=20 and score>20:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=30 and score>30:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=40 and score>40:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=50 and score>50:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=75 and score>75:
            GAME_SOUNDS['level_up'].play()

        for i in range(4):
            go=0
            b1=playerPosX+GAME_SPRITES['bird'].get_width()
            b2=p+6
            b3=w[i]+GAME_SPRITES['pipe'][0].get_width()
            b4=p+GAME_SPRITES['bird'].get_height()
            if ((b1-12<=w[i]<=b1 and b2<=t[i]-150)or(playerPosX<=w[i]<b1-12 and p<=t[i]-150)or(playerPosX<w[i]<=b1 and b4>t[i])):
                go=1
            elif (w[i]<b1<=b3 and (p<=t[i]-150 or b4>t[i]) ):
                go=1
            elif ( (playerPosX<b3<=playerPosX+6 and b4-13>=t[i])or(playerPosX<b3<=playerPosX+14 and p+12<=t[i]-150)or(playerPosX+14<b3<=b1 and p<=t[i]-150)or(playerPosX+6<b3<=b1 and b4>t[i]) ):
                go=1
            if go==1:
                numb=0
                with open('hs.txt') as f:
                    numb=int(f.read())
                if score>numb:
                    with open('hs.txt','w') as f:
                        f.write(str(score)+' ')
                return 1
            '''if ( 80<=w[i]<=80+GAME_SPRITES['bird'].get_width() or w[i]<=(80+GAME_SPRITES['bird'].get_width())<=(w[i]+GAME_SPRITES['pipe'][0].get_width()) or 80<=(w[i]+GAME_SPRITES['pipe'][0].get_width())<=(80+GAME_SPRITES['bird'].get_width()) ) and (p+GAME_SPRITES['bird'].get_height())>=t[i]:
                return True
            elif ( 80<=w[i]<=80+GAME_SPRITES['bird'].get_width() or w[i]<=(80+GAME_SPRITES['bird'].get_width())<=(w[i]+GAME_SPRITES['pipe'][0].get_width()) or 80<=(w[i]+GAME_SPRITES['pipe'][0].get_width())<=(80+GAME_SPRITES['bird'].get_width()) ) and (t[i]-500+GAME_SPRITES['pipe'][0].get_height())>=p:
                return True '''

        keys=pygame.key.get_pressed() # a list storing keys pressed in 1 iteration
        if ((keys[K_UP] or keys[K_w]) and p>=0) and PAUSE==0:     # This syntax is correct, although there are no
            p-=3                      # loops involved, but if UP key is pressed 5 times
        elif ((keys[K_DOWN] or keys[K_s]) and p<=545-GAME_SPRITES['bird'].get_height()) and PAUSE==0:
            p+=3                      # in 1 iteration, then this if condition is executed
        elif ((keys[K_LEFT] or keys[K_a]) and playerPosX>=0) and PAUSE==0:
            playerPosX-=3             # 5 times, how I don't know !
        elif ((keys[K_RIGHT] or keys[K_d]) and playerPosX+GAME_SPRITES['bird'].get_width()<=960) and PAUSE==0:
            playerPosX+=3

        # for key in keys:
        #     if key==K_UP:
        #         p-=3              This syntax is wrong, though it seems
        #     elif key==K_DOWN:     correct, but it is not
        #         p+=3

        for i in range(4):
            if w[i]>-130 and score<=10 and PAUSE==0:
                w[i]-=pipeVel[0]
            elif w[i]>-130 and 10<score<=20 and PAUSE==0:
                w[i]-=pipeVel[1]
            elif w[i]>-130 and 20<score<=30 and PAUSE==0:
                w[i]-=pipeVel[2]
            elif w[i]>-130 and 30<score<=40 and PAUSE==0:
                w[i]-=pipeVel[3]
            elif w[i]>-130 and 40<score<=50 and PAUSE==0:
                w[i]-=pipeVel[4]
            elif w[i]>-130 and 50<score<=75 and PAUSE==0:
                w[i]-=pipeVel[5]
            elif w[i]>-130 and 75<score and PAUSE==0:
                w[i]-=pipeVel[6]
            elif 1<=i<=3 and PAUSE==0:
                w[i]=w[i-1]+GAME_SPRITES['pipe'][0].get_width()+180
                t[i]=random.randint(250,400)
                t_coin[i]=random.randint(0,1)
            elif i==0 and PAUSE==0:
                w[0]=w[3]+GAME_SPRITES['pipe'][0].get_width()+180
                t[0]=random.randint(250,400)
                t_coin[0]=random.randint(0,1)
        # now this will bring some volatility to the pipe pattern

        '''if k1==0 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
        elif k1==1 and PAUSE==1:
            SCREEN.blit(rest,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))
        elif k2==1 and PAUSE==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1 and PAUSE==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))'''

        for event in pygame.event.get():

            change = 0

            if event.type==QUIT:
                pygame.quit()
                sys.exit()
                return 0
            elif event.type==KEYDOWN and event.key==K_ESCAPE:
                PAUSE=1
                change=1
            x,y=pygame.mouse.get_pos()
            # clic=pygame.mouse.get_pressed()

            if (n==1 or k1==1 or k2==1) and PAUSE==1:
                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and k1==1 and PAUSE==1:
                    k1=0
                    GAME_SOUNDS['click'].play()
                    return 2
                elif (332<=x<=628 and 325<=y<=388) and k1==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes_click']
                elif k1==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=629 and 408<=y<=471) and k1==1 and PAUSE==1:
                    k1=0
                    change=1
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=629 and 408<=y<=471) and k1==1 and PAUSE==1:
                    no=GAME_SPRITES['no_click']
                elif k1==1 and PAUSE==1:
                    no=GAME_SPRITES['no']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (484<=x<=780 and 535<=y<=598) and k2==1 and PAUSE==1:
                    k2=0
                    # change=1
                    GAME_SOUNDS['click'].play()
                elif (484<=x<=780 and 535<=y<=598) and k2==1 and PAUSE==1:
                    bb=GAME_SPRITES['back_click']
                elif k2==1 and PAUSE==1:
                    bb=GAME_SPRITES['back']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and n==1 and PAUSE==1:
                    n=0
                    GAME_SOUNDS['click'].play()
                    pygame.quit()
                    sys.exit()
                    return 0
                elif (332<=x<=628 and 325<=y<=388) and n==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes_click']
                elif n==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=629 and 408<=y<=471) and n==1 and PAUSE==1:
                    n=0
                    change=1
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=629 and 408<=y<=471) and n==1 and PAUSE==1:
                    no=GAME_SPRITES['no_click']
                elif n==1 and PAUSE==1:
                    no=GAME_SPRITES['no'] ##

            if change==1:
                continue

            if k1==0 and k2==0 and n==0 and PAUSE==1:
                if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 205<=y<=268) and k1==0 and k2==0 and n==0) and PAUSE==1:
                    '''or (event.type==KEYDOWN and event.key==K_ESCAPE)'''
                    '''or (event.type==KEYDOWN and event.key==K_ESCAPE and k1==0 and k2==0 and n==0)'''
                    PAUSE=0
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=628 and 205<=y<=268) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    kk=GAME_SPRITES['resume_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    kk=GAME_SPRITES['resume']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 283<=y<=346) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    k1,k2,n=1,0,0
                elif (332<=x<=628 and 283<=y<=346) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    mm=GAME_SPRITES['restart_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    mm=GAME_SPRITES['restart']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 361<=y<=424) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    k2,k1,n=1,0,0
                elif (332<=x<=628 and 361<=y<=424) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    nn=GAME_SPRITES['instruct_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    nn=GAME_SPRITES['instruct']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 439<=y<=502) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    n,k1,k2=1,0,0
                elif (332<=x<=628 and 439<=y<=502) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    pp=GAME_SPRITES['exit_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    pp=GAME_SPRITES['exit'] ##

if __name__=='__main__':
    pygame.init()
    FPSCLOCK=pygame.time.Clock()
    pygame.display.set_caption('FLAPPY BIRD by Neelangshu Roy')
    pygame.display.set_icon(pygame.image.load('Game sprites/flappybird_windowicon.png'))
    GAME_SPRITES['background']=pygame.image.load(BACKGROUND).convert()
    GAME_SPRITES['base']=pygame.image.load(BASE).convert_alpha()
    GAME_SPRITES['pipe']=(
        pygame.image.load(PIPE).convert_alpha(),
        pygame.transform.rotate(pygame.image.load(PIPE).convert_alpha(),180)
    )
    GAME_SPRITES['bird']=pygame.image.load(BIRD).convert_alpha()
    GAME_SPRITES['myname']=pygame.image.load('Game sprites/my_name.png').convert_alpha()
    GAME_SPRITES['gamename']=pygame.image.load('Game sprites/game_name.png').convert_alpha()
    GAME_SPRITES['gameover']=pygame.image.load('Game sprites/game_over.png').convert_alpha()
    GAME_SPRITES['coin']=pygame.image.load('Game sprites/coin.png').convert_alpha()
    GAME_SPRITES['level']=pygame.image.load('Game sprites/level.png').convert_alpha()

    GAME_SPRITES['play']=pygame.image.load('Game sprites/play.png').convert_alpha()
    GAME_SPRITES['play_click']=pygame.image.load('Game sprites/play_clicked.png').convert_alpha()
    GAME_SPRITES['exit']=pygame.image.load('Game sprites/exit.png').convert_alpha()
    GAME_SPRITES['exit_click']=pygame.image.load('Game sprites/exit_clicked.png').convert_alpha()
    GAME_SPRITES['resume']=pygame.image.load('Game sprites/resume.png').convert_alpha()
    GAME_SPRITES['resume_click']=pygame.image.load('Game sprites/resume_clicked.png').convert_alpha()
    GAME_SPRITES['restart']=pygame.image.load('Game sprites/restart.png').convert_alpha()
    GAME_SPRITES['restart_click']=pygame.image.load('Game sprites/restart_clicked.png').convert_alpha()
    GAME_SPRITES['instruct']=pygame.image.load('Game sprites/instructions.png').convert_alpha()
    GAME_SPRITES['instruct_click']=pygame.image.load('Game sprites/instructions_clicked.png').convert_alpha()
    GAME_SPRITES['instructions']=pygame.image.load('Game sprites/instruction.png').convert_alpha()
    GAME_SPRITES['back']=pygame.image.load('Game sprites/back.png').convert_alpha()
    GAME_SPRITES['back_click']=pygame.image.load('Game sprites/back_clicked.png').convert_alpha()
    GAME_SPRITES['exitpanel']=pygame.image.load('Game sprites/exit_panel.png').convert_alpha()
    GAME_SPRITES['restartpanel']=pygame.image.load('Game sprites/restart_panel.png').convert_alpha()
    GAME_SPRITES['yes']=pygame.image.load('Game sprites/yes.png').convert_alpha()
    GAME_SPRITES['yes_click']=pygame.image.load('Game sprites/yes_clicked.png').convert_alpha()
    GAME_SPRITES['no']=pygame.image.load('Game sprites/no.png').convert_alpha()
    GAME_SPRITES['no_click']=pygame.image.load('Game sprites/no_clicked.png').convert_alpha()
    GAME_SPRITES['new']=pygame.image.load('Game sprites/new.png').convert_alpha()
    GAME_SPRITES['retry']=pygame.image.load('Game sprites/retry.png').convert_alpha()
    GAME_SPRITES['retry_click']=pygame.image.load('Game sprites/retry_clicked.png').convert_alpha()

    GAME_SPRITES['digits']=(
        pygame.image.load('Game sprites/0_number.png').convert_alpha(),
        pygame.image.load('Game sprites/1_number.png').convert_alpha(),
        pygame.image.load('Game sprites/2_number.png').convert_alpha(),
        pygame.image.load('Game sprites/3_number.png').convert_alpha(),
        pygame.image.load('Game sprites/4_number.png').convert_alpha(),
        pygame.image.load('Game sprites/5_number.png').convert_alpha(),
        pygame.image.load('Game sprites/6_number.png').convert_alpha(),
        pygame.image.load('Game sprites/7_number.png').convert_alpha(),
        pygame.image.load('Game sprites/8_number.png').convert_alpha(),
        pygame.image.load('Game sprites/9_number.png').convert_alpha(),
    )
    GAME_SOUNDS['die']=pygame.mixer.Sound('Game sounds/die.wav')
    GAME_SOUNDS['hit']=pygame.mixer.Sound('Game sounds/hit.wav')
    GAME_SOUNDS['point']=pygame.mixer.Sound('Game sounds/point.wav')
    GAME_SOUNDS['wing']=pygame.mixer.Sound('Game sounds/wing.wav')
    GAME_SOUNDS['welcomeMusic']=pygame.mixer.Sound('Game sounds/game_openingSound.mp3')
    GAME_SOUNDS['click']=pygame.mixer.Sound('Game sounds/click.wav')
    GAME_SOUNDS['level_up']=pygame.mixer.Sound('Game sounds/level_complete.wav')
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['welcomeMusic'],0.80)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['click'],0.20)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['point'],0.30)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['level_up'],8.0)

    bool = welcome()
    while bool:
        check=0
        check = roll()
        if check==0:
            bool=False
            break
        elif check==1:
            bool=True
        elif check==2:
            continue
        bool = gameover()
        if bool==False:
            break


import numpy as np
import torch

class CustomCutout:
    """Custom-based cutout transform."""

    def __init__(self, length: int) -> None:
        """Initialize the custom-based cutout transform.

        Args:
            length: Length of the cutout.

        """

        self.length = length

    def __call__(self, img: torch.Tensor) -> torch.Tensor:
        h, w = img.size(1), img.size(2)
        mask = np.ones((h, w), np.float32)

        y = np.random.randint(h)
        x = np.random.randint(w)

        y1 = np.clip(y - self.length // 2, 0, h)
        y2 = np.clip(y + self.length // 2, 0, h)
        x1 = np.clip(x - self.length // 2, 0, w)
        x2 = np.clip(x + self.length // 2, 0, w)

        mask[y1:y2, x1:x2] = 0.0
        mask = torch.from_numpy(mask)
        mask = mask.expand_as(img)

        img *= mask

        return img


#The program implements a Genetic Algorithm to find 92 solutions to the 8-queens problem.
#The program consists of chromosomes, a fitness function, crossover and mutation operators.
#The chromosome structure is a list of 8 integers, each integer representing the column of the queen.
#The fitness function is the number of pairs of queens that are attacking each other. the goal is to find a chromosome with a fitness score of 0.
#the fitness function also uses a heuristic to reduce the number of times the fitness function is called.
#Crossover only occurs so that there are no repeated numbers in the chromosome (i.e. no two queens are in the same row).
#Mutation only occurs if fitness score is better than the previous one.
#Mutation only occurs so that there are no repeated numbers in the chromosome (i.e. no two queens are in the same row).
#the program will print the number of solutions found, the solutions themselves, and the time it took to find them.
#the program will also print the board of all 92 solutions.

import random
import time

#function to generate a random chromosome
def generate_chromosome():
    chromosome = []
    for i in range(8):
        chromosome.append(random.randint(0,7))
    return chromosome

#function to calculate the fitness score of a chromosome
def fitness(chromosome):
    fitness = 0
    for i in range(8):
        for j in range(i+1,8):
            if chromosome[i] == chromosome[j]:
                fitness += 1
            if abs(chromosome[i] - chromosome[j]) == abs(i-j):
                fitness += 1
    return fitness

#function to perform crossover
#Crossover only occurs so that there are no repeated numbers in the chromosome (i.e. no two queens are in the same row).
def crossover(chromosome1, chromosome2):
    crossover_point = random.randint(0,7)
    new_chromosome1 = chromosome1[:crossover_point] + chromosome2[crossover_point:]
    new_chromosome2 = chromosome2[:crossover_point] + chromosome1[crossover_point:]
    for i in range(8):
        if new_chromosome1.count(new_chromosome1[i]) > 1:
            new_chromosome1[i] = random.randint(0,7)
        if new_chromosome2.count(new_chromosome2[i]) > 1:
            new_chromosome2[i] = random.randint(0,7)
    return new_chromosome1, new_chromosome2

#function to perform mutation
#Mutation only occurs if fitness score is better than the previous one.
#Mutation only occurs so that there are no repeated numbers in the chromosome (i.e. no two queens are in the same row).
def mutation(chromosome):
    mutation_point = random.randint(0,7)
    new_chromosome = chromosome[:]
    new_chromosome[mutation_point] = random.randint(0,7)
    for i in range(8):
        if new_chromosome.count(new_chromosome[i]) > 1:
            new_chromosome[i] = random.randint(0,7)
    return new_chromosome

#function to print the board of a chromosome
def print_board(chromosome):
    print(chromosome)
    print()
    for i in range(8):
        for j in range(8):
            if chromosome[i] == j:
                print("Q", end = " ")
            else:
                print(".", end = " ")
        print()

#function to find the first solution found by the genetic algorithm
def find_first_solution():
    population = []
    for i in range(100):
        population.append(generate_chromosome())
    while True:
        new_population = []
        for i in range(100):
            chromosome1 = population[random.randint(0,99)]
            chromosome2 = population[random.randint(0,99)]
            new_chromosome1, new_chromosome2 = crossover(chromosome1, chromosome2)
            if fitness(new_chromosome1) < fitness(chromosome1):
                new_chromosome1 = mutation(new_chromosome1)
            if fitness(new_chromosome2) < fitness(chromosome2):
                new_chromosome2 = mutation(new_chromosome2)
            new_population.append(new_chromosome1)
            new_population.append(new_chromosome2)
        population = new_population
        for i in range(100):
            if fitness(population[i]) == 0:
                return population[i]

#function to find first 92 solutions found by the genetic algorithm
def find_all92_solutions():
    population = []
    for i in range(100):
        population.append(generate_chromosome())
    solutions = []
    while len(solutions) < 92:
        new_population = []
        for i in range(100):
            chromosome1 = population[random.randint(0,99)]
            chromosome2 = population[random.randint(0,99)]
            new_chromosome1, new_chromosome2 = crossover(chromosome1, chromosome2)
            if fitness(new_chromosome1) < fitness(chromosome1):
                new_chromosome1 = mutation(new_chromosome1)
            if fitness(new_chromosome2) < fitness(chromosome2):
                new_chromosome2 = mutation(new_chromosome2)
            new_population.append(new_chromosome1)
            new_population.append(new_chromosome2)
        population = new_population
        for i in range(100):
            if fitness(population[i]) == 0 and population[i] not in solutions:
                solutions.append(population[i])
    return solutions

#main function
def main():
    start_time = time.time()
    print("First solution:")
    first_solution = find_first_solution()
    print_board(first_solution)
    print("Time to find first solution: %s seconds" % (time.time() - start_time))
    print()
    start_time = time.time()
    print("All 92 solutions:")
    all_solutions = find_all92_solutions()
    for i in range(92):
        print_board(all_solutions[i])
        print()
    print("Time to find all solutions: %s seconds" % (time.time() - start_time))

main()


def square_function(x, l):
    if x <= l/3.0 or x >= l*2.0/3:
        y = 0
    else:
        y = 1
    return y

def projection_integrand(x,n,l):
    integrand = np.sqrt(2.0/l)*np.sin((n*np.pi*x)/l)*square_function(x,l)
    return integrand

l=10.0
x = np.arange(0,l,0.01)
c = np.zeros(10)

for n in range(0,10):
    c_n,_ = quad(projection_integrand, 0,l,args=(n,l))
    c[n] = c_n

3.Intro to QM - Wave Mechanics/Wave decomposition-Figuring out amplitudes.py


path = "./charging.csv"

def computeChargingTime(remaining_energy:float, tot_cap:float):
    charge = dict()
    with open(path, "r") as f:
        f.seek(0)
        for line in f.readlines()[1:]:
            a = line.split(',') # The elements of the list a are strings, corresponding to the comma-separated values in the line
            charge[float(a[0])] = int(a[1].replace("\n", ""))*60
    for i in charge.keys():
        if percentage<=i:
            max_index = i
            break
        if percentage>=i:
            min_index = i

    upper_time = charge[max_index]
    lower_time = charge[min_index]

    interpolated_time = lower_time*(max_index - percentage) + upper_time*(percentage - min_index)
    interpolated_time = interpolated_time/(max_index - min_index)
    time = charge[1] - upper_time
    time += interpolated_time
    return time

print(computeChargingTime(0.19))


"""
samna-backed module for interfacing with the Xylo-A2 AFE HW module
"""

import time
import warnings

import samna

from samna.afe2.configuration import AfeConfiguration as AFE2Configuration
from samna.afe2 import validate_configuration

from rockpool.nn.modules.module import Module
from rockpool.parameters import SimulationParameter
from rockpool import TSEvent
from rockpool.typehints import P_float

from .. import xylo_devkit_utils as hdkutils
from . import xa2_devkit_utils as hdu
from .xa2_devkit_utils import AFE2HDK

try:
    from tqdm.autonotebook import tqdm
except ModuleNotFoundError:

    def tqdm(wrapped, *args, **kwargs):
        return wrapped

from typing import Union, Dict, Any, Tuple, Optional

__all__ = ["AFESamna"]

class AFESamna(Module):
    """
    Interface to the Audio Front-End module on a Xylo-A2 HDK

    This module uses ``samna`` to interface to the AFE hardware on a Xylo-A2 HDK. It permits recording from the AFE hardware.

    To record from the module, use the :py:meth:`~.AFESamna.evolve` method. You need to pass this method an empty matrix, with the desired number of time-steps. The time-step ``dt`` is specified at module instantiation.

    A simulation of the module is available in :py:class:`.AFESim`.

    Warnings:
        This module does not currently support manual configuration. A fixed configuration is provided which uses auto-calibration, applied when the module is instantiated. This takes approximately 50 seconds to configure, leading to slow instantiation.

    See Also:
        For information about the Audio Front-End design, and examples of using :py:class:`.AFESim` for a simulation of the AFE, see :ref:`/devices/analog-frontend-example.ipynb`.

    Examples:
        Instantiate an AFE module, connected to a Xylo-A2 HDK

        >>> from rockpool.devices.xylo import AFESamna
        >>> import rockpool.devices.xylo.xylo_devkit_utils as xdu
        >>> afe_hdks = xdu.find_xylo_a2_boards()
        >>> afe = AFESamna(afe_hdks[0], dt = 10e-3)

        Use the module to record some audio events

        >>> import numpy as np
        >>> audio_events = afe(np.zeros([0, 100, 0]))
    """

    def __init__(
        self,
        device: AFE2HDK,
        config: Optional[AFE2Configuration] = None,
        dt: float = 1e-3,
        *args,
        **kwargs,
    ):
        """
        Instantiate an AFE module, via a samna backend

        Args:
            device (AFE2HDK): A connected AFE2 HDK device
            config (AFE2Configuration): A samna AFE2 configuration object
            dt (float): The desired spike time resolution in seconds
        """
        # - Check input arguments
        if device is None:
            raise ValueError(
                "`device` must be a valid, opened Xylo AFE V2 HDK self._device."
            )

        # - Get a default configuration
        if config is not None:
            warnings.warn(
                "Setting a manual configuration for the Xylo-AFE2 is not yet supported."
            )

        if config is None:
            config = samna.afe2.configuration.AfeConfiguration()

        # - Determine how many output channels we have
        Nout = len(config.analog_top.channels)

        # - Initialise the superclass
        super().__init__(shape=(0, Nout), spiking_input=True, spiking_output=True)

        # - Store the HDK device node
        self._device = device

        # - Store the dt parameter
        self.dt: P_float = SimulationParameter(dt)

        # - Configure the HDK
        device_io = self._device.get_io_module()
        device_io.write_config(0x52, 0b11)
        # time.sleep(0.5)

        # - Create write and read buffers
        self._xylo_core_read_buf = hdu.Xylo2ReadBuffer()
        graph = samna.graph.EventFilterGraph()
        graph.sequential(
            [self._device.get_xylo_model_source_node(), self._xylo_core_read_buf]
        )

        self._afe_read_buf = hdu.AFE2ReadBuffer()
        graph = samna.graph.EventFilterGraph()
        graph.sequential([self._device.get_afe_model_source_node(), self._afe_read_buf])

        self._afe_write_buf = hdu.AFE2WriteBuffer()
        graph = samna.graph.EventFilterGraph()
        graph.sequential([self._afe_write_buf, self._device.get_afe_model_sink_node()])

        # - Check that we have a correct device version
        self._chip_version, self._chip_revision = hdu.read_afe2_chip_version(
            self._afe_read_buf, self._afe_write_buf
        )
        if self._chip_version != 1 or self._chip_revision != 0:
            raise ValueError(
                f"AFE version is {(self._chip_version, self._chip_revision)}; expected (1, 0)."
            )

        # - Configure the HDK
        device_io.write_config(0x1002, 1)
        # time.sleep(0.5)
        device_io.write_config(0x0022, 1)
        # time.sleep(0.2)

        device_io.write_config(0x54, 1)
        device_io.write_config(0x0003, 1)
        device_io.write_config(0x0004, 0x03)
        device_io.write_config(0x02, 0x30)
        # time.sleep(0.5)
        # xylo_handler = device_io.get_xylo_handler()

        # - Set up known good configuration
        print("Configuring AFE...")
        hdu.apply_afe2_default_config(self._device)
        print("Configured AFE")

    def evolve(self, input_data, record: bool = False) -> Tuple[Any, Any, Any]:
        """
        Use the AFE HW module to record live audio and return as encoded events

        Args:
            input_data (np.ndarray): An array ``[0, T, 0]``, specifying the number of time-steps to record.

        Returns:
            (np.ndarray, dict, dict) output_events, {}, {}
        """

        # - Handle auto batching
        input_data, _ = self._auto_batch(input_data)

        # - For how long should we record?
        duration = input_data.shape[1] * self.dt

        # - Record events
        timestamps, channels = hdu.read_afe2_events_blocking(
            self._device, self._afe_write_buf, self._afe_read_buf, duration
        )

        # - Convert to an event raster
        events_ts = TSEvent(
            timestamps,
            channels,
            t_start=0.0,
            t_stop=duration,
            num_channels=self.size_out,
        ).raster(self.dt, add_events=True)

        # - Return output, state, record dict
        return events_ts, self.state(), {}

    @property
    def _version(self) -> (int, int):
        """
        Return the version and revision numbers of the connected Xylo-AFE2 chip

        Returns:
            (int, int): version, revision
        """
        return (self._chip_version, self._chip_revision)


from django.contrib import admin

from .models import Mask

class MaskAdmin(admin.ModelAdmin):
    fieldsets = (
        ('Content', {
            'fields': ('title', 'subtitle', 'image'),
        }),
        ('Visibility', {
            'fields': ('effective', 'expiration'),
        }),
    )
    list_display = ('title', 'subtitle', 'image', 'effective', 'expiration')
    ordering = ('-effective', 'expiration')
    search_files = ('title', 'subtitle', 'image')
    view_on_site = False

admin.site.register(Mask, MaskAdmin)


import sqlite3,cgi
print("Content-Type:text/html\r\n\r\n")

conn=sqlite3.connect("mydatadb.db")
cur=conn.cursor()
form=cgi.FieldStorage()
emp_id=form.getvalue("emp_id")
emp_name=form.getvalue("emp_name")
department=form.getvalue("department")
print(emp_id,emp_name,department)
sql="insert into emplyee values('"+emp_id+"','"+emp_name+"','"+department+"')"
print(sql)
try:
        #cur.execute("create table emp(emp_id integer,emp_name text,department text)")
        rs=cur.execute(sql)
except Exception as e:
        print("Exception")
        print(e)
else:
        conn.commit()
        print("succesfully inserted")
conn.close()
cur.close()


import pandas as pd
import os

# 读取Excel文件
df = pd.read_excel('G:\\updated_data.xlsx')

# 获取列名列表
columns = df.columns.tolist()

# 遍历每一列
for column_name in ['大米', '小麦面粉', '杂粮', '薯类', '油炸面食', '猪肉', '牛羊肉', '禽肉', '内脏类', '水产类', '鲜奶', '奶粉', '酸奶', '蛋类', '豆腐', '豆腐丝等', '豆浆', '干豆', '新鲜蔬菜', '海草类', '咸菜', '泡菜', '酸菜', '糕点', '水果', '果汁饮料', '其他饮料']:
    # 获取列名
    column_freq_day = f'食用{column_name}的频率（次数/天）'
    column_freq_week = f'食用{column_name}的频率（次数/周）'
    column_freq_month = f'食用{column_name}的频率（次数/月）'
    column_avg = f'{column_name}平均每次食用量'
    column_eat = f'是否吃{column_name}'

    # 根据“是否吃{column_name}”的值进行处理
    for i in range(len(df)):
        if df[column_eat][i] == 2:
            # 如果不吃，则将“频率”和“平均每次食用量”设为0
            df[column_freq_month][i] = 0
            df[column_avg][i] = 0
        elif df[column_eat][i] == 1:
            # 如果吃，则根据“频率”的单位进行转换
            if pd.notna(df[column_freq_day][i]):
                df[column_freq_month][i] = df[column_freq_day][i] * 30
            elif pd.notna(df[column_freq_week][i]):
                df[column_freq_month][i] = df[column_freq_week][i] * 4
            # 删除“频率”的原始列
            df.drop([column_freq_day, column_freq_week], axis=1, inplace=True)

    # 删除列名
    df.drop(column_eat, axis=1, inplace=True)

# 将转换后的结果保存到G盘
if os.path.exists("G:\\"):
    df.to_excel('G:\\converted_data.xlsx', index=False)
    print("文件保存成功")
else:
    print("G盘不存在")


def bfs(s):
    # [1] q, v[], 필요 flag 생성
    q = []
    v = [0] * (V + 1)

    # [2] 단위작업
    q.append(s)
    v[s] = 1
    alst.append(s)

    while q:
        # [3] 데이터 한개 꺼냄
        c = q.pop(0)

        # [4] 4/8방향, 연결된 노드 등 반복처리
        for n in adj[c]:
            # 범위내, 미방문, 조건맞으면(길이면, 같은 값이면, 일정범위 이내면)
            if v[n] == 0:
                q.append(n)
                v[n] = 1  # 이전 v[c]+1 인 경우도 있음
                alst.append(n)

T = int(input())
for tc in range(1, T + 1):
    V, E = map(int, input().split())
    adj = [[] for _ in range(V + 1)]
    for _ in range(E):
        s, e = map(int, input().split())
        adj[s].append(e)
        adj[e].append(s)  # 양방향 연결!

    # 인접리스트=>번호순 조건: 반드시 정렬후 사용
    for lst in adj:
        lst.sort()

    alst = []
    bfs(1)
    print(f'#{tc}', *alst)


import random

def changeBlanks(guess,secretWord,blanks):
    index = -2
    while(index != -1):
        index = secretWord.find(guess)
        if(index != -1):
            temp = list(blanks)
            temp[index] = guess
            blanks = "".join(temp)
            temp = list(secretWord)
            temp[index] = '*'
            secretWord = "".join(temp)
    return secretWord, blanks

words = ['peanut', 'butter', 'jelly']
secretWord = random.choice(words)
print(secretWord)
incorrectGuessCounter = 0
win = False
blanks = '_' * len(secretWord)
print("This is game is basically hangman you have 8 incorrect guess to get all the letters in the word")
while(incorrectGuessCounter < 9 and win == False):
    print(blanks)
    guess = input("Guess a character\n")
    if(guess in secretWord):
        secretWord, blanks = changeBlanks(guess,secretWord,blanks)


from .. import db
from ..db_class.db import Notification, Case, Case_Org, Org, User, Task, Task_User
from sqlalchemy import desc
import datetime

def get_notif(nid):
    return Notification.query.get(nid)

def get_user_notif(user, unread_read):
    if unread_read == "true":
        return Notification.query.where(Notification.user_id==user.id, Notification.is_read==False).order_by(desc(Notification.creation_date)).all()
    else:
        return Notification.query.where(Notification.user_id==user.id, Notification.is_read==True).order_by(desc(Notification.creation_date)).all()

def read_notification_core(notif_id):
    notif = get_notif(notif_id)
    if notif:
        notif.is_read = not notif.is_read
        if notif.is_read:
            notif.read_date = datetime.datetime.now(tz=datetime.timezone.utc)
        else:
            notif.read_date = None
        db.session.commit()
        return True
    return False

def delete_notification_core(nid):
    notif = get_notif(nid)
    if notif:
        db.session.delete(notif)
        db.session.commit()
        return True
    return False

def create_notification_org(message, case_id, org_id, html_icon, current_user):
    org = Org.query.get(org_id)
    for user in org.users:
        if not user == current_user:
            notif = Notification(
                message=message,
                is_read=False,
                user_id=user.id,
                case_id=str(case_id),
                creation_date=datetime.datetime.now(tz=datetime.timezone.utc),
                html_icon=html_icon
            )
            db.session.add(notif)
            db.session.commit()

    return True

def create_notification_all_orgs(message, case_id, html_icon, current_user):
    case_org = Case_Org.query.where(case_id==case_id).all()
    for c_o in case_org:
        org = Org.query.get(c_o.org_id)
        for user in org.users:
            if not user == current_user:
                notif = Notification(
                    message=message,
                    is_read=False,
                    user_id=user.id,
                    case_id=str(case_id),
                    creation_date=datetime.datetime.now(tz=datetime.timezone.utc),
                    html_icon=html_icon
                )
                db.session.add(notif)
                db.session.commit()

    return True

def create_notification_user(message, case_id, user_id, html_icon):
    notif = Notification(
        message=message,
        is_read=False,
        user_id=str(user_id),
        case_id=str(case_id),
        creation_date=datetime.datetime.now(tz=datetime.timezone.utc),
        html_icon=html_icon
    )
    db.session.add(notif)
    db.session.commit()

    return notif

def case_task_deadline_notif(case_or_task, msg, html_icon, now, current_user, flag_task=False):
    if case_or_task.deadline:
        notif_deadline = None
        if case_or_task.notif_deadline_id:
            notif_deadline = get_notif(case_or_task.notif_deadline_id)

        case_deadline = datetime.datetime.strptime(case_or_task.deadline.strftime("%Y-%m-%d"), "%Y-%m-%d")
        loc = case_deadline - now

        if loc.days > 0:
            if loc.days <= 10:
                if notif_deadline:
                    if (case_deadline - notif_deadline.for_deadline).days > loc.days:
                        notif_deadline.message = f"{loc.days} {msg}"
                        notif_deadline.for_deadline = now
                        notif_deadline.is_read = False
                        db.session.commit()
                else:
                    if flag_task:
                        notif_deadline = create_notification_user(f"{loc.days} {msg}", case_or_task.case_id, current_user.id, html_icon)
                    else:
                        notif_deadline = create_notification_user(f"{loc.days} {msg}", case_or_task.id, current_user.id, html_icon)
                    notif_deadline.for_deadline = now
                    case_or_task.notif_deadline_id = notif_deadline.id
                    db.session.commit()

def create_notification_deadline(current_user):
    now = datetime.datetime.strptime(datetime.datetime.now(tz=datetime.timezone.utc).strftime("%Y-%m-%d"), "%Y-%m-%d")
    # now = datetime.datetime.strptime("2023-07-01", "%Y-%m-%d")

    cases = Case.query.join(Case_Org, Case_Org.org_id==current_user.org_id).all()
    for case in cases:
        msg = f"days remains for case '{case.id}-{case.title}'"
        case_task_deadline_notif(case, msg, "fa-solid fa-radiation", now, current_user)

    tasks = Task.query.join(Task_User, Task_User.user_id==current_user.id).all()
    for task in tasks:
        case = Case.query.get(task.case_id)
        msg = f"days remains for task '{task.title}' of case '{case.id}-{case.title}'"
        case_task_deadline_notif(task, msg, "fa-solid fa-skull-crossbones", now, current_user, True)

    return True

def mark_all_read(user):
    notif_list = get_user_notif(user, unread_read="true")

    for notif in notif_list:
        notif.is_read = True
        notif.read_date = datetime.datetime.now(tz=datetime.timezone.utc)
        db.session.commit()

    return True


from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.safestring import mark_safe

from .base import InteractiveElement

class Test(InteractiveElement):
    """
    Represents a user-made test
    """

    title = models.TextField(
        blank=False,
        default="",
        verbose_name="tittel",
        help_text="Tittel på brukertesten",
    )

    published = models.BooleanField(
        null=True,
        default=True,
        verbose_name="Publisert",
    )

    class Meta:
        verbose_name = "brukertest"
        verbose_name_plural = "brukertester"

    def get_absolute_url(self):
        return reverse("user_test", kwargs={"pk": self.id})

    def __str__(self):
        return str(self.title)

class TestQuestion(models.Model):
    text = models.TextField(blank=False, default="", verbose_name="spørsmål")

    test = models.ForeignKey(
        "Test", null=True, on_delete=models.CASCADE, related_name="questions"
    )

    def changeform_link(self):
        if self.id:
            changeform_url = reverse(
                "admin:interactive_testquestion_change", args=(self.id,)
            )
            liste = "
"
            for alt in self.alternatives.all():
                liste += "
" + str(alt.text) + " - "
                for result in alt.get_target_with_weights():
                    liste += str(result[0]) + "[" + str(result[1]) + "], "
                liste = liste[:-2]
            liste += "
"
            return mark_safe(
                'Endre alternativer' % changeform_url
                + liste
            )
        return (
            "Du må lagre (og fortsette å redigere) spørsmål én gang først. \n"
            "Kan også være smart å sette publisert=nei før du lagrer."
        )

    changeform_link.short_description = "Alternativer"  # omit column header

    class Meta:
        verbose_name = "testspørsmål"
        verbose_name_plural = "testspørsmål"

    def __str__(self):
        return str(self.text)

def validate_weight_syntax(code):
    try:
        split = code.split(",")
        [int(i) for i in split]
    except Exception:
        raise ValidationError("Kun helltal som vekter!")

class TestQuestionAlternative(models.Model):
    text = models.TextField(blank=False, verbose_name="svaralternativ")

    question = models.ForeignKey(
        "TestQuestion", null=True, on_delete=models.CASCADE, related_name="alternatives"
    )

    target = models.ManyToManyField(
        "TestResult",
        verbose_name="tilsvarende resultat (lagre én gang for å få korrekte resultater)",
        help_text="Velg resultatene dette alternativet svarer til.",
        blank=True,
    )

    weights = models.TextField(
        verbose_name="vektlegging av resultater",
        help_text=(
            "Bestem hvor mye hvert resultat vektlegges ved valg av dette alternativet. "
            "Format er 3,1,4 (altså heltall) det 3 er vekten til det øveste resultatet osv. "
            "Hvis blank får alle vekt 1, og hvis listen ikke er lang nok får resten vekt 1"
        ),
        blank=True,
        validators=[validate_weight_syntax],
    )

    def get_target_with_weights(self):
        split = self.weights.split(",")
        if split == [""]:
            ints = []
        else:
            ints = [int(i) for i in split]
        targets = self.target.all()
        my_list = list(zip(targets, ints))
        if len(ints) < len(targets):
            for i in range(len(ints), len(targets)):
                my_list.append((targets[i], 1))
        return my_list

    class Meta:
        verbose_name = "alternativ"
        verbose_name_plural = "alternativer"

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        for target in self.target.all():
            if target.test != self.question.test:
                self.target.remove(target)
        super().save(*args, **kwargs)

class TestResult(models.Model):
    title = models.CharField(max_length=100, blank=False)

    content = models.TextField(blank=False, verbose_name="beskrivelse")

    test = models.ForeignKey(
        "Test", null=True, on_delete=models.CASCADE, related_name="results"
    )

    def __str__(self):
        return str(self.title)

    class Meta:
        verbose_name = "testresultat"
        verbose_name_plural = "testresultater"


#!/usr/bin/env python3
import demoFunctions, csv, os

# read our configuration
config = demoFunctions.readConfig()

# login to the org
demoFunctions.authenticate(config)

# get a list of the fields to remove
with open('config/fields.csv','r') as csvFile:
    csvReader = csv.reader(csvFile)
    for row in csvReader:
        fieldApiName = row[0]
        fieldId = int(row[1])
        print('removing Custom field {fieldApiName} with id {fieldId}' \
                .format(fieldApiName = fieldApiName, fieldId = fieldId))

        demoFunctions.deleteCustomField(config, fieldApiName, fieldId)

os.remove('config/fields.csv')
print('Done removing fields, file config/fields.csv removed')


import urllib.request
req = urllib.request.Request('https://adventofcode.com/2018/day/1/input')
req.add_header('cookie', 'session=53616c7465645f5f3b11f98d4ad0d173b5924fafd79b0c5e9be05963d42e40e6c4d7f30f10a77eab04467ce7d4f99424')
response = urllib.request.urlopen(req).read().decode('utf-8')
results = []

total = 0
found = False
while not found:
    print(total)
    for value in response.split():
        total += int(value)
        if total in results:
            found = True
            print(total)
            break

        results.append(total)


import os
import re
import sys
import urllib.request

"""Logpuzzle exercise
Given an apache logfile, find the puzzle urls and download the images.

Here's what a puzzle url looks like:
10.254.254.28 - - [06/Aug/2007:00:13:48 -0700] "GET /~foo/puzzle-bar-aaab.jpg HTTP/1.0" 302 528 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"
"""

def read_urls(filename):
    """Returns a list of the puzzle urls from the given log file,
    extracting the hostname from the filename itself.
    Screens out duplicate urls and returns the urls sorted into
    increasing order."""
    urls = []

    file_urls = open(filename, 'r')
    line = file_urls.readline()
    while line:
        match = re.search(r'GET\s(\D{1}\w{3}\D\w{9}\D+[^.ico][jpg]+)\sHTTP', line)
        urls
        if match and match.group(1) not in urls:
            urls.append(match.group(1))

        line = file_urls.readline()

    return sorted(urls)

def download_images(img_urls, dest_dir='test'):
    """Given the urls already in the correct order, downloads
    each image into the given directory.
    Gives the images local filenames img0, img1, and so on./home/luciano
    Creates an index.html in the directorydownload_images
    with an img tag to show each local image file.
    Creates the directory if necessary.
    """
    if not os.path.isdir(dest_dir):
        os.system('mkdir ' + dest_dir )

    # for img in img_urls:
    #     urllib.request.urlretrieve(img_urls, dest_dir)

    with open(dest_dir +'/index.html', 'w') as f:
        f.write('\n\t')
        for img in img_urls:
            f.write("\n\t\t")
        f.write('\n\t\n')

def main():
    args = sys.argv[1:]

    if not args:
        print('usage: [--todir dir] logfile ')
        sys.exit(1)

    download_images(read_urls(args[0]))

if __name__ == '__main__':
    main()


# ---------- IMPORT ------------
import logging
import matplotlib
import matplotlib.pyplot as plt
import datetime
import json
import ijson
from datetime import timedelta, date
# ------------------------------

# ---------- INPUT -------------
path_source_userdata = "/home/lmoldon/data/users_reduced.json"

source_IDs = []

source_names = []
# ------------------------------

# ---------- OUTPUT ------------
# ------------------------------

# ---------- CONFIG ------------
# ------------------------------

# ---------- INITIAL -----------
logging.basicConfig(format='%(asctime)s [%(levelname)s] - %(message)s', datefmt='%d-%m-%y %H:%M:%S', level=logging.INFO)
datetimeFormat = "%Y-%m-%d"
plotdata = {}  # key = day in observedtime, value = value of selected mode
# ------------------------------

log_starttime = datetime.datetime.now()

def getUserIdFromLogin(login):
    for userID in userdata:
        if userdata[userID]["name"] == login:
            return userID
    return -1

logging.info("Loading data ...")
with open(path_source_userdata, "r") as fp:
    userdata = json.load(fp)
logging.info("Done.")

logging.info("Starting ...")

res = {}

if source_IDs != []:
    for entry in source_IDs:
        try:
            res[entry] = userdata[entry]["name"]
        except:
            pass

if source_names != []:
    for entry in source_names:
        temp = getUserIdFromLogin(entry)
        if temp != -1:
            res[temp] = entry

logging.info("Done:")
print(res)

log_endtime = datetime.datetime.now()
log_runtime = (log_endtime - log_starttime)
logging.info("Total runtime: " + str(log_runtime))


# coding=utf-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import ast
import argparse
from collections import OrderedDict
from functools import partial
from math import ceil

import numpy as np
import paddle.fluid as fluid
import paddlehub as hub
from paddlehub.module.module import moduleinfo, runnable, serving
from paddle.fluid.core import PaddleTensor, AnalysisConfig, create_paddle_predictor
from paddlehub.io.parser import txt_parser
from paddlehub.common.paddle_helper import add_vars_prefix

from faster_rcnn_resnet50_fpn_venus.processor import load_label_info, postprocess, base64_to_cv2
from faster_rcnn_resnet50_fpn_venus.data_feed import test_reader, padding_minibatch
from faster_rcnn_resnet50_fpn_venus.fpn import FPN
from faster_rcnn_resnet50_fpn_venus.resnet import ResNet
from faster_rcnn_resnet50_fpn_venus.rpn_head import AnchorGenerator, RPNTargetAssign, GenerateProposals, FPNRPNHead
from faster_rcnn_resnet50_fpn_venus.bbox_head import MultiClassNMS, BBoxHead, TwoFCHead
from faster_rcnn_resnet50_fpn_venus.bbox_assigner import BBoxAssigner
from faster_rcnn_resnet50_fpn_venus.roi_extractor import FPNRoIAlign

@moduleinfo(
    name="faster_rcnn_resnet50_fpn_venus",
    version="1.0.0",
    type="cv/object_detection",
    summary=
    "Baidu's Faster-RCNN model for object detection, whose backbone is ResNet50, processed with Feature Pyramid Networks",
    author="paddlepaddle",
    author_email="paddle-dev@baidu.com")
class FasterRCNNResNet50RPN(hub.Module):
    def _initialize(self):
        # default pretrained model, Faster-RCNN with backbone ResNet50, shape of input tensor is [3, 800, 1333]
        self.default_pretrained_model_path = os.path.join(self.directory, "faster_rcnn_resnet50_fpn_model")

    def context(self, num_classes=708, trainable=True, pretrained=True, phase='train'):
        """
        Distill the Head Features, so as to perform transfer learning.

        Args:
            trainable (bool): whether to set parameters trainable.
            pretrained (bool): whether to load default pretrained model.
            get_prediction (bool): whether to get prediction.
            phase (str): optional choices are 'train' and 'predict'.

        Returns:
             inputs (dict): the input variables.
             outputs (dict): the output variables.
             context_prog (Program): the program to execute transfer learning.
        """
        context_prog = fluid.Program()
        startup_program = fluid.Program()
        with fluid.program_guard(context_prog, startup_program):
            with fluid.unique_name.guard():
                image = fluid.layers.data(name='image', shape=[-1, 3, -1, -1], dtype='float32')
                # backbone
                backbone = ResNet(norm_type='affine_channel', depth=50, feature_maps=[2, 3, 4, 5], freeze_at=2)
                body_feats = backbone(image)
                # fpn
                fpn = FPN(max_level=6, min_level=2, num_chan=256, spatial_scale=[0.03125, 0.0625, 0.125, 0.25])
                var_prefix = '@HUB_{}@'.format(self.name)
                im_info = fluid.layers.data(name='im_info', shape=[3], dtype='float32', lod_level=0)
                im_shape = fluid.layers.data(name='im_shape', shape=[3], dtype='float32', lod_level=0)
                body_feat_names = list(body_feats.keys())
                body_feats, spatial_scale = fpn.get_output(body_feats)
                # rpn_head: RPNHead
                rpn_head = self.rpn_head()
                rois = rpn_head.get_proposals(body_feats, im_info, mode=phase)
                # train
                if phase == 'train':
                    gt_bbox = fluid.layers.data(name='gt_bbox', shape=[4], dtype='float32', lod_level=1)
                    is_crowd = fluid.layers.data(name='is_crowd', shape=[1], dtype='int32', lod_level=1)
                    gt_class = fluid.layers.data(name='gt_class', shape=[1], dtype='int32', lod_level=1)
                    rpn_loss = rpn_head.get_loss(im_info, gt_bbox, is_crowd)
                    # bbox_assigner: BBoxAssigner
                    bbox_assigner = self.bbox_assigner(num_classes)
                    outs = fluid.layers.generate_proposal_labels(
                        rpn_rois=rois,
                        gt_classes=gt_class,
                        is_crowd=is_crowd,
                        gt_boxes=gt_bbox,
                        im_info=im_info,
                        batch_size_per_im=bbox_assigner.batch_size_per_im,
                        fg_fraction=bbox_assigner.fg_fraction,
                        fg_thresh=bbox_assigner.fg_thresh,
                        bg_thresh_hi=bbox_assigner.bg_thresh_hi,
                        bg_thresh_lo=bbox_assigner.bg_thresh_lo,
                        bbox_reg_weights=bbox_assigner.bbox_reg_weights,
                        class_nums=bbox_assigner.class_nums,
                        use_random=bbox_assigner.use_random)
                    rois = outs[0]

                roi_extractor = self.roi_extractor()
                roi_feat = roi_extractor(head_inputs=body_feats, rois=rois, spatial_scale=spatial_scale)
                # head_feat
                bbox_head = self.bbox_head(num_classes)
                head_feat = bbox_head.head(roi_feat)
                if isinstance(head_feat, OrderedDict):
                    head_feat = list(head_feat.values())[0]
                if phase == 'train':
                    inputs = {
                        'image': var_prefix + image.name,
                        'im_info': var_prefix + im_info.name,
                        'im_shape': var_prefix + im_shape.name,
                        'gt_class': var_prefix + gt_class.name,
                        'gt_bbox': var_prefix + gt_bbox.name,
                        'is_crowd': var_prefix + is_crowd.name
                    }
                    outputs = {
                        'head_features': var_prefix + head_feat.name,
                        'rpn_cls_loss': var_prefix + rpn_loss['rpn_cls_loss'].name,
                        'rpn_reg_loss': var_prefix + rpn_loss['rpn_reg_loss'].name,
                        'generate_proposal_labels': [var_prefix + var.name for var in outs]
                    }
                elif phase == 'predict':
                    pred = bbox_head.get_prediction(roi_feat, rois, im_info, im_shape)
                    inputs = {
                        'image': var_prefix + image.name,
                        'im_info': var_prefix + im_info.name,
                        'im_shape': var_prefix + im_shape.name
                    }
                    outputs = {
                        'head_features': var_prefix + head_feat.name,
                        'rois': var_prefix + rois.name,
                        'bbox_out': var_prefix + pred.name
                    }
                add_vars_prefix(context_prog, var_prefix)
                add_vars_prefix(startup_program, var_prefix)

                global_vars = context_prog.global_block().vars
                inputs = {key: global_vars[value] for key, value in inputs.items()}
                outputs = {
                    key: global_vars[value] if not isinstance(value, list) else [global_vars[var] for var in value]
                    for key, value in outputs.items()
                }

                for param in context_prog.global_block().iter_parameters():
                    param.trainable = trainable

                place = fluid.CPUPlace()
                exe = fluid.Executor(place)
                exe.run(startup_program)
                if pretrained:

                    def _if_exist(var):
                        if num_classes != 81:
                            if 'bbox_pred' in var.name or 'cls_score' in var.name:
                                return False
                        return os.path.exists(os.path.join(self.default_pretrained_model_path, var.name))

                    fluid.io.load_vars(exe, self.default_pretrained_model_path, predicate=_if_exist)
                return inputs, outputs, context_prog

    def rpn_head(self):
        return FPNRPNHead(
            anchor_generator=AnchorGenerator(
                anchor_sizes=[32, 64, 128, 256, 512],
                aspect_ratios=[0.5, 1.0, 2.0],
                stride=[16.0, 16.0],
                variance=[1.0, 1.0, 1.0, 1.0]),
            rpn_target_assign=RPNTargetAssign(
                rpn_batch_size_per_im=256,
                rpn_fg_fraction=0.5,
                rpn_negative_overlap=0.3,
                rpn_positive_overlap=0.7,
                rpn_straddle_thresh=0.0),
            train_proposal=GenerateProposals(min_size=0.0, nms_thresh=0.7, post_nms_top_n=2000, pre_nms_top_n=2000),
            test_proposal=GenerateProposals(min_size=0.0, nms_thresh=0.7, post_nms_top_n=1000, pre_nms_top_n=1000),
            anchor_start_size=32,
            num_chan=256,
            min_level=2,
            max_level=6)

    def roi_extractor(self):
        return FPNRoIAlign(
            canconical_level=4, canonical_size=224, max_level=5, min_level=2, box_resolution=7, sampling_ratio=2)

    def bbox_head(self, num_classes):
        return BBoxHead(
            head=TwoFCHead(mlp_dim=1024),
            nms=MultiClassNMS(keep_top_k=100, nms_threshold=0.5, score_threshold=0.05),
            num_classes=num_classes)

    def bbox_assigner(self, num_classes):
        return BBoxAssigner(
            batch_size_per_im=512,
            bbox_reg_weights=[0.1, 0.1, 0.2, 0.2],
            bg_thresh_hi=0.5,
            bg_thresh_lo=0.0,
            fg_fraction=0.25,
            fg_thresh=0.5,
            class_nums=num_classes)


"""
Given an array A of N positive numbers. The task is to find the position where equilibrium first occurs in the array.
Equilibrium position in an array is a position such that the sum of elements below it is equal to the sum of elements after it.
"""
if __name__ == '__main__':
    T = int(input())
    for i in range(T):
        n = int(input())
        a = input().rstrip().split()
        a = [int(a[j]) for j in range(len(a))]
        if len(a) ==1:
            print(1)
        elif (len(a) == 2):
            print(-1)
        else:
            sumCheck = sum(a)
            re = -1
            sumStart = a[0]
            c = 1
            while(c < len(a)):
                if (sumCheck - a[c] - sumStart == sumStart):
                    re = c+1
                    break
                sumStart += a[c]
                c +=1

            print(re)


from import_functions.auxiliary_function_for_importing_data import *
import numpy as np
import mpu

from import_functions.import_prices import import_prices
from import_functions.import_yields import import_commune_yields, join_yields

"""
Uses common matching work on columns through years to match them.
"""

def aggregate_matching_column_loop(
    data, column_names, data_file_name, eq_target_column, target_columns
):
    """Returns a DataFrame containing only columns we could match with their official name.

    Args:
        data (pd.DataFrame): DataFrame of current inspected file.
        column_names (list of str): list of column names from the metadata DataFrame
        data_file_name (str): name of the file currently inspected
        eq_target_column (list of str): list of column names that match official column names
        target_columns (list of str): list of official column names

    Returns:
        temp (pd.DataFrame): DataFrame containing only columns we could match with their official name
    """
    perfect_match_indexes = [
        perfect_match_index(col, column_names)
        for col in eq_target_column
        if not col is None
    ]
    perfect_match_columns = [
        column_names[id] for id in perfect_match_indexes if not id is None
    ]
    temp = data[perfect_match_columns]
    temp.columns = [
        target_columns[i]
        for i in range(len(eq_target_column))
        if not eq_target_column[i] is None
        and not perfect_match_index(eq_target_column[i], column_names) is None
    ]
    temp["Path"] = data_file_name
    return temp

def aggregate_matching_column_moments_loop(
    data, column_names, data_file_name, eq_target_column, target_columns
):
    perfect_match_indexes = [
        perfect_match_index(col, column_names) for col in eq_target_column if col != ""
    ]
    temp = pd.DataFrame(
        data=[], columns=["variable", "Path", "Mean", "Min", "Q1", "Median" "Q3", "Max"]
    )
    for i in range(len(perfect_match_indexes)):
        id = perfect_match_indexes[i]
        if not id is None:
            col = column_names[id]
            if data[col].dtypes.kind in "fi":
                temp = temp.append(
                    pd.DataFrame(
                        {
                            "variable": [target_columns[i]],
                            "Path": [data_file_name],
                            "Mean": [np.mean(data[col])],
                            "Min": [np.min(data[col])],
                            "Q1": [np.quantile(data[col], 0.25, axis=0)],
                            "Median": [np.median(data[col])],
                            "Q3": [np.quantile(data[col], 0.75, axis=0)],
                            "Max": [np.max(data[col])],
                        }
                    )
                )
    return temp

def import_dataset(
    home_folder_path=None,
    mauritania_FSMS_data_zipfile="Mauritania FSMS data",
    columns_csv_path="columns.csv",
    path_to_population_image="Groupe 3 - Marchés Alimentaires/images/population images",
    path_to_wfp_food_prices_mauritania_csv="Groupe 3 - Marchés Alimentaires/prix/wfp_food_prices_mauritania.csv",
    historical_data_files_path="GeoWatch Labs Agricultural Maps/Historical Yields",
):
    if home_folder_path is None:
        home_folder_path = Path.home()
    #os.chdir(home_folder_path)
    unzip_data(mauritania_FSMS_data_zipfile)
    data_files_list = get_list_of_data_files(mauritania_FSMS_data_zipfile, ".sav")
    nb_valid_files = 0

    equivalent_columns_table = pd.read_csv(columns_csv_path,
                                           sep=";", header=0)

    if len(equivalent_columns_table.columns) == 1:
        equivalent_columns_table = pd.read_csv(columns_csv_path,
                                               sep=",", header=0)

    target_columns = [
        col for col in equivalent_columns_table.columns if str(col) != "nan"
    ]

    match = pd.DataFrame(data=[], columns=target_columns)
    match_moments = pd.DataFrame(
        data=[], columns=["variable", "Path", "Mean", "Min", "Q1", "Median" "Q3", "Max"]
    )

    for data_file_index in range(len(data_files_list)):
        print(round(data_file_index / len(data_files_list) * 100), " %")
        data_file_name = data_files_list[data_file_index]
        data, meta = get_data_with_filename(data_file_name)

        year_file = extract_year_from_filename(data_file_name)

        if year_file == '2012':

            if 'GPScoord' in data.columns:

                data['coord'] = data['GPScoord'].apply(clean_gps_coord)
                data[['latitude','longitude']] = pd.DataFrame(data['coord'].apply(extract_lat_lon).tolist(), index=data.index)
                meta.column_names += ['latitude','longitude']

        if not meta is None:
            nb_valid_files += 1

            column_names = [col for col in meta.column_names if not col is None]
            eq_target_column = [
                equivalent_columns_table.loc[data_file_index, col]
                for col in target_columns
            ]

            match = match.append(
                aggregate_matching_column_loop(
                    data,
                    column_names,
                    data_file_name,
                    eq_target_column,
                    target_columns,
                )
            )
            match_moments = match_moments.append(
                aggregate_matching_column_moments_loop(
                    data,
                    column_names,
                    data_file_name,
                    eq_target_column,
                    target_columns,
                )
            )
    match = match.reset_index(drop=True)
    match = fill_moughtaa_wilaya(match)

    match["year"] = match["Path"].apply(extract_year_from_filename)
    match["month"] = match["Path"].apply(extract_month_from_filename)

    test = match['moughataa']

    historical_data_files_list = get_list_of_data_files(
        historical_data_files_path, ".tif"
    )

    file_commune_yield = 'commune_to_yield_avg_by_year_by_crop.pickle'
    file_commune_dict = 'commune_dict.pickle'

    if os.path.exists(file_commune_yield) & os.path.exists(file_commune_dict):
        commune_to_yield_avg_by_year_by_crop = mpu.io.read(file_commune_yield)
        commune_dict = mpu.io.read(file_commune_dict)
    else:
        commune_to_yield_avg_by_year_by_crop, commune_dict = import_commune_yields(
        historical_data_files_list, path_to_population_image)

        mpu.io.write(file_commune_dict, commune_dict)

        mpu.io.write(file_commune_yield,
                 commune_to_yield_avg_by_year_by_crop)

    match = join_yields(match, commune_to_yield_avg_by_year_by_crop, commune_dict)

    clean_moughataa_column(match, commune_dict)

    match = import_prices(
        match,
        path_to_wfp_food_prices_mauritania_csv,
    )

    if not match.empty:
        match.reset_index()
        match.to_csv(
            "aggregated_match_for_FSMS_files_with_yields_with_price.csv",
            sep=",",
            index=False,
        )
        return match
    if not match_moments.empty:
        match_moments.reset_index()
        match_moments.to_csv(
            "aggregated_match_moments_for_FSMS_files.csv", sep=",", index=False
        )


from modules import module
from datetime import datetime, timedelta, timezone

class Youtube(module.Module):
    ''' adapted from recon-ng Twitter module
        written by Tim Tomes (@LaNMaSteR53) '''

    def __init__(self):
        # every module needs a way to identify it
        self.name = "Youtube"
        return

    # returns a list of video IDs that are within the specified area since the specified date
    def search(self, key, lat, lon, rad, since):
        pageToken = None
        point = str(lat) + ',' + str(lon)
        stamp = since.isoformat('T')
        videoIds = []
        url = 'https://www.googleapis.com/youtube/v3/search' #?locationRadius={}km&order=date&publishedAfter={}&part=snippet&location={}&type=video&maxResults=50&key={}'
        while True:
            payload = {'locationRadius': str(rad) + 'km',
                       'order': 'date',
                       'publishedAfter': stamp,
                       'part': 'snippet',
                       'location': point,
                       'type': 'video',
                       'maxResults': '50',
                       'pageToken': pageToken,
                       'key': key}
            try:
                resp = self.request(url, content=payload)
            except:
                self.error("Unable to connect to Youtube API.")
                return []
            jsonobj = resp.json()
            if not jsonobj:
                self.error(resp.text)
                return []
            for video in jsonobj['items']:
                videoIds.append(video['id']['videoId'])
            # we've now processed a whole page
            if not 'nextPageToken' in jsonobj: return videoIds # no next page, we're done
            pageToken = jsonobj['nextPageToken']

    def run(self, locname, lat, lon, rad, since):
        self.output('Collecting data from Youtube for {}...'.format(locname))
        startTime = datetime.now(timezone.utc).astimezone()

        pins = []
        count = 0

        apiKey = self.getKey('google_api')

        videoIds = self.search(apiKey, lat, lon, rad, since)

        self.output('YouTube module collecting data for ~{} total videos...'.format(len(videoIds)))

        if len(videoIds) == 0: return

        for videoId in videoIds:
            geoPayload = {'part': 'snippet, recordingDetails',
                          'id': videoId,
                          'key': apiKey
                         }
            resp = self.request('https://www.googleapis.com/youtube/v3/videos', content=geoPayload)
            geoInfo = resp.json()
            if not geoInfo:
                self.error(resp.text)
                return

            video = geoInfo['items'][0]
            if len(geoInfo['items']) != 1: self.error("Got more than one video for query. Huh?")

            if not 'latitude' in video['recordingDetails']['location']:
                continue # if location isn't there, we don't even want it

            source = 'YouTube'
            screen_name = video['snippet']['channelTitle']
            profile_name = video['snippet']['channelTitle']
            profile_url = 'https://www.youtube.com/channel/{}'.format(video['snippet']['channelId'])
            media_url = 'https://www.youtube.com/watch?v={}'.format(video['id'])
            thumb_url = video['snippet']['thumbnails']['default']['url']
            message = video['snippet']['title']
            latitude = video['recordingDetails']['location']['latitude']
            longitude = video['recordingDetails']['location']['longitude']
            time = datetime.strptime(video['snippet']['publishedAt'], '%Y-%m-%dT%H:%M:%S.%fZ')

            # also potentially useful: video description
            # video['snippet']['description']

            pins.append(self.createPin(source, screen_name, profile_name, profile_url, media_url, thumb_url, message, latitude, longitude, time))
            count += 1
            if len(pins) == 200:
                # every 200, do a db dump
                self.output('YouTube module processed {} videos so far...'.format(count))
                self.addPins(locname, pins)
                pins = []

        # now that they're all processed
        self.addPins(locname, pins) # dump any left
        self.output("YouTube module has processed {} videos...".format(count))
        self.registerPull(locname, self.name, startTime)
        timeDelta = datetime.now(timezone.utc).astimezone() - startTime
        self.output("YouTube pull took {} seconds.".format(timeDelta.total_seconds()))


import datetime
import json
import logging
import threading
import time

import os
import requests

from .util import FrozenDict

log = logging.getLogger(__name__)

class PeriodicalOperation:
    def __init__(self, interval, clock=time.time):
        self.clock = clock
        self.interval = interval
        self.lock = threading.Lock()
        self.last = self.clock()
        self.cache = PeriodicalOperation
        self.log = log.getChild(self.__class__.__name__)

    def __call__(self):
        if self.cache == PeriodicalOperation:
            self.log.debug('first run')
            self.lock.acquire(True)
            self.run()
        now = self.clock()
        if now >= self.last + self.interval:
            if self.lock.acquire(False):
                self.log.info('got lock')
                threading.Thread(target=self.run).start()
        return self.cache

class UrlFetcher(PeriodicalOperation):
    def __init__(self, url, interval, clock=time.time):
        super().__init__(interval, clock)
        self.url = url
        self.etag = ''

    def run(self):
        # noinspection PyBroadException
        try:
            self.log.debug("ETag: %r", self.etag)
            headers = {'If-None-Match': self.etag}
            res = requests.get(url=self.url, headers=headers, timeout=3.0)

            if res.status_code == 304:
                self.log.debug("use cached value")
                return self.cache
            elif res.ok:
                self.log.debug("unpack new value")
                self.etag = res.headers['ETag']
                self.cache = res.json(object_hook=FrozenDict)
                return self.cache
            else:
                res.raise_for_status()
        except:
            if log.isEnabledFor(logging.DEBUG):
                log.debug("Exception fetching %r", self.url, exc_info=True)
            else:
                log.info("Exception fetching %r", self.url)

            if self.cache is PeriodicalOperation:
                self.cache = {}
            return self.cache
        finally:
            self.last = self.clock()
            self.lock.release()

class Reporter(PeriodicalOperation):
    def __init__(self, client, url, interval, clock=time.time):
        super().__init__(interval, clock)
        self.cache = None
        self.client = client
        self.url = url

    @staticmethod
    def fmt_time(t):
        return datetime.datetime.fromtimestamp(t).strftime('%FT%TZ')

    def run(self):
        # noinspection PyBroadException
        try:
            now = self.clock()
            start, stop, self.last = self.last, now, now
            bucket = {
                'start': self.fmt_time(start),
                'stop': self.fmt_time(stop),
                'toggles': {
                    name: feature.report()
                    for name, feature in self.client.features.items()
                },
            }

            report = {
                "appName": self.client.app_name,
                "instanceId": self.client.instance_id,
                "bucket": bucket,
            }
            self.log.info('%r', report)
            res = requests.post(self.url, json=report)
            self.log.info('%r', res.status_code)
        except:
            pass
        finally:
            self.lock.release()

class FileFetcher:
    open_f = open
    stat_f = os.stat

    def __init__(self, path):
        self.cache = {}
        self.path = path
        self.last = 0

    def __call__(self):
        # noinspection PyBroadException
        try:
            st = self.stat_f(self.path)
            if st.st_mtime > self.last:
                with self.open_f(self.path) as fh:
                    self.cache = json.load(fh)
                self.last = st.st_mtime
        except:
            if log.isEnabledFor(logging.DEBUG):
                log.debug("Failed to read %r", self.path, exc_info=True)
            else:
                log.info("Failed to read %r")
        finally:
            return self.cache


import math
import torch
import torch.nn as nn

class EncodeModule(nn.Module):
    def __init__(self, dots, units, ratio_min, ratio_max):
        super().__init__()
        self.dots = dots
        self.units = units
        self.ratio_min = ratio_min
        self.ratio_max = ratio_max
        self.ratio_prior = _estimate_prior(ratio_min, ratio_max)
        self.weight = nn.Parameter(torch.empty(dots, units))

        self.reset_parameter()

    def reset_parameter(self):
        with torch.no_grad():
            return self.weight.normal_(0, 0.03)

    def forward(self, si: torch.Tensor, pr_last: torch.Tensor):
        """
        :param si: stimuli # (batch_size * dots)
        :param pr_last: last presentation # (batch_size * units)
        :return:
        """
        alpha = si @ self.weight + 1  # (batch_size * units)
        alpha = self.reciprocal_relu(alpha)
        pr = pr_last * alpha.detach()  # (batch_size * units)
        output = [alpha, pr]
        return output

    @staticmethod
    def reciprocal_relu(x: torch.Tensor):
        x_ = torch.masked_fill(x, x == 2, float('inf'))
        return (x < 1) * (1 / (2 - x_)) + (x >= 1) * x

class LateralModule(nn.Module):
    def __init__(self, units, ratio_min, ratio_max):
        super().__init__()
        self.units = units
        self.ratio_min = max(ratio_min, 0.01)
        self.ratio_max = ratio_max
        self.weight = nn.Parameter(torch.zeros(units, units))  # (units, units)
        self.bias = nn.Parameter(torch.ones(units) * _estimate_prior(ratio_min, ratio_max))
        self.register_buffer('eye_mask', torch.ones(units, units) - torch.eye(units, units))  # (units, units)

    def forward(self, pr: torch.Tensor):
        pulse = torch.bernoulli(pr.clamp(0, 1))  # (batch_size, units)
        output = pulse @ (self.weight * self.eye_mask) + self.bias
        output.data.clamp_(self.ratio_min, self.ratio_max)  # (batch_size, units)
        return output

class MartingaleModule(nn.Module):
    def __init__(self, units, ratio_min, ratio_max):
        super().__init__()
        self.pr_prior = _estimate_prior(ratio_min, ratio_max)
        self.pr_mean = nn.Parameter(torch.ones(units) * self.pr_prior)

    def forward(self):
        return self.pr_mean

class SquashModule(nn.Module):
    def __init__(self, ratio_min, ratio_max, squash_factor=(0.1, 0.5), squash_slope=1.0):
        super().__init__()
        self.ratio_min = ratio_min
        self.ratio_max = ratio_max
        self.ratio_prior = _estimate_prior(ratio_min, ratio_max)
        self.squash_factor = squash_factor
        self.squash_slope = squash_slope

    def forward(self, x):
        return self._squash(x, self.ratio_min, self.ratio_max, self.ratio_prior, self.squash_factor, self.squash_slope)

    @staticmethod
    def _squash(x, value_min: float, value_max: float, value_inflection: float, factor=(0.1, 0.5), slope=1.0):
        def half_squash(half_factor):
            def half_squash_factorized(x_):
                x_ = slope * x_
                fn = torch.tanh
                # fn = lambda val: val / (1 + val.abs())
                return (1 - half_factor) * (1 - torch.relu(1 - x_)) + half_factor * fn(x_)

            return half_squash_factorized

        def rst_op(func, scale, trans, reflect=False):
            def reflect_op(f):
                return lambda val: -f(-val)

            def scale_op(f):
                return lambda val: scale * f(val / scale)

            def trans_op(f):
                return lambda val: trans + f(val - trans)

            if reflect:
                return trans_op(scale_op(reflect_op(func)))
            else:
                return trans_op(scale_op(func))

        return (x >= value_inflection) * rst_op(half_squash(factor[1]), value_max - value_inflection, value_inflection)(
            x) + (x < value_inflection) * rst_op(half_squash(factor[0]), value_inflection - value_min, value_inflection,
                                                 reflect=True)(x)

def _estimate_prior(ratio_min, ratio_max):
    # the estimate of prior probability
    return 1 / (1 + math.pow(
        (math.pow(ratio_min, ratio_min) * math.pow(1 - ratio_min, 1 - ratio_min)) /
        (math.pow(ratio_max, ratio_max) * math.pow(1 - ratio_max, 1 - ratio_max)),
        1 / (ratio_max - ratio_min)))

if __name__ == '__main__':
    import matplotlib.pyplot as plt

    z = torch.linspace(0, 1, 100)
    y = SquashModule._squash(z, 0.0, 1, 0.5, 10)
    plt.plot(z.numpy(), y.numpy())
    plt.show()
    pass