#batman is the best
from collections import deque
import pygame, ezpztext
import time
import random
import threading
import traceback
import pygame
import os
import sys
from pygame import *
from pygame.locals import *

from Movement import Movement
from Hole import Hole
from Timer import Timer
import ParserThread
import util

pygame.init()

level = 0
numOfLevels = 10
rebelScore = 0

white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0, 255, 0)
yellow = (255, 255, 0)
grey = (96, 125, 139)
orange = (255, 87, 34)

# default colour for text editor font
txtfont_default = white
txtfont_focus = green

# Global settings
control_mode = 'TYPE' # 'KEYPRESS' or 'TYPE'
time_limit = 20 # Time limit that affects Time Bar and Duration countdown

# Use a timer
timer = Timer()

# Use the Movement class to keep track of movements
movement = Movement(1)

# Game state
game_state = 'idle'
parsing = False

#textbox
txtbx = ezpztext.Textbox(lines=14, default_color=txtfont_default,
            focus_color=txtfont_focus, maxlength=28, y=60, x=840)

for i in range(len(txtbx.txtbx)):
    txtbx.txtbx[i].prompt = "{:>2}: ".format(i + 1)

# Use ParserThread to create a separate thread for parsing user code
parser_thread = ParserThread.Thread()

map_width = 800
map_height = 600
status_bar = 40
display_width = map_width +400
display_height = map_height + status_bar

lead_x = 750
lead_y = 540
lead_direction = 'down'
blueprintCollected = False
blueprintExist = False

BlueprintThickness = 30
block_size = 10
FPS = 30
gameDisplay = pygame.display.set_mode((display_width,display_height))
##gameDisplay = pygame.display.set_mode((display_width,display_height),FULLSCREEN)
pygame.display.set_caption('Star Wars: A programming education game')

wallpaper_img = util.load_image('wallpaper/Wallpaper.png')
text_editor_img = util.load_image('pictures/right panel/Text editor.png')
maps = ['pictures/Map/warm_up.png',
           'pictures/Map/Map_0.png','pictures/Map/Map_4.png','pictures/Map/Balcony_map.png',
           'pictures/Map/Map_1.png','pictures/Map/SU.png','pictures/Map/Map_3.png',
           'pictures/Map/Map_5.png','pictures/Map/docking_bay.png','pictures/Map/Last_level_map_space.png']

map_img = [util.load_image(m) for m in maps]

lukeUpStationary = util.load_image('pictures/lukeMove/Luke_up_stationary.png')
lukeUpWalk1 = util.load_image('pictures/lukeMove/Luke_up_walk_1.png')
lukeUpWalk2 = util.load_image('pictures/lukeMove/Luke_up_walk_2.png')
lukeDownStationary = util.load_image('pictures/lukeMove/Luke_down_stationary.png')
lukeDownWalk1 = util.load_image('pictures/lukeMove/Luke_down_walk_1.png')
lukeDownWalk2 = util.load_image('pictures/lukeMove/Luke_down_walk_2.png')
lukeRightStationary = util.load_image('pictures/lukeMove/Luke_right_stationary.png')
lukeRightWalk = util.load_image('pictures/lukeMove/Luke_right_walk_1.png')
lukeLeftStationary = util.load_image('pictures/lukeMove/Luke_left_stationary.png')
lukeLeftWalk = util.load_image('pictures/lukeMove/Luke_left_walk_1.png')

reyUpStationary = util.load_image('pictures/reyMove/Rey_up_stationary.png')
reyUpWalk1 = util.load_image('pictures/reyMove/Rey_up_walk_1.png')
reyUpWalk2 = util.load_image('pictures/reyMove/Rey_up_walk_2.png')
reyDownStationary = util.load_image('pictures/reyMove/Rey_down_stationary.png')
reyDownWalk1 = util.load_image('pictures/reyMove/Rey_down_walk_1.png')
reyDownWalk2 = util.load_image('pictures/reyMove/Rey_down_walk_2.png')
reyRightStationary = util.load_image('pictures/reyMove/Rey_right_stationary.png')
reyRightWalk1 = util.load_image('pictures/reyMove/Rey_right_walk_1.png')
reyRightWalk2 = util.load_image('pictures/reyMove/Rey_right_walk_2.png')
reyLeftStationary = util.load_image('pictures/reyMove/Rey_left_walk_1.png')
reyLeftWalk1 = util.load_image('pictures/reyMove/Rey_left_walk_1.png')
reyLeftWalk2 = util.load_image('pictures/reyMove/Rey_left_walk_2.png')

finnUpStationary = util.load_image('pictures/finnMove/Finn_up_stationary.png')
finnUpWalk1 = util.load_image('pictures/finnMove/Finn_up_walk_1.png')
finnUpWalk2 = util.load_image('pictures/finnMove/Finn_up_walk_2.png')
finnDownStationary = util.load_image('pictures/finnMove/Finn_down_stationary.png')
finnDownWalk1 = util.load_image('pictures/finnMove/Finn_down_walk_1.png')
finnDownWalk2 = util.load_image('pictures/finnMove/Finn_down_walk_2.png')
finnRightStationary = util.load_image('pictures/finnMove/Finn_right_stationary.png')
finnRightWalk1 = util.load_image('pictures/finnMove/Finn_right_walk_1.png')
finnRightWalk2 = util.load_image('pictures/finnMove/Finn_right_walk_2.png')
finnLeftStationary = util.load_image('pictures/finnMove/Finn_left_stationary.png')
finnLeftWalk1 = util.load_image('pictures/finnMove/Finn_left_walk_1.png')
finnLeftWalk2 = util.load_image('pictures/finnMove/Finn_left_walk_2.png')

renUpStationary = util.load_image('pictures/renMove/Ren_up.png')
renDownStationary = util.load_image('pictures/renMove/Ren_down.png')
renRightStationary = util.load_image('pictures/renMove/Ren_right.png')
renLeftStationary = util.load_image('pictures/renMove/Ren_left.png')

darthUpStationary = util.load_image('pictures/darthMove/Darth_up.png')
darthDownStationary = util.load_image('pictures/darthMove/Darth_down.png')
darthRightStationary = util.load_image('pictures/darthMove/Darth_right.png')
darthLeftStationary = util.load_image('pictures/darthMove/Darth_left.png')

stormtUpStationary = util.load_image('pictures/stormtMove/StormT_up.png')
stormtDownStationary = util.load_image('pictures/stormtMove/StormT_down.png')
stormtRightStationary = util.load_image('pictures/stormtMove/StormT_right.png')
stormtLeftStationary = util.load_image('pictures/stormtMove/StormT_left.png')

mFalconStationary = util.load_image('pictures/milleniumFalcon/mFalcon_stationary.png')
mFalconThrusterSmall = util.load_image('pictures/milleniumFalcon/mFalcon_thruster_small.png')
mFalconThrusterBig = util.load_image('pictures/milleniumFalcon/mFalcon_thruster_big.png')

reyMoveUp = [reyUpWalk1, reyUpWalk2, reyUpStationary]
reyMoveDown = [reyDownWalk1, reyDownWalk2, reyDownStationary]
reyMoveRight = [reyRightWalk1, reyRightWalk2, reyRightStationary]
reyMoveLeft = [reyLeftWalk1, reyLeftWalk2, reyLeftStationary]

lukeMoveUp = [lukeUpWalk1, lukeUpWalk2, lukeUpStationary]
lukeMoveDown = [lukeDownWalk1, lukeDownWalk2, lukeDownStationary]
lukeMoveRight = [lukeRightStationary, lukeRightWalk, lukeRightStationary]
lukeMoveLeft = [lukeLeftStationary, lukeLeftWalk, lukeLeftStationary]

finnMoveUp = [finnUpWalk1, finnUpWalk2, finnUpStationary]
finnMoveDown = [finnDownWalk1, finnDownWalk2, finnDownStationary]
finnMoveRight = [finnRightWalk1, finnRightWalk2, finnRightStationary]
finnMoveLeft = [finnLeftWalk1, finnLeftWalk2, finnLeftStationary]

renMoveUp = [renUpStationary, renUpStationary, renUpStationary]
renMoveDown = [renDownStationary, renDownStationary, renDownStationary]
renMoveRight = [renRightStationary, renRightStationary, renRightStationary]
renMoveLeft = [renLeftStationary, renLeftStationary, renLeftStationary]

darthMoveUp = [darthUpStationary, darthUpStationary, darthUpStationary]
darthMoveDown = [darthDownStationary, darthDownStationary, darthDownStationary]
darthMoveRight = [darthRightStationary, darthRightStationary, darthRightStationary]
darthMoveLeft = [darthLeftStationary, darthLeftStationary, darthLeftStationary]

stormtMoveUp = [stormtUpStationary, stormtUpStationary, stormtUpStationary]
stormtMoveDown = [stormtDownStationary, stormtDownStationary, stormtDownStationary]
stormtMoveRight = [stormtRightStationary, stormtRightStationary, stormtRightStationary]
stormtMoveLeft = [stormtLeftStationary, stormtLeftStationary, stormtLeftStationary]

mFalconFireUp = [mFalconStationary, mFalconThrusterSmall, mFalconStationary, mFalconThrusterSmall,
                 mFalconThrusterBig, mFalconStationary, mFalconThrusterSmall, mFalconThrusterBig,
                 mFalconThrusterBig, mFalconStationary, mFalconThrusterSmall, mFalconThrusterBig,
                 mFalconThrusterSmall, mFalconThrusterBig, mFalconThrusterBig, mFalconThrusterBig]
blueprint_img = util.load_image('pictures/Blueprint.png')

# holes
holes = []

trooper_LOS = pygame.Rect(420, 210, 30, 30)

# for run button
btnimg = util.load_image('pictures/runbtn.png')
eraseimg = util.load_image('pictures/erasebtn.png')
runbtn_rect = pygame.Rect(1075, 590, *btnimg.get_rect().size)
erasebtn_rect = pygame.Rect(830, 15, *eraseimg.get_rect().size)

clock = pygame.time.Clock()

smallfont = pygame.font.Font('diehund.ttf', 30)
medfont = pygame.font.Font('diehund.ttf', 40)
largefont = pygame.font.Font('diehund.ttf', 80)

#sound fxps
#---BGM
bgm1 = "sounds/bgm1-throneroom.ogg"
bgm1loop = "sounds/bgm1-throneroomloop.ogg"
bgm2 = "sounds/bgm2-intothetrap.ogg"
bgm2loop = "sounds/bgm2-intothetraploop.ogg"
bgm3 = "sounds/bgm3-countdooku.ogg"
bgm3loop = "sounds/bgm3-countdookuloop.ogg"
bgm4 = "sounds/bgm4-duelofthefates.ogg"
bgm4loop = "sounds/bgm4-duelofthefatesloop.ogg"

falcon = pygame.mixer.Sound("sounds/powerupandblast.ogg")
trooper = pygame.mixer.Sound("sounds/stormtrooper1.ogg")
fall = pygame.mixer.Sound("sounds/fall1.ogg")
bangwall = pygame.mixer.Sound("sounds/bangwall1.ogg")    #done
collectblueprint= pygame.mixer.Sound("sounds/collectblueprint1.ogg")
jump1 = pygame.mixer.Sound("sounds/jump1.ogg")
startGame = pygame.mixer.Sound("sounds/start.ogg")
wallbang = pygame.mixer.Sound("sounds/bang1.ogg")
dvlist = ["sounds/darth vader - die1.wav","sounds/darth vader - i have you now.wav","sounds/darth vaer - breath.wav","sounds/darth vader - thisistheend.wav"]

BEGIN_LOOP = pygame.USEREVENT + 1

def loadLevel(level):
    position=[[360,570],[180,180],[0,450],[30,270],[750,420],[360,30],[420,30],[60,330],[30,270],[30,270]]
    levelXList = [[510,0,0,810],[0,180,360,180,360,600,360,450,420],[0,120,270,420,690,540,390,240,0],
                  [0,0,0,30,780,780],[0,30,780,0,420,180,510,180,300,420,510,30,180,510,630],[0,0,60,390],
             [0,0,270,330,360,450,450,450,450,450,750],
             [0,0,360,600,240,480,720,0,0],[0,0,0,30],[0,0,0,30]]
    levelYList = [[360,0,180,180],[0,0,120,450,390,0,240,0,-30],[0,0,0,0,0,150,270,390,510],[0,30,300,570,30,300],
                  [0,570,0,0,0,480,480,30,30,60,60,210,180,180,210],
                  [0,90,270,0],
                  [0,90,120,120,240,0,120,270,420,540,60],
                  [0,180,180,180,270,270,240,390,300],[0,60,300,570],[0,60,300,570]]
    widthlist = [[300,810,270,30],[180,240,60,630,450,210,240,150,30],
                 [120,150,150,150,120,150,150,150,240],[600,30,30,780,30,30],
                 [30,780,30,390,780,120,120,120,90,90,120,150,120,120,180],
                 [360,60,300,420],
                 [420,240,60,90,60,360,270,180,270,360,60],
                 [810,180,60,60,60,60,90,810,60],[810,30,30,780],[810,30,30,780]]
    heightlist=[[240,180,420,240],[600,120,60,150,60,390,90,180,30],
                [420,300,180,60,600,450,330,210,90],[60,240,270,30,240,270],
                [600,30,570,60,60,90,90,120,90,60,90,120,210,210,120],
                [90,510,330,600],
                [90,390,360,90,360,90,90,90,90,60,480],
                [180,120,120,120,120,120,150,210,90],[60,210,300,30]
                ,[60,210,300,30]]
    win_width = [30,30,120,30,30,30,210,30,30,60]
    win_height = [240,30,30,30,30,30,30,60,510,120]
    win_xyCoordinates = [[780,180],[420,0],[570,0],[780,270],[390,0],[360,570],
                         [240,570],[780,180],[780,60],[510,240]]
    holeCoords = [[],[[570,180],[570,210]],[],[[390,0],[390,30],[390,60],[390,90],[390,120],[390,150],[390,180],[390,210],[390,240],[390,270]
                                               ,[390,300],[390,330],[390,360],[390,390],[390,420],[390,450],[390,480],[390,510],[390,540],[390,570]]
                  ,[],[[360,150],[360,300],[360,420]],[[240,180],[240,360]],[],[[180,210],[180,240],[210,450],[210,480],[210,510],[360,270],[360,270],[360,270],[360,300],[360,330],[570,150],
                                [570,180],[570,210],[510,390],[510,420]],[]]

    vader_face = [1,0,0,2,2,0,0,1,1,3] # 0-Down, 1-Left, 2- Up, 3-Right
    blueprint_xy = [[],[],[],[],[120,150],[],[240,240],[],[],[]]
    return [position[level][0],position[level][1],levelXList[level],levelYList[level],widthlist[level],heightlist[level],win_width[level],win_height[level],\
            win_xyCoordinates[level][0],win_xyCoordinates[level][1],holeCoords[level], vader_face[level],blueprint_xy[level]]

def done_moving():
    if movement.get_next_move() == 'stationary':
        return True
    return False

class Player:

    def __init__(self):
        self.moveUp = lambda steps = 1: self.move('move_up', steps)
        self.moveDown = lambda steps = 1: self.move('move_down', steps)
        self.moveLeft = lambda steps = 1: self.move('move_left', steps)
        self.moveRight = lambda steps = 1: self.move('move_right', steps)

        self.jumpUp = lambda steps = 1: self.move('jump_up', steps)
        self.jumpDown = lambda steps = 1: self.move('jump_down', steps)
        self.jumpLeft = lambda steps = 1: self.move('jump_left', steps)
        self.jumpRight = lambda steps = 1: self.move('jump_right', steps)

    def move(self, direction, steps):
        global game_state
        game_state = direction

        while True:
            if game_state == 'gameover':
                game_state = 'idle' # reset game_state
            if game_state == 'idle':
                steps -= 1
                if steps <= 0: break
                game_state = direction

    def holeInFront(self):
        for hole in holes:
            player_rect = pygame.Rect(lead_x, lead_y, 30, 30)
            collide_direction = hole.collides(player_rect)
##            print player_rect
##            print 'psuedo_holes', collide_direction
##            print 'lead_direction', lead_direction
##            # if lead_direction == collide_direction: return True
            if lead_direction == collide_direction:
                return True
        return False

this_is_impossible_to_be_screwed_up = Player()

def parser_func(code):
    global game_state
    try:
        exec(code)
##    except SystemExit:
##        print "exit from loop."
    except:
        traceback.print_exc()
        game_state = 'error'
    finally:
        parsing = False

def display_error():
    global game_state, rebelScore
    rebelScore -= 2
    paused = True
    message_to_screen("CODE ERROR", red,
                      y_displace=-50, size = "large")
    message_to_screen("Press C to play again", orange,
                      50, size = "medium")
    message_to_screen("or Q to quit", orange,
                      100, size = "medium")
    pygame.display.update()
    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_c:
                    paused = False
                elif event.key == pygame.K_q:
                    pygame.quit()
                    quit()

        clock.tick(5)

    game_state = 'idle'
    gameLoop()

def barrier(xlocation,ylocation, barrier_width, barrier_height):
    pygame.draw.rect(gameDisplay,black, [xlocation, ylocation, barrier_width, barrier_height])

def pause():
    paused = True
    message_to_screen("Paused", black, -100, size = "large")
    message_to_screen("Press c to continue", black, 25, size = "small")
    pygame.display.update()
    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_c:
                    paused = False
                elif event.key == pygame.K_q:
                    pygame.quit()
                    quit()

        clock.tick(5)

def helpInstructions(level):
    csmallfont = pygame.font.Font('diehund.ttf', 15)
    csmallfont.set_italic(True);

    xsmallfont = pygame.font.Font('diehund.ttf', 15)
    xsmallfont.set_underline(True)
    xsmallfont.set_bold(True)
    gameDisplay.blit(xsmallfont.render("Level "+str(level + 1), True, white),\
                         [835, 375])
    xsmallfont.set_underline(False)
    xsmallfont.set_bold(False)

    # 9 Lines max
    helpMessage = {0 : ["Commands to move your player", # Learn move
                        "c      self.moveUp()",
                        "c      self.moveRight()",
                        "",
                        "You can put in parameters, eg",
                        "to move right 4 steps",
                        "c      self.moveRight(4)"],
                   1 : ["Commands to move your player", # Learn move
                        "c      self.moveUp()",
                        "c      self.moveRight()",
                        "c      self.moveDown()",
                        "c      self.moveLeft()",
                        "",
                        "Python is indentation and case ",
                        "sensitive!",
                        "It could be the source of your bugs"],
                   2 : ["Loops can ease your pain of coding", # Learn basic loop
                        "lines of the same thing.",
                        "c",
                        "c      while True :",
                        "c          self.moveRight()",
                        "c          self.moveLeft()",
                        "c",
                        "'self' represents the object you are",
                        "controlling, in this case, the player."],
                   3 : ["Here are some useful actions to use", # Learn condition check
                        "for jumping across holes.",
                        "",
                        "c        self.jumpRight()",
                        "c        self.jumpLeft()",
                        "c        self.jumpUp()",
                        "c        self.jumpDown()",],
                   4 : ["The Death Star Blueprint earns you ",
                        "30 points!",
                        "Programming is about efficiency.",
                        "If you didn't realize, points have", # Example conditions 1
                        "been awarded based on how many",
                        "line is your code and how much",
                        "time is left upon reaching the ",
                        "objective.",
                        "",
                        ""],
                   5 : ["Avoid getting detected by infrared",
                        "sensors! They're like holes!",
                        "You can use jump to avoid them. ", # Example conditions 2
                        "",
                        "a condition check.",
                        "c      while True:",
                        "c          if self.holeInFront():",
                        "c              <do stuff>",
                        "c          <do stuff>"],
                   6 : ["Avoid getting detected by Storm", # Test!
                        "Troopers. Jumping isn't going to",
                        "help you.",
                        "Hint:",
                        "      If you like a challenge,",
                        "      collect the blueprint.",
                        "      Otherwise, take the right path.",
                        "",
                        ""],
                   7 : ["Let's see how fast you can get",
                        "this over and done with.",
                        "Hint:",
                        "  You will need 4 moves in a ",
                        "  loop."],
                   8 : ["You are close to completion. The ",
                        "Millenium Falcon is at the next ",
                        "docking bay!",
                        "",
                        "c    while <condition>:",
                        "c        if <condition>:",
                        "c            <do stuff>",
                        "c        else:",
                        "c            <do stuff>"],
                   9 : ["Hop onto the Millenium Falcon and",
                        "escape!",
                        "Holes will randomly appear on the",
                        "map, so try putting if-else ",
                        "statement in a loop!"]}
    for lineNumber in range(len(helpMessage[level])):
        isCode = False
        if len(helpMessage[level][lineNumber]) > 0:
            if helpMessage[level][lineNumber][0] == 'c':
                helpMessage[level][lineNumber] = helpMessage[level][lineNumber][1:];
                isCode = True;

        if isCode:
            gameDisplay.blit(csmallfont.render(helpMessage[level][lineNumber], True, grey),\
                             [835, 395+lineNumber*xsmallfont.get_linesize()])
        else:
            gameDisplay.blit(xsmallfont.render(helpMessage[level][lineNumber], True, white),\
                             [835, 395+lineNumber*xsmallfont.get_linesize()])

def status(score,set_time,elapse_time):
    text = smallfont.render("Score:          " + str(score), True, black)
    gameDisplay.blit(text,[55,map_height])

    if(elapse_time>set_time):
        elapse_time=set_time
    pygame.draw.rect(gameDisplay,red, [map_width/2, map_height+2, map_width*(set_time-elapse_time)/(2*set_time), status_bar])
    pygame.draw.line(gameDisplay,black,(map_width/2-2,map_height),(map_width/2-2,display_height), 4)
    text2 = smallfont.render("Time left", True, black)
    gameDisplay.blit(text2,[3*map_width/4-15,map_height])

def randBlueprintGen():
    randBlueprintX = 120
    randBlueprintY = 150
    return randBlueprintX, randBlueprintY

#----Sounds method for choosing which bgm to load-----------#
def loadBGM(level):
    loadList = []

    if level == 1 or level == 2 or level == 0:
        loadList = [bgm1,bgm1loop]

    elif level == 3 or level == 4:
        loadList = [bgm2,bgm2loop]

    elif level == 5 or level == 6 or level == 7:
        loadList = [bgm3, bgm3loop]

    elif level == 8 or level == 9:
        loadList = [bgm4, bgm4loop]

    return loadList

def game_intro():
    global characterMove
    pygame.mixer.music.load("sounds/intro - star wars main theme.ogg")
    pygame.mixer.music.play(0)
    intro = True

    while intro:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_i:
                    characterMove = [renMoveUp, renMoveDown, renMoveRight, renMoveLeft]
                    intro=False
                if event.key == pygame.K_s:
                    characterMove = [stormtMoveUp, stormtMoveDown, stormtMoveRight, stormtMoveLeft]
                    intro=False
                if event.key == pygame.K_t:
                    characterMove = [lukeMoveUp, lukeMoveDown, lukeMoveRight, lukeMoveLeft]
                    intro=False
                if event.key == pygame.K_d:
                    characterMove = [darthMoveUp, darthMoveDown, darthMoveRight, darthMoveLeft]
                    intro=False
                if event.key == pygame.K_m:
                    startGame.play()
                    characterMove = [finnMoveUp, finnMoveDown, finnMoveRight, finnMoveLeft]
                    intro=False
                if event.key == pygame.K_f:
                    startGame.play()
                    characterMove = [reyMoveUp, reyMoveDown, reyMoveRight, reyMoveLeft]
                    intro=False
                if event.key == pygame.K_q:
                    pygame.quit()
                    quit()

        gameDisplay.fill(white)
        wp = wallpaper_img
        wp = pygame.transform.scale(wp,(display_width,display_height))
        gameDisplay.blit(wp, (0,0))
        pygame.display.update()
        clock.tick(5)

def rebel_move(direction, playerX, playerY, xChange, yChange, rebelScore, time_limit, seconds, xlocation, ylocation, barrier_width,barrier_height,randBlueprintX, randBlueprintY):

    global game_map
    image = None
    for img in characterMove[direction]:

        playerX += xChange
        playerY += yChange

        gameDisplay.fill(white)
        gameDisplay.blit(game_map, (0,0))
        gameDisplay.blit(text_editor, (map_width,0))
        pygame.draw.line(gameDisplay,black,(map_width,display_height),(map_width,0), 2)#draw boundary for user to type code
        pygame.draw.line(gameDisplay,black,(0,map_height),(map_width,map_height), 2)#draw boundary for status bar
        status(rebelScore, time_limit,seconds)
        #if level one
        game_map=map_img[level]
        if (blueprintCollected == False) and blueprintExist:
            gameDisplay.blit(blueprint_img, (randBlueprintX, randBlueprintY))

        gameDisplay.blit(btnimg, runbtn_rect)
        gameDisplay.blit(eraseimg, erasebtn_rect)
        draw_holes()
        gameDisplay.blit(img, (playerX, playerY))
        if level == 9:
            gameDisplay.blit(mFalconStationary, (510, 225))

        image = img

        txtbx.draw(gameDisplay)
        helpInstructions(level)
        pygame.display.update()
        clock.tick(10)

    return playerX, playerY, image

def rebel_jump(direction, playerX, playerY, xChange, yChange, rebelScore, time_limit, seconds, xlocation, ylocation, barrier_width,barrier_height,randBlueprintX, randBlueprintY):

    global game_map
    image = None

    img = characterMove[direction][-1] # get stationary img

    for j in range(6):

        # hardcoding storm trooper line of sight
        player_rect = pygame.Rect(playerX, playerY, 30, 30)
        if player_rect.colliderect(trooper_LOS) and level == 6:
            break

        playerX += xChange

        if direction == 2 or direction == 3:
            if j < 3:
                playerY -= abs(xChange)
            else:
                playerY += abs(xChange)
        elif direction == 0:
            if j < 4:
                playerY -= int(1.7*abs(yChange))
            else:
                playerY += int(0.4*abs(yChange))
        elif direction == 1:
            if j < 2:
                playerY -= int(0.4*abs(yChange))
            else:
                playerY += int(1.7*abs(yChange))

        gameDisplay.fill(white)
        gameDisplay.blit(game_map, (0,0))
        gameDisplay.blit(text_editor, (map_width,0))
        pygame.draw.line(gameDisplay,black,(map_width,display_height),(map_width,0), 2)#draw boundary for user to type code
        pygame.draw.line(gameDisplay,black,(0,map_height),(map_width,map_height), 2)#draw boundary for status bar
        status(rebelScore, time_limit,seconds)
        #if level one
        game_map=map_img[level]

        if (blueprintCollected == False) and blueprintExist:
            #barrier(xlocation, randomHeight, barrier_width)
            gameDisplay.blit(blueprint_img, (randBlueprintX, randBlueprintY))

        #for checking hole position
##            for hole in holes:
##                hole.draw()
        gameDisplay.blit(btnimg, runbtn_rect)
        gameDisplay.blit(eraseimg, erasebtn_rect)
        draw_holes()
        gameDisplay.blit(img, (playerX, playerY))
        if level == 9:
            gameDisplay.blit(mFalconStationary, (510, 225))

        image = img

        txtbx.draw(gameDisplay)
        helpInstructions(level)
        pygame.display.update()
        clock.tick(15)

    return playerX, playerY, image

def mfalcon_fly(rebelScore, time_limit, seconds, randBlueprintX, randBlueprintY):

    global game_map
    falcon.play()
    mFalconX = 510
    mFalconY = 225

    for i in range(len(mFalconFireUp) + 100):

        if i > 15:
            index = 15
            mFalconX += 5
        else:
            index = i

        for j in range(2):
            gameDisplay.fill(white)
            gameDisplay.blit(game_map, (0,0))
            draw_holes()
            gameDisplay.blit(mFalconFireUp[index], (mFalconX, mFalconY))
            gameDisplay.blit(text_editor, (map_width,0))
            pygame.draw.line(gameDisplay,black,(map_width,display_height),(map_width,0), 2)#draw boundary for user to type code
            pygame.draw.line(gameDisplay,black,(0,map_height),(map_width,map_height), 2)#draw boundary for status bar
            status(rebelScore, time_limit,seconds)
            helpInstructions(level)
            #if level one
            game_map=map_img[level]

            if (not blueprintCollected) and blueprintExist:
                gameDisplay.blit(blueprint_img, (randBlueprintX, randBlueprintY))
            gameDisplay.blit(btnimg, runbtn_rect)
            gameDisplay.blit(eraseimg, erasebtn_rect)

            txtbx.draw(gameDisplay)
            helpInstructions(level)
            pygame.display.update()

            if index != 15:
                clock.tick(10)

def place_random_holes():
    del holes[:]
    if level == 9:
        possible_locs = range(3, 20, 2)
    else:
        possible_locs = range(3, 25, 2)
    vertical_locs = random.randint(6, 12)
    for i in range (8): # number of columns of holes
        x = random.randrange(3, 16, 2)
        y = random.randrange(6, 12)
        make_hole_columns(x * 30, y * 30, random.choice((2, 3)))

def make_hole_columns(x, y, height):
    for i in range(height):
        holes.append(Hole(gameDisplay, (x, y + (i * 30))))

def draw_holes():
    if level == numOfLevels - 1: # only draw holes for last level
        for hole in holes:
            hole.draw()

def crashed_into_wall(lead_x, lead_y, xlist, ylist, widthlist, heightlist):
    player_rect = pygame.Rect(lead_x, lead_y, 30, 30)
    for i in range(len(xlist)):
        wall = pygame.Rect(xlist[i], ylist[i], widthlist[i], heightlist[i])
        if wall.colliderect(player_rect): return True
    return False

def linecount_to_score(n):
    return txtbx.lines - n

def text_objects(text,color,size):
    if size == "small":
        textSurface = smallfont.render(text, True, color)
    elif size == "medium":
        textSurface = medfont.render(text, True, color)
    elif size == "large":
        textSurface = largefont.render(text, True, color)
    return textSurface, textSurface.get_rect()

def message_to_screen(msg,color, y_displace = 0, size = "small"):
    textSurf, textRect = text_objects(msg, color, size)
    textRect.center = (map_width / 2), (map_height / 2) + y_displace
    gameDisplay.blit(textSurf, textRect)

def gameLoop():
    global parsing, game_state, text_editor, elemNumber, level,txtbx, game_map, blueprintCollected, characterMove,numOfLevels, rebelScore
    global lead_x, lead_y, lead_direction,holes,blueprintExist, time_limit
    gameWon = False
    gameExit = False
    gameOver = False
    leftCollision = False
    rightCollision = False
    topCollision = False
    bottomCollision = False
    player = characterMove[1][2]
    [lead_x,lead_y,xlist,ylist,widthlist,heightlist,win_width,win_height,win_xlocation,win_ylocation,holeCoords,vadarOrientation,blueprint] = loadLevel(level)

    lead_x_change = 0
    lead_y_change = 0
    randBlueprintX = 0
    randBlueprintY = 0
    blueprintExist = False
    if(len(blueprint)>0):
        blueprintCollected = False
        blueprintExist = True
        randBlueprintX = blueprint[0]
        randBlueprintY = blueprint[1]

    step_count = 0
    pause_duration = 0
    code_lines = 0
    movement.reset()

    timerStart=False
    seconds=0
    del holes[:]
    for i in range(len(holeCoords)):
        holes.append(Hole(gameDisplay, (holeCoords[i][0], holeCoords[i][1])))
    # use get_ticks to time
    #timer.reset()

    barrier_width = 30
    barrier_height = 30
    xlocation = (map_width/2)+ random.randint(-0.2*map_width, 0.2*map_width)
    ylocation = random.randrange(map_height*0.1,map_height*0.6)

    #----------LOAD BGM-----------#
    beginloop = False
    bgmlist = loadBGM(level)
    pygame.mixer.music.stop() # make sure theres no music playing.
    pygame.mixer.music.load(bgmlist[0])
    pygame.mixer.music.play(0)
    pygame.mixer.music.set_endevent(BEGIN_LOOP)

    while not gameExit:

        #Check if bgm has finish playing

        event = pygame.mixer.music.get_endevent()
        pygame.mixer.music.queue(bgmlist[1])

        if gameWon == True:
            rebelScore += linecount_to_score(code_lines)+int(time_limit-seconds)
            pygame.draw.rect(gameDisplay, white, [240, map_height+4, 90, 31])
            status(rebelScore, time_limit,seconds)
            #-----sounds
            pygame.mixer.music.stop()
            pygame.mixer.music.load("sounds/victorybgm.ogg")
            pygame.mixer.music.play(-1)
            #-----sounds
            if level == 9:
                message_to_screen("Congratulations!", green,
                                  y_displace=-150, size = "large")
                message_to_screen("Your Score is " + str(rebelScore), green,
                                  y_displace=-50, size = "medium")
                message_to_screen("Please notify your friendly TA", orange,
                                  50, size = "small")
                message_to_screen("to collect your prize", orange,
                                  100, size = "small")
            else:
                message_to_screen("Level cleared!", green,
                                  y_displace=-50, size = "large")
                message_to_screen("Press C to proceed", orange,
                                  50, size = "small")
                message_to_screen("or Q to quit", orange,
                                  100, size = "small")

            level = (level+1)%numOfLevels
            txtbx.clear()

            pygame.display.update()

        elif gameOver == True:
            rebelScore -= 2
            pygame.mixer.music.stop()
            pygame.mixer.music.load("sounds/lose - imperial march.ogg")
            pygame.mixer.music.play(-1)
            #-----sounds
            message_to_screen("GAME OVER", red,
                              y_displace=-50, size = "large")
            message_to_screen("Press C to play again", orange,
                              50, size = "medium")
            message_to_screen("or Q to quit", orange,
                              100, size = "medium")
            #----- displays
            if vadarOrientation == 0:
                gameDisplay.blit(darthDownStationary, (win_xlocation, win_ylocation))
            elif vadarOrientation == 2:
                gameDisplay.blit(darthUpStationary, (win_xlocation, win_ylocation))
            elif vadarOrientation == 1:
                gameDisplay.blit(darthLeftStationary, (win_xlocation, win_ylocation))
            else:
                gameDisplay.blit(darthRightStationary, (win_xlocation, win_ylocation))
            pygame.display.update()

        while gameOver == True or gameWon == True:
            game_state = 'gameover'
            parser_thread.stop()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    gameWon = False
                    gameOver = False
                    gameExit = True
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        gameWon = False
                        gameExit = True
                        gameOver = False
                    if event.key == pygame.K_c:
                        game_state = 'idle'
                        gameWon= False
                        pygame.mixer.music.stop()
                        gameLoop()

    ############## timer ##########################
        if timerStart:
            timer.update()
            seconds = timer.get_time() #calculate how many seconds
            if (time_limit - seconds)<=0:
                randnumb = random.randint(0,len(dvlist)-1)
                #-----sounds
                pygame.mixer.Sound(dvlist[randnumb]).play()
                #-----sounds
                gameOver=True
            #print (seconds) #print how many seconds

###################### WIN GAME CONDITIONS: Lands on the exit grid ###########################
        win_rect = pygame.Rect(win_xlocation, win_ylocation, win_width, win_height)
        player_rect = pygame.Rect(lead_x, lead_y, 30, 30)
        if win_rect.colliderect(player_rect):
            gameWon = True
            if level == 9:
                mfalcon_fly(rebelScore, time_limit, seconds, randBlueprintX, randBlueprintY)

###################### END GAME CONDITIONS: Out of bound detection, Timelimit ###########################
        if lead_x > map_width - block_size or lead_x < 0 or lead_y > map_height - block_size \
            or lead_y<0:
            gameOver = True

        if game_state == 'error':
            display_error()

####################### UPDATES PLAYER LOCATION ################################
        # lead_x += lead_x_change
        # lead_y += lead_y_change

####################### displaying it on screen ################################
        gameDisplay.fill(white)
        game_map=map_img[level]
        text_editor=text_editor_img
        gameDisplay.blit(game_map, (0,0))
        gameDisplay.blit(text_editor, (map_width,0))
        pygame.draw.line(gameDisplay,black,(map_width,display_height),(map_width,0), 2) #draw boundary for user to type code
        pygame.draw.line(gameDisplay,black,(0,map_height),(map_width,map_height), 2) #draw boundary for status bar
        if not gameWon:
            gameDisplay.blit(player, (lead_x, lead_y))
        status(rebelScore, time_limit,seconds)
        helpInstructions(level)

        if level == numOfLevels - 1:
            draw_holes()
        if level == 9 and not gameWon:
            gameDisplay.blit(mFalconStationary, (510, 225))

####################### barrier collision detection #############################

        for i in range(0,len(xlist)):
            ylocation = ylist[i]
            xlocation = xlist[i]
            barrier_height = heightlist[i]
            barrier_width = widthlist[i]
            #for debugging:
            #pygame.draw.rect(gameDisplay,red,[xlocation,ylocation,barrier_width,barrier_height])
            if ylocation + barrier_height > lead_y and lead_y + block_size > ylocation:
                if lead_x - (block_size/2) < xlocation + barrier_width and lead_x > xlocation + barrier_width/2:
                    leftCollision = True
                if lead_x + (4*block_size) > xlocation and lead_x < xlocation + barrier_width/2:
                    rightCollision = True
            elif xlocation + barrier_width > lead_x and lead_x + block_size > xlocation:
                if lead_y - (block_size/2) < ylocation + barrier_height and lead_y > ylocation + barrier_height/2:
                    topCollision = True
                if lead_y + (4*block_size) > ylocation and lead_y < ylocation + barrier_height/2:
                    bottomCollision = True

######################## when blueprint have been collected ###########################
        if (blueprintCollected == False) and blueprintExist:
            gameDisplay.blit(blueprint_img, (randBlueprintX, randBlueprintY))
            if lead_x >= randBlueprintX and lead_x <= randBlueprintX + BlueprintThickness or lead_x + block_size >= randBlueprintX and \
               lead_x + block_size <= randBlueprintX + BlueprintThickness:

                if lead_y >= randBlueprintY and lead_y <= randBlueprintY + BlueprintThickness:
                    rebelScore+=30
                    collectblueprint.play()
                    blueprintCollected = True

                elif lead_y + block_size >= randBlueprintY and lead_y + block_size <= randBlueprintY + BlueprintThickness:
                    rebelScore+=30
                    collectblueprint.play()
                    blueprintCollected = True

        clock.tick(30)
            ##for checking holes in map
##        for hole in holes:
##            hole.draw()

    ######################### Player controls - Keypress or Typed text #########################

        events = pygame.event.get()

        # to quit game
        for event in events:
            if event.type == pygame.QUIT:
                gameExit = True

        # Use the Movement class to keep track of moves.
        if control_mode == 'TYPE':
            next_move = movement.get_next_move()
            # print "next_move", next_move
            # print "left collision", leftCollision
            # print "right collision", rightCollision
            # print "top collision", topCollision
            # print "btm collision", bottomCollision

            # 0: up, 1: down, 2: right, 3: left
            if next_move == 'stationary':
                lead_x_change = 0
                lead_y_change = 0
            elif next_move == 'move_up':
                if topCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_move(0, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # topCollision = False
                else:
                    lead_x, lead_y, player = rebel_move(0, lead_x, lead_y, 0, -10, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'move_down':
                if bottomCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_move(1, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # bottomCollision = False
                else:
                    lead_x, lead_y, player = rebel_move(1, lead_x, lead_y, 0, 10, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'move_left':
                if leftCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_move(3, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # leftCollision = False
                else:
                    lead_x, lead_y, player = rebel_move(3, lead_x, lead_y, -10, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'move_right':

                if rightCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_move(2, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # rightCollision = False
                else:
                    lead_x, lead_y, player = rebel_move(2, lead_x, lead_y, 10, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'jump_up':
                jump1.play()
                if topCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_jump(0, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # topCollision = False
                else:
                    lead_x, lead_y, player = rebel_jump(0, lead_x, lead_y, 0, -10, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'jump_down':
                jump1.play()
                if bottomCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_jump(1, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # bottomCollision = False
                else:
                    lead_x, lead_y, player = rebel_jump(1, lead_x, lead_y, 0, 10, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'jump_left':
                jump1.play()
                if leftCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_jump(3, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # leftCollision = False
                else:
                    lead_x, lead_y, player = rebel_jump(3, lead_x, lead_y, -10, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            elif next_move == 'jump_right':
                jump1.play()
                if rightCollision:
                    bangwall.play()
                    lead_x, lead_y, player = rebel_jump(2, lead_x, lead_y, 0, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)
                    # rightCollision = False
                else:
                    lead_x, lead_y, player = rebel_jump(2, lead_x, lead_y, 10, 0, rebelScore, time_limit, seconds, xlocation, ylocation,
                                                    barrier_width, barrier_height, randBlueprintX, randBlueprintY)

            # reset all collision state after moving (although right now it resets even when not moving)
            topCollision = False
            bottomCollision = False
            leftCollision = False
            rightCollision = False

        if crashed_into_wall(lead_x, lead_y, xlist, ylist, widthlist, heightlist):
            bangwall.play()
            gameOver = True

        # hardcoding storm trooper line of sight
        player_rect = pygame.Rect(lead_x, lead_y, 30, 30)
        if level == 6 and player_rect.colliderect(trooper_LOS):
            trooper.play()
            gameOver = True

        # check if player is on a hole
        for hole in holes:
            player_rect = pygame.Rect(lead_x, lead_y, 30, 30)
            collide_direction = hole.collides(player_rect)
            if collide_direction == 'exact':
                fall.play()
                gameOver = True

        if parsing:
            movement_state = game_state[:4]
            direction = game_state[5:]
            if movement_state == 'jump' or movement_state == 'move':
                movement.add_move(game_state)
                lead_direction = direction
                game_state = 'moving'
            elif game_state == 'moving' and done_moving():
                game_state = 'idle'

        # run code button
        gameDisplay.blit(btnimg, runbtn_rect)
        gameDisplay.blit(eraseimg, erasebtn_rect)
        for event in events:
            if event.type == pygame.MOUSEBUTTONUP:
                # print pygame.mouse.get_pos()
                if erasebtn_rect.collidepoint(pygame.mouse.get_pos()):
                    txtbx.clear()
                if runbtn_rect.collidepoint(pygame.mouse.get_pos()):
                    if timerStart==False:
                        timer.set_ticks_func(pygame.time.get_ticks)
                        timer.reset()
                        timerStart=True

                    if level == numOfLevels - 1:
                        place_random_holes()

                    parsing = True

                    code = txtbx.get_text()
                    code = code.replace('self', 'this_is_impossible_to_be_screwed_up')
                    code_lines += txtbx.get_linecount()
                    parser_thread.start(parser_func, code)

        txtbx.update(events)
        txtbx.draw(gameDisplay)
        pygame.display.update()

    parser_thread.stop()
    pygame.quit()
    quit()

game_intro()
gameLoop()


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

# In[1]:

#错误笔记：
#1.最终运行时应把前面调用函数的测试部分全部注释掉，避免测试部分使用的参数和最终运行的
# 传入的参数重复，造成错误。

# In[2]:

get_ipython().run_line_magic('pwd', '')

# In[3]:

# cd E:\\jupyterCode

# In[4]:

# cd .ipynb_checkpoints

# In[5]:

#sklearn提供了用于数据挖掘和分析的简单有效的工具
#matplotlib是Python中常用的绘制图形的库
#testCases提供了一些测试示例用以评估函数的正确性
#planar_utils提供了此作业中使用的各种函数

# In[6]:

#1---------安装包
import numpy as np
import matplotlib.pyplot as plt
from testCases import *
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import plot_decision_boundary,sigmoid,load_planar_dataset,load_extra_datasets

get_ipython().run_line_magic('matplotlib', 'inline')
np.random.seed(1)

# In[31]:

#2-------------数据集①
#以下代码会将“flower” 2分类数据集加载到变量 X 和 Y中。
X,Y=load_planar_dataset()
#红色（y=0）和蓝色（y=1），使用matplotlib可视化数据集
plt.scatter(X[0,:],X[1,:],c=Y.reshape(X[0,:].shape),s=40,cmap=plt.cm.Spectral)

# In[8]:

#2-------------数据集②
"""
noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure = load_extra_datasets()
datasets = {"noisy_circles": noisy_circles,
            "noisy_moons": noisy_moons,
            "blobs": blobs,
            "gaussian_quantiles": gaussian_quantiles}
dataset = "noisy_moons"
X,Y=datasets[dataset]
X, Y = X.T, Y.reshape(1, Y.shape[0])
if dataset == "blobs":
    Y = Y % 2

#plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral)
#上一语句如出现问题请使用下面的语句：
plt.scatter(X[0, :], X[1, :], c=np.squeeze(Y), s=40, cmap=plt.cm.Spectral)
"""

# In[9]:

#现在有的：
#包含特征（x1，x2）的numpy数组（矩阵）X
#包含标签（红色：0，蓝色：1）的numpy数组（向量）Y。

#########################
#了解数据集：
#1.数据集中有多少个训练示例？
#2.变量“X”和“Y”的shape是什么？

# In[10]:

shape_X=X.shape
shape_Y=Y.shape
m=shape_X[1]
print('The shape of X is: '+str(shape_X))
print('The shape of Y is: '+str(shape_Y))
print('I have m = %d training examples!' % (m))

# In[11]:

#3------------简单的Logistic回归
#可以使用sklearn的内置函数来执行此操作，运行以下代码在数据集上训练逻辑回归分类器
clf=sklearn.linear_model.LogisticRegressionCV();
clf.fit(X.T,Y.T)

# In[32]:

#运行下面的代码绘制此模型的决策边界：
# 错误 plot_decision_boundary(lambda x:clf.predict(x),X,Y)
#squeeze()函数的功能是：从矩阵shape中，去掉维度为1的。
plot_decision_boundary(lambda x:clf.predict(x), X, np.squeeze(Y)) #绘制决策边界
plt.title("Logistic Regression")    #图标题
LR_predictions=clf.predict(X.T)     #预测结果
print("逻辑回归的准确性： %d " % float((np.dot(Y,LR_predictions)+np.dot(1 - Y,1 - LR_predictions))/float(Y.size)*100)+"% " + "(正确标记的数据点所占的百分比)")
#print(np.dot(Y,LR_predictions))
#print(np.dot(1 - Y,1 - LR_predictions))
#print(float(Y.size))
#print(Y)
#print(LR_predictions)
#print(Y.shape)
#print(LR_predictions.shape)

# In[13]:

#准确性只有47%的原因是数据集不是线性可分的，所以逻辑回归表现不佳，现在我们正式开始构建神经网络.
#采用激活函数a=tan（z）
#建立神经网络的一般方法是：
# 1.定义神经网络结构（输入单元的数量，隐藏单元的数量）
# 2.初始化模型的参数
# 3.循环：
#     实施前向传播
#     计算损失
#     实现向后传播
#     更新参数（梯度下降）
# 我们要它们合并到一个nn_model()函数中，
#当我们构建好了nn_model()并学习了正确的参数，我们就可以预测新的数据

# In[14]:

# 1.定义神经网络结构（输入单元的数量，隐藏单元的数量）
"""
 n_x:输入层的数量
 n_h：隐藏层的数量（本实验设置为4）
 n_y：输出层的数量
"""
def layer_sizes(X,Y):
    """
    参数：
     X - 输入数据集,维度为（输入的数量，训练/测试的数量）
     Y - 标签，维度为（输出的数量，训练/测试数量）

    返回：
     n_x - 输入层的数量
     n_h - 隐藏层的数量
     n_y - 输出层的数量
    """
    n_x=X.shape[0]  #输入层
    n_h=4 #隐藏层，硬编码为4
    n_y=Y.shape[0] #输出层

    return (n_x,n_h,n_y)
"""
#测试layer_sizes
print("==========layer_sizes==========")
X_asses,Y_asses=layer_sizes_test_case()
(n_x,n_h,n_y)=layer_sizes(X_asses,Y_asses)
print("输入层的节点数量为：n_x="+str(n_x))
print("隐藏层的节点数量为：n_h="+str(n_h))
print("输出层的节点数量为：n_y="+str(n_y))
"""

# In[15]:

# 2.初始化模型的参数
"""
np.random.randn(a,b)*0.01来随机初始化一个维度为（a，b）的矩阵
理解：
W是随机生成了符合高斯分布的数，再*0.01，使得W很小，
为何要随机生成？ 因为如果像b一样全赋0值，就会产生对称性，假如hidden layer有两个由输入值产生的神经元，则由于对称性，无论是正向传播还是反向传播，这两个本应表示不同特征的神经元所做的运算都是一致的，即对称的，not well，所以随机生成了一些数赋值给矩阵W，计算b就不用担心对称性的问题，故直接赋0值
而*0.01使得W很小是因为，可以参照激活函数sigmoid和tanh，当W很大，用W * X+b=a得到的a很大，再用对a用激活函数如sigmoid(a)，由于a很大了，sigmoid(a)中的a会趋向正无穷或负无穷，则函数值sigmoid(a)趋向于一个平缓的趋势，在梯度下降的时候计算的梯度很小，会导致学习的很慢，故使得W取一个很小的值(激活函数图sigmoid,tanh在网上可以很容易找到)。不过在某些情况下不取0.01.会取其他的比较小的值

np.zeros((a,b)) 用零初始化矩阵（a，b）
"""

def initialize_parameters(n_x,n_h,n_y):
    """
    参数：
     n_x - 输入层节点的数量
     n_h - 隐藏层节点的数量
     n_y - 输出层节点的数量
    返回：
    parameters - 包含参数的字典：
    W1-权重矩阵，维度为(n_h,n_x)
    b1-偏向量，维度为(n_h,1)
    w2-权重矩阵，维度为(n_y,n_h)
    b2-偏向量，维度为(n_y,1)

    """
    np.random.seed(2)#指定一个随机种子，以便于你的输出与我们的一样。
    """
    我们在调用random.rand()时，每次产生的数都是随机的。但是，当我们预先
    使用 random.seed(x) 设定好种子之后，其中的 x 可以是任意数字，
    如10，这个时候，先调用它的情况下，使用 random() 生成的随机数将会是同一个。
    """
    W1=np.random.randn(n_h,n_x)*0.01
    b1=np.zeros(shape=(n_h,1))
    W2=np.random.randn(n_y,n_h)*0.01
    b2=np.zeros(shape=(n_y,1))

    #使用断言确保我的数据格式是正确的
    assert(W1.shape==(n_h,n_x))
    assert(b1.shape==(n_h,1))
    assert(W2.shape==(n_y,n_h))
    assert(b2.shape==(n_y,1))

    #用字典储存，这样返回字典，从字典中参数值获取value。就不用返回一大堆了。
    parameters={
        "W1":W1,
        "b1":b1,
        "W2":W2,
        "b2":b2
    }

    return parameters
"""
#测试initialize_parameters
print("==========initialize_parameters==========")
#X_asses,Y_asses=layer_sizes_test_case()
#(n_x,n_h,n_y)=layer_sizes(X_asses,Y_asses)

n_x , n_h , n_y = initialize_parameters_test_case()
parameters = initialize_parameters(n_x , n_h , n_y)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
"""

# In[16]:

# 3.循环：
    # --实施前向传播。
    # 我们可以使用sigmoid()函数，也可以使用np.tanh()函数。
    # 这里我们用np.tanh()函数

def forward_propagation(X,parameters):
    """
    参数：
        X- 维度为（n_x,m）的输入数据 ,因为有m个训练集
        parameters -初始化函数(initialize_parameters)的输出
    返回：
        A2-使用sigmoid（）函数计算的第二次激活后的数值
        cache-包含"Z1","A1","Z2","A2"的字典类型数量

    """
    W1= parameters["W1"]             #注意是[],不是()
    b1= parameters["b1"]
    W2= parameters["W2"]
    b2= parameters["b2"]

    #前向传播计算A2
    Z1=np.dot(W1,X)+b1
    A1=np.tanh(Z1)
    Z2=np.dot(W2,A1)+b2
    A2=sigmoid(Z2)
    #A2=np.tanh(Z2)
    #使用断言确保我的数据格式是正确的
    assert(A2.shape==(1,X.shape[1])) #?????????为什么是X.shape[1]
    #assert(A2.shape==(n_y,1)) #不能用这个，因为n_y不是传入的参数了
    cache={
        "Z1":Z1,
        "A1":A1,
        "Z2":Z2,
        "A2":A2
    }

    return (A2,cache)
"""
#测试forward_propagation
print("==========forward_propagation==========")
X,parameters = forward_propagation_test_case()
A2,cache = forward_propagation(X,parameters)
#求其中一个用A2 =forward_propagation(X,parameters)[0]

print("Z1 = " + str(cache["Z1"]))
print("A1 = " + str(cache["A1"]))
print("Z2 = " + str(cache["Z2"]))
print("A2 = " + str(cache["A2"]))

#numpy.mean(a, axis, dtype, out，keepdims )函数。本次实验选择返回实数的。

axis 不设置值，对 m*n 个数求均值，返回一个实数
axis = 0：压缩行，对各列求均值，返回 1* n 矩阵
axis =1 ：压缩列，对各行求均值，返回 m *1 矩阵
"""
"""
print(np.mean(cache["Z1"]), np.mean(cache["A1"]), np.mean(cache["Z2"]), np.mean(cache["A2"]))
"""

# In[17]:

# 3.循环：
    # --计算损失（损失函数/代价函数）
def compute_cost(A2,Y,parameters):
        """
        参数：
        A2-使用sigmoid（）函数计算的第二次激活后的数值
        Y-“True”标签向量，维度为（1，数量）
        parameters-一个包含W1，b1，W2和b2的字典类型的变量
        返回：
        成本-交叉熵成本给定的方程

        """
        m=Y.shape[1]
        W1=parameters["W1"]
        W2=parameters["W2"]

        #计算成本
        logprobs=np.multiply(np.log(A2),Y)+np.multiply(np.log(1-A2),1-Y)
        cost=-(np.sum(logprobs))/m
        cost=float(np.squeeze(cost))
        #使用断言确保我的数据格式是正确的
        """
        isinstance(object,classinfo)
        Python中的 isinstance() 函数，是Python中的一个内置函数，用来判断一个函数是否是一个已知的类型

        """
        assert(isinstance(cost,float))

        return cost
"""
#测试compute_cost
print("==========compute_cost==========")
A2 , Y_assess , parameters = compute_cost_test_case()
cost = compute_cost(A2 , Y_assess , parameters)
print(str(cost))
"""

# In[18]:

0.6929198937761266

# In[19]:

# 3.循环：
    # --实现向后传播
    #tanh（a）是激活函数，求导后为1-a^2
    #
def backward_propagation(parameters,cache,X,Y):
        """
        使用六个方程来搭建反向传播函数。
        参数：
        parameters-包含W1，W2的字典
        cache-包含Z1，A1，Z2，A2的字典
        X-输入数据，维度为（2，数量）
        Y-“True”标签，维度为（1，数量）

        返回：
        grads-包含W和b的字典
        """
        m=X.shape[1]

        W1=parameters["W1"]
        W2=parameters["W2"]
        A1=cache["A1"]
        A2=cache["A2"]

#np.sum(A, axis = 1, keepdims = True)axis=1 以竖轴为基准 ，同行相加keepdims主要用于保持矩阵的二维特性
        dZ2=A2-Y
        dW2=(1/m)*np.dot(dZ2,A1.T)
        db2=(1/m)*(np.sum(dZ2,axis=1,keepdims=True))
        dZ1=np.dot(W2.T,dZ2)*(1-np.power(A1,2))
        dW1=(1/m)*np.dot(dZ1,X.T)
        db1=(1/m)*(np.sum(dZ1,axis=1,keepdims=True))
        grads={
            "dW2":dW2,
            "db2":db2,
            "dW1":dW1,
            "db1":db1
        }

        return grads
"""
#测试backward_propagation
print("==========backward_propagation==========")
parameters,cache,X,Y= backward_propagation_test_case()
grads = backward_propagation(parameters,cache,X,Y)
print("dW1 = " + str(grads["dW1"]))
print("db1 = " + str(grads["db1"]))
print("dW2 = " + str(grads["dW2"]))
print("db2 = " + str(grads["db2"]))
"""

# In[20]:

# 3.循环：
    # --更新参数（梯度下降）。
def update_parameters(parameters,grads,learning_rate=5.1):
    """
    使用给出的梯度下降更新规则，更新参数
        参数：
        parameters-包含W1，W2的字典
        grads-包含dW1,db1,dW2,db2的字典
        learning_rate-学习速率
        返回：
        parameters-包含更新参数的字典类型的变量。

    """
    W1,W2= parameters["W1"], parameters["W2"]
    b1,b2= parameters["b1"], parameters["b2"]

    dW1 = grads["dW1"]
    db1 = grads["db1"]
    dW2 = grads["dW2"]
    db2 = grads["db2"]
    #使用更新规则方程

    W1=W1-learning_rate*dW1
    b1=b1-learning_rate*db1
    W2=W2-learning_rate*dW2
    b2=b2-learning_rate*db2
    parameters={
        "W1":W1,
        "b1":b1,
        "W2":W2,
        "b2":b2
    }

    return parameters
"""
#测试update_parameters
print("==========backward_propagation==========")
parameters,grads= update_parameters_test_case()
parameters = update_parameters(parameters,grads)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
"""

# In[21]:

# 我们要它们合并到一个nn_model()函数中，当我们构建好了nn_model()并学习了正确的参数，
#我们就可以预测新的数据。
#神经网络模型必须以正确的顺序使用先前的功能
"""
定义的函数
layer_sizes (X,Y)
initialize_parameters (n_x,n_h,n_y)
forward_propagation (X,parameters)
compute_cost(A2,Y,parameters)
backward_propagation(parameters,cache,X,Y)
update_parameters(parameters,grads,learning_rate)
"""
def nn_model(X,Y,n_h,num_iterations = 10000,print_cost=False):
    """
    参数：
    X-数据集，维度为（2，示例数）
    Y-标签，维度为（1，示例数）
    n_h-隐藏层的数量
    num_iterations-梯度下降循环中的迭代次数
    print_cost-如果为True，则每1000次迭代打印一次成本数值(代价函数)
    返回：
    parameters-模型学习的参数，它们可以用来进行预测。
    """

    np.random.seed(3)
    n_x=layer_sizes(X,Y)[0]
    n_y=layer_sizes(X,Y)[2]

    parameters=initialize_parameters(n_x,n_h,n_y)
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]

    for i in range(0,num_iterations):
        A2,cache=forward_propagation(X,parameters)
        cost=compute_cost(A2,Y,parameters)
        grads=backward_propagation(parameters,cache,X,Y)
        parameters=update_parameters(parameters,grads)

        if print_cost and i%1000==0:
                print("第",i,"次循环，成本为: "+str(cost))

    return parameters
"""
#测试nn_model
print("==========nn_model==========")
X,Y= nn_model_test_case()
parameters = nn_model(X,Y,4,num_iterations=10000,print_cost=False)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
"""

# In[33]:

#预测predict()来使用模型进行预测，使用前向传播来预测结果
def predict(parameters,X):
    """
    使用学习的参数，为X中的每个示例预测一个类

    参数：
    parameters-包含参数的字典
    X-输入数据(n_x,m) n_x个特征，m个样本即示例

    返回：
    predictions-我们模型预测的向量(红色：0/蓝色：1)

    """
    A2,cache=forward_propagation(X,parameters)
    #np.round()函数的做用：对给定的数组进行四舍五入。
    #但是需要特别注意的是,当整数部分以0结束时,round函数一律是向下取整。
    predictions=np.round(A2)

    return predictions
"""
#测试perdict
print("==========perdict==========")
parameters,X= predict_test_case()
predictions = predict(parameters,X)
# X以m * n矩阵举例
# np.mean(X) 矩阵中所有元素求均值
# np.mean(X,0) 压缩行，对各列求均值,返回 1* n 矩阵
# np.mean(X,1) 压缩列，对各行求均值,返回 m *1 矩阵
print("预测的平均值= "+str(np.mean(predictions)))
"""

# In[34]:

parameters = nn_model(X, Y, n_h = 4, num_iterations=10000, print_cost=True)
plot_decision_boundary(lambda x: predict(parameters, x.T), X, np.squeeze(Y))
plt.title("Decision Boundary for hidden layer size " + str(4))    #图标题
plt.show()
predictions = predict(parameters, X)     #预测结果
print ('准确率: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')

# In[35]:

#更改隐藏层节点数量
#我们上面的实验把隐藏层定为4个节点，现在我们更改隐藏层里面的节点数量，看一看节点数量是否会对结果造成影响
plt.figure(figsize=(16,32))
hidden_layer_sizes=[1,2,3,4,5,20,50] #隐藏层的数量
#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列
for i,n_h in enumerate(hidden_layer_sizes):
    #位置是由三个整型数值构成,第一个代表行数,第二个代表列数,第三个代表索引位置
    #这个函数用来表示把figure分成nrows*ncols的子图表示， 索引值，表示把图画在第plot_number个位置（从左下角到右上角）
    plt.subplot(5,2,i+1)
    plt.title("Hidden Layer of size %d" % n_h)
    parameters=nn_model(X,Y,n_h,num_iterations=5000)
    plot_decision_boundary(lambda x:predict(parameters,x.T),X,np.squeeze(Y))
    predictions=predict(parameters,X)
    accuracy=float((np.dot(Y,predictions.T)+np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
    print("隐藏层的节点数量：{} ，准确率{} %".format(n_h,accuracy))

# In[36]:

"""
结论：
较大的模型（具有更多隐藏单元）能够更好地适应训练集，直到最终的最大模型过度拟合数据。
最好的隐藏层大小似乎在n_h = 5附近。实际上，这里的值似乎很适合数据，而且不会引起过度拟合。
我们还将在后面学习有关正则化的知识，它允许我们使用非常大的模型（如n_h = 50），而不会出现太多过度拟合。

"""

# In[26]:

##【可选】探索
"""
1. 当改变sigmoid激活或ReLU激活的tanh激活时会发生什么？
2. 改变learning_rate的数值会发生什么
3. 如果我们改变数据集呢？
"""

# In[27]:

#1. 当改变sigmoid激活或ReLU激活的tanh激活时会发生什么？
#1.1 当改变sigmoid激活为tanh激活时：准确率降低为89%
#1.2 当改变sigmoid激活为tanh激活时：

# In[28]:

#2. 改变learning_rate的数值会发生什么（learning_rate为1.2， 90%）
#2.1 learning_rate为0.1  89%
#2.2 learning_rate增大为5.1 也为90%

# In[29]:

#3. 如果我们改变数据集呢？
#逻辑回归正确性为87%
#------------>>>>单隐藏层，隐藏节点数量为4 的决策边界提高为96%
#------------>>>>单隐藏层，隐藏节点数量为20 的决策边界提高为97%

# In[30]:

#知识点
"""
1.tanh激活函数通常比隐藏层单元的sigmoid激活函数效果更好，因为其输出的平均值更接近于零，因此它将数据集中在下一层是更好的选择
2.您正在构建一个识别黄瓜（y = 1）与西瓜（y = 0）的二元分类器。 你会推荐哪一种激活函数用于输出层？
sigmoid函数,因为sigmoid函数的输出值可以很容易地理解为概率。
3.你已经为所有隐藏的单位建立了一个使用tanh激活的网络。使用np.random.randn(…, …)*1000将权重初始化为相对较大的值。会发生什么？
tanh对于较大的值变得平坦，这导致其梯度接近于零。 这减慢了优化算法。这将导致tanh的输入也非常大，从而导致梯度接近于零。因此，优化算法将变得缓慢。

"""

# In[ ]:

# In[ ]:


import torch
from .utils import AverageMeter, get_predictions, calculate_accuracy, prepare_batch
import torchvision

def validate(args, epoch, data_loader, model, criterion, logger, decoder=None):
    print('validation at epoch {}'.format(epoch))
    model.eval()

    video_acc_avg = AverageMeter()

    clip_logits = []
    previous_video_id = None
    previous_video_gt = None
    for i, (inputs, targets) in logger.scope_enumerate(data_loader, epoch, total_time='time/val_epoch',
                                                       fetch_time='time/val_data', body_time='time/val_step'):

        #grid = torchvision.utils.make_grid(inputs['rgb_clip'][0].add(2.).div(4.).clamp(0., 1.))
        #args.writer.add_image('rgb_clip_val', grid, 0)

        video_ids = targets['video']
        batch_size, inputs, labels = prepare_batch(args, inputs, targets)
        with torch.no_grad():
            outputs = model(*inputs)

        # calculate validation loss
        loss = criterion(outputs=outputs.cpu(), targets=labels.cpu(), inputs=inputs)

        # calculate clip and video accuracy
        video_acc = acc = calculate_accuracy(get_predictions(outputs, decoder), labels)

        if decoder is None:
            # calculate video outputs by averaging clip outputs from the same video
            # we cannot do this in CTC mode
            video_outputs = []
            video_labels = []
            for j in range(batch_size):
                if video_ids[j] != previous_video_id and previous_video_id is not None:
                    clip_logits = torch.stack(clip_logits)
                    video_logits = torch.mean(clip_logits, dim=0)
                    video_outputs.append(video_logits)
                    video_labels.append(previous_video_gt)
                    clip_logits = []

                # outputs = BxTxC (ctc) or BxC (non ctc), clip_logits = CLIPxTxC (ctc) or CLIPxC (non ctc)
                clip_logits.append(outputs[j].data.cpu())
                previous_video_id = video_ids[j]
                previous_video_gt = labels[j].cpu()

            if video_outputs:
                video_outputs = torch.stack(video_outputs)
                video_labels = torch.stack(video_labels)
                video_acc = calculate_accuracy(get_predictions(video_outputs), video_labels)

        video_acc_avg.update(video_acc)

        logger.log_value("val/loss", loss.item(), batch_size)
        logger.log_value("val/acc", acc, batch_size)
        logger.log_value("val/video", video_acc_avg.avg)

    return logger.get_value("val/acc")


##############
# Logic layer
##############

import numpy as np
import pandas as pd
import json
import glob
import os
import logging

# sort of print
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# dealing with data computation

class PandasDataModel:

	def readDataset(self, path_confirmed, path_deaths, path_recovered):
		self.confirmed = pd.read_csv(path_confirmed, error_bad_lines=False)
		self.deaths = pd.read_csv(path_deaths, error_bad_lines=False)
		self.recovered = pd.read_csv(path_recovered, error_bad_lines=False)

	def writeDataset(self, path_confirmed, path_deaths, path_recovered):
		self.confirmed.to_csv(path_confirmed, index=False)
		self.confirmed.to_csv(path_deaths, index=False)
		self.confirmed.to_csv(path_recovered, index=False)

	def __init__(self, path_confirmed, path_deaths, path_recovered):

		logger.info("Starting up Data Model...")
		self.readDataset(path_confirmed, path_deaths, path_recovered)
		#logger.info(self.confirmed, self.deaths, self.recovered)
		self.dfconfirmed = self.confirmed.drop(['Province/State', 'Lat', 'Long'], axis=1).groupby('Country/Region').sum()
		self.dfdeaths = self.deaths.drop(['Province/State', 'Lat', 'Long'], axis=1).groupby('Country/Region').sum()
		self.dfrecovered = self.recovered.drop(['Province/State', 'Lat', 'Long'], axis=1).groupby('Country/Region').sum()
		#logger.info(list(self.dfconfirmed.columns), list(self.dfdeaths.columns), list(self.dfrecovered.columns))
		#logger.info(list(self.dfconfirmed.index), list(self.dfdeaths.index), list(self.dfrecovered.index))

		#{'row1': {'col1': 1, 'col2': 0.5}, 'row2': {'col1': 2, 'col2': 0.75} ...}
		self.confirmed_dict = self.dfconfirmed.to_dict(orient='index')
		self.death_dict = self.dfconfirmed.to_dict(orient='index')
		self.recovered_dict = self.dfconfirmed.to_dict(orient='index')

		self.confirmed_json = self.dfconfirmed.to_json()

		# My Code

		self.my_confirmed = self.dfconfirmed.pivot_table(index='Country/Region',aggfunc=sum).T
		self.my_deaths = self.dfdeaths.pivot_table(index='Country/Region',aggfunc=sum).T
		self.my_recovered = self.dfrecovered.pivot_table(index='Country/Region',aggfunc=sum).T
		self.confirmed_pt = self.my_confirmed['Portugal']
		self.deaths_pt = self.my_deaths['Portugal']
		self.recovered_pt = self.my_recovered['Portugal']
		self.confirmed_pt = pd.DataFrame(self.confirmed_pt)
		self.deaths_pt = pd.DataFrame(self.deaths_pt)
		self.recovered_pt = pd.DataFrame(self.recovered_pt)
		self.confirmed_pt = self.confirmed_pt.rename({'Portugal':'Confirmed'}, axis=1)
		self.deaths_pt = self.deaths_pt.rename({'Portugal':'Deaths'}, axis=1)
		self.recovered_pt = self.recovered_pt.rename({'Portugal':'Recovered'}, axis=1)
		self.result_pt = pd.concat([self.confirmed_pt, self.deaths_pt, self.recovered_pt], axis=1, join='outer')
		self.result_pt = self.result_pt.reset_index()
		self.result_dict = self.result_pt.to_dict(orient='index')
		self.list_pt = [ v for v in self.result_dict.values() ]

		# End My Code

		logger.info("Data Model built.")

	def getConfirmedListings(self):
    		return json.dumps(self.confirmed_dict, indent=2)

	def getDeathListings(self):
    		return json.dumps(self.death_dict, indent=2)

	def getRecoveredistings(self):
    		return json.dumps(self.recovered_dict, indent=2)

	def getCountryListining(self):
			return self.list_pt


import csv
import json

file = 'output/analysis.csv'
json_file = 'data/merged_results.json'

#Read CSV File
def read_CSV(file, json_file):
    csv_rows = []
    with open(file) as csvfile:
        reader = csv.DictReader(csvfile)
        field = reader.fieldnames
        for row in reader:
            csv_rows.extend([{field[i]:row[field[i]] for i in range(len(field))}])
            convert_write_json(csv_rows, json_file)

#Convert csv data into json and format it to make it human readable
def convert_write_json(data, json_file):
    with open(json_file, "w") as f:
        f.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': ')))

read_CSV(file,json_file)


import random

rollcounts=[]
percents=[]
totalrolls=-1

def rolldice(totalrolls=1,minval=1,maxval=6):
    rollcounts=[0]*(maxval-minval+1)
    for i in range(totalrolls):
        roll=random.randint(minval,maxval)
        rollindex=roll-minval
        rollcounts[rollindex]+=1
    return rollcounts

def calculatepercents(rollcounts,totalrolls):
    percents=[]
    for i in range(len(rollcounts)):
        percent=round(100*rollcounts[i]/totalrolls,3)
        percents.append(percent)
    return percents

def displayresults(rollcounts,percents,totalrolls,minval,maxval):
    if(totalrolls>1):
        print("Results from rolling a dice with sides from",minval,"to",maxval,"a total of",totalrolls,"times")
    else:
        print("Results from rolling a dice with sides from",minval,"to",maxval,"a total of",totalrolls,"time")

    for i in range(len(percents)):
        val=i+minval
        print(val," ",rollcounts[i]," ",percents[i],"%",sep="")

def handle_int_input(message,defaultvalue):
    val=input(message)
    if(val!="" and val.isdigit):
        val=int(val)
    else:
        val=defaultvalue
    return val

done=False
while (not done):
    totalrolls=handle_int_input("Enter the total number of rolls (default is 1): ",1)
    minval=handle_int_input("Enter the minimum value (default is 1): ",1)
    maxval=handle_int_input("Enter the maximum value (default is 6): ",6)

    rollcounts=rolldice(totalrolls,minval,maxval)
    percents=calculatepercents(rollcounts,totalrolls)
    displayresults(rollcounts,percents,totalrolls,minval,maxval)


class Node:
	def __init__(self,data):
		self.data = data
		self.next = None

class LinkList:
	def __init__(self):
		self.head = None
		self.size=0
		self.tail=None

	def denote_head(self):
		Ghead=self.head

	def insert_first(self,data):
		node = Node(data)
		if self.head==None:
			self.head = node
			self.tail=node
		else:
			node.next=self.head
			self.head = node
		self.size+=1

	def print_all(self):
		temp=self.head
		while temp!=None:
			print(temp.data)
			temp=temp.next

	def insert_last(self,data):
		node=Node(data)
		if self.tail==None:
			self.tail=node
		else:
			self.tail.next=node
		self.size+=1

	def delete_first(self):
		self.head=self.head.next
		self.size-=1

	def delete_last(self):
		temp=self.head
		for i in range(self.size):
			if i==self.size-2:
				temp.next=None
				self.size-=1
			else:
				temp=temp.next

	def size1(self):
		return self.size;

ll=LinkList()
ll.insert_first(1)
ll.insert_first(2)
ll.insert_first(3)
ll.insert_last(0)
ll.delete_last()
#ll.delete_first()
ll.print_all()
print("size is :",ll.size1())


from os.path import isfile

def write_stats(data):

	# takes the list() and writes it

	# show ranking

	with open("statistics.txt", "w+") as f:
		for s in data:
			name = s[0]
			name = name.replace(" ","|")
			line =  name + " " + str(s[1]) + "\n"
			f.write(line)

def sort(arr):

	for i in range(len(arr)-1, 0, -1):
		for x in range(i):
			if int(arr[x][1]) < int(arr[x+1][1]):
				temp = arr[x+1]
				arr[x+1] = arr[x]
				arr[x] = temp
	return arr

def process_stats(stat):

	"""Returns names and scores correctly with spaces"""

	data = []

	data.append(stat) # new score

	if isfile("statistics.txt"): # if there is, read from it and if not, skip and make the file
		with open("statistics.txt", "r") as f:
			raw_data = f.readlines()
			for i in raw_data:
				i = i.replace("\n", "")
				score = i.split(" ")
				score = score[0].replace("|", " "), score[1]
				data.append(score)

	data = sort(data)

	if len(data) > 10: data.pop()

	#print data

	return data

#stat = ("BENIS", 1)
#dat = process_stats(stat)
#write_stats(dat)

# it takes list of 10 or so positions and manages it
# separate names with | <- save

# 1. if isfile:
# 1. a)
#      read rankings
# 1. b) compare rankings to new score
# 1. c) update if needed
# 1. d) save rankings
# 2. else:
# 2. a) create file
# 2. b) settle new score
# 2. c) save rankings

# after setting the new record, show records


import cv2
import numpy as np
import imageio

# choose codec according to format needed
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video = cv2.VideoWriter('pacman_final_seed42_5.avi', fourcc, 8, (192, 248))

imglst = []
for i in range(0, 210):
    img = cv2.imread("pacman_results/maze_"+str(i) + '.png')
    imglst.append(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    video.write(img)

cv2.destroyAllWindows()
video.release()

imageio.mimsave('video5.gif', imglst, fps=8)


#!/usr/bin/env python
# -*- coding:utf-8 -*-
menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车站': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}

menu_list = [menu]
print("输入相应的[地点]进入下一级菜单,[back]返回上一级菜单,[exit]退出菜单")
while True:

    cur_menu = menu_list[-1]
    if len(menu_list) > 1:
        pri_menu = menu_list[-2]
    else:
        pri_menu = menu_list[-1]

    print("=====\n" + "\n".join(cur_menu.keys()) + "\n=====")
    user_input = input("[输入]:")
    if user_input in cur_menu.keys():
        menu_list.append(cur_menu[user_input])
    elif user_input == "back":
        if len(menu_list) > 1:
            menu_list.remove(cur_menu)
    elif user_input == "exit":
        print("退出菜单")
        break
    else:
        print("您的输入有误，请重新输入")

01开发基础/第二章-数据类型-字符编码-文件操作/课后作业/01Menu.py


import pandas as pd

df = pd.read_csv('../core/output/batters.csv')
df = df[['retroID', 'pos_1B', 'pos_2B', 'pos_3B',
         'pos_C', 'pos_OF', 'pos_P', 'pos_SS']]
df.set_index('retroID', inplace=True)
df = df[df == 1].stack().reset_index().drop(0, 1)
df.rename(columns={'level_1': 'POS'}, inplace=True)
df['POS'] = df['POS'].apply(lambda pos: pos[4:])
pos_dict = df.set_index('retroID').to_dict()['POS']

def get_pos(retroId):
    return pos_dict[retroId] or 'U'


from termcolor import colored
import copy

def eventPrint(operations, alg):
    print("{} edit distance actions are listed below:".format(alg))
    print("Total action count = {}\n".format(len(operations)))

    for op in operations:
        print("\t- {}".format(op))
    print()

def backtrack(alg, dataMatrix, dim1, dim2, word1, word2, result):

    ops = [] # Events which are either an insertion, a deletion, a substitution, or a replacement.
    pathMatrix = copy.deepcopy(dataMatrix) # To store the colored path, I've hold a path matrix.
    currentPoint = dataMatrix[dim1][dim2]
    cLat, cLon = dim1, dim2 # cLat and cLon are currentLatitude and currentLongitude
    while True:
        if cLat == 0 and cLon == 0: # Exit condition
            pathMatrix[cLat][cLon] = colored(dataMatrix[0][0], "cyan", attrs=["bold"])
            break
        if cLat > 0 and cLon > 0:
            diag = dataMatrix[cLat-1][cLon-1] # Diagonal value of current position
            insertion = dataMatrix[cLat][cLon-1] # Upper value of current position
            deletion = dataMatrix[cLat-1][cLon] # Left value of current position
            # If algorithm is Damerau-Levenshtein, "substitution" event can happen.
            if alg == "Damerau-Levenshtein":
                # check for primary conditions
                if dataMatrix[cLat - 2][cLon - 2] < min(diag, insertion, deletion):
                    # check for remaining conditions
                    # word1[cLat - 1] != word2[cLon - 1] and
                    # word1[cLat - 1] == word2[cLon - 2] and
                    # word1[cLat - 2] == word2[cLon - 1] is
                    # a condition for subsequent unique two
                    # characters that occurs at a reversed
                    # pattern at each word. e.g. "ab" and "ba"
                    if cLat > 2 and cLon > 2 and word1[cLat - 1] != word2[cLon - 1] and word1[cLat - 1] == word2[cLon - 2] and word1[cLat - 2] == word2[cLon - 1]:
                        ops.append("substitution between {} and {}".format(colored(word1[cLat-1], "red", attrs=["bold"]), colored(word2[cLon-1], "red", attrs=["bold"])))
                        pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"]) # setting the path as colored
                        pathMatrix[cLat-1][cLon-1] = colored(dataMatrix[cLat-1][cLon-1], "cyan", attrs=["bold"]) # setting the path as colored
                        currentPoint = dataMatrix[cLat - 2][cLon - 2] # setting new position with new latitude and longitude
                        cLat, cLon = cLat - 2, cLon - 2 # setting new latitude and longitude
                        continue
            # it checks the replacement
            # first since it brings the
            # current position more
            # closer than the other two
            # events.
            if diag < currentPoint:
                ops.append("replacement of {} with {}".format(colored(word1[cLat-1], "red", attrs=["bold"]), colored(word2[cLon-1], "red", attrs=["bold"])))
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                currentPoint = diag # setting the new value
                cLat, cLon = cLat-1, cLon-1 # setting the new position
                continue
            # if replacement isn't valid,
            # it checks insertion and deletion
            # subsequently.
            if insertion < currentPoint:
                ops.append("insertion of {}".format(colored(word2[cLon-1], "red", attrs=["bold"])))
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                currentPoint = insertion # setting the new value
                cLat, cLon = cLat, cLon - 1 # setting the new position
                continue
            # check for deletion operation
            if deletion < currentPoint:
                ops.append("deletion of {}".format(colored(word1[cLat-1], "red", attrs=["bold"])))
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                currentPoint = deletion # setting the new value
                cLat, cLon = cLat - 1, cLon # setting the new position
                continue
            # if all operations are invalid,
            # it checks for equality option
            # where at this position, both words
            # have the same letter. If so, it
            # continues from the diagonal,
            # but no operations are done since
            # it is meaningless to apply cost on
            # an operation where character ¶
            # turns into character ¶.
            if diag == currentPoint:
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                cLat, cLon = cLat - 1, cLon -1 # setting the new position
                continue
        else:
            # if the algorithm reaches out the borders
            # these control statements are designed to
            # direct the position to the final position of
            # the algorithm, which is the starting point of
            # the edit distance table, [0,0]
            if cLat == 0:
                # if latitude is 0, it means no character
                # to insert, thus only deletion is available.
                ops.append("insertion of {}".format(colored(word2[cLon-1], "red", attrs=["bold"])))
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                cLon = cLon - 1 # setting the new longitude
            else:
                # if latitude is not 0, it means longitude is 0
                # since the code doesn't enter the exit condition block
                # and it can only be a insertion operation.
                ops.append("deletion of {}".format(colored(word1[cLat-1], "red", attrs=["bold"])))
                pathMatrix[cLat][cLon] = colored(dataMatrix[cLat][cLon], "cyan", attrs=["bold"])
                cLat = cLat - 1 # setting the new latitude

    # printing the output of the task
    print("{} edit distance between {} and {} = {}\n".format(
        colored(alg, "yellow", attrs=["bold"]),
        colored(word1, "green", attrs=["reverse"]),
        colored(word2, "green", attrs=["reverse"]),
        colored(result, "red", attrs=["bold"])
    ))

    # since backtracking stores the events in a reversed manner,
    # a reversal of the eventlist would be the corrent sequence of events.
    ops.reverse()
    # printing the events
    eventPrint(ops, alg)

    print("The {} Edit Distance Table:\n".format(colored(alg, "red", attrs=["bold"])))

    # visually enhanced edit distance table is printed here.
    maxDim = len(str(dim1 * dim2))
    for lat in range(dim1):
        for lon in range(dim2):
            # calculates the length of
            # the greatest integer in
            # the table and organizes
            # the table based on that information.
            print(pathMatrix[lat+1][lon+1], end=" "*(maxDim - len(str(dataMatrix[lat][lon]))))
        print()
    print()


import argparse
import aioprocessing
import importlib
import json
import multiprocessing as multiproc
import re
from config import LOG_PATH
from datetime import datetime
from distutils.util import strtobool
from os.path import exists

SCENARIO_NAMES = {
    'Basic Scenario': 3,
    'Basic Authority Scenario': 3,
    'Basic Topic Scenario': 3
}

class Evaluator:
    def run(self):
        self.connector.start()
        if self.lock_mode == "lock":
            self.send_queue.put({'type': 'lock_webUI'})
            received_message = self.receive_pipe.recv()
        elif self.lock_mode == "unlock":
            self.send_queue.put({'type': 'unlock_webUI'})
            received_message = self.receive_pipe.recv()
        else:
            scenario_run_ids = []
            for scenario, raps in SCENARIO_NAMES.items():
                for i in range(0, raps):
                    print(f"Starting scenario '{scenario}' run {i+1}...")
                    run_message = {
                        'type': 'run_scenario',
                        'scenario': {'name': scenario},
                        'is_evaluator': True
                    }
                    self.send_queue.put(run_message)
                    received_message = self.receive_pipe.recv()
                    if received_message['type'] == 'scenario_run_id':
                        print(f"Got run id for '{scenario}' run {i+1}: {received_message['scenario_run_id']}")
                    else:
                        raise RuntimeError(f"Did not receive scenario run ID after starting scenario '{scenario}' "
                                           f"run {i+1}")
                    received_message = self.receive_pipe.recv()
                    if received_message['type'] == 'scenario_results':
                        receiving_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
                        print(f"Scenario '{scenario}' run {i+1} finished as '{received_message['scenario_run_id']}' "
                              f"at {receiving_time} executed under {received_message['supervisor_amount']} "
                              f"supervisors.\n\n")
                        if self.print_to_file:
                            json_path = LOG_PATH / 'evaluator_log.json'
                            with open(json_path, 'r+' if exists(json_path) else 'w+') as json_file:
                                try:
                                    data = json.load(json_file)
                                except json.decoder.JSONDecodeError:
                                    data = {}
                                json_file.seek(0)
                                data[received_message['scenario_run_id']] = {
                                    'datetime': receiving_time,
                                    'scenario': scenario,
                                    'run': i+1,
                                    'supervisor_amount': received_message['supervisor_amount']}
                                print(json.dumps(data, indent=4), file=json_file)
        exit_message = {
            'type': 'end_socket'
        }
        self.send_queue.put(exit_message)

    def __init__(self, director_hostname, connector, logger_str, sec_conn=False, lock_mode='', print_to_file=False):
        self.director_hostname = director_hostname
        self.logger_str = logger_str
        self.lock_mode = lock_mode
        self.print_to_file = print_to_file
        # setup multiprocessing environment
        self.send_queue = aioprocessing.AioQueue()
        self.manager = multiproc.Manager()
        self.pipe_dict = self.manager.dict()
        self.receive_pipe, self.pipe_dict["evaluator"] = aioprocessing.AioPipe(False)
        # get correct connector to director
        module = importlib.import_module("connectors." + re.sub("([A-Z])", "_\g<1>", connector).lower()[1:])
        connector_class = getattr(module, connector)
        self.connector = connector_class(director_hostname, 0, self.send_queue, self.pipe_dict, sec_conn,
                                         no_registration=True if lock_mode else False)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("-c", "--connector", default="ChannelsConnector", choices=['ChannelsConnector'],
                        help="The connector class to use for connecting to director.")
    parser.add_argument("-d", "--director", default="127.0.0.1:8000",
                        help="The hostname of the director, where the evaluation script shall register at.")
    parser.add_argument("-log", "--logger", default="FileLogger", choices=['FileLogger'],
                        help="The logger class to use for logging trust values during a scenario run.")
    parser.add_argument("-wss", "--sec-socket", type=lambda x: bool(strtobool(x)), nargs='?', const=True,
                        default=False, help="Whether to use a secure websocket connection to the director.")
    parser.add_argument("-L", "--lock_mode", default="", choices=['lock', 'unlock'],
                        help="Changes the evaluator script to only lock or unlock the webUI.")
    parser.add_argument("-p", "--print", type=lambda x: bool(strtobool(x)), nargs='?', const=True,
                        default=False, help="Whether the evaluator prints log information to a file.")
    args = parser.parse_args()
    # set multiprocessing start method
    multiproc.set_start_method('spawn')
    # init supervisor as class and execute
    evaluator = Evaluator(args.director, args.connector, args.logger, args.sec_socket, args.lock_mode, args.print)
    evaluator.run()


from typing import List
def missing_number_using_xor(input: List[int]) -> int:
    sequence = list(range(1, len(input)+1))
    result = 0
    for number in input:
        result ^= number
    for number in sequence:
        result ^= number
    return result

def missing_number_using_sum(input: List[int]) -> int:
    sequence = list(range(1, len(input)+1))
    sum_of_inputs = sum(input)
    sum_of_sequence = sum(sequence)
    return sum_of_sequence - sum_of_inputs


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Oct  1 11:41:04 2019

@author: mlees
"""

import sys
sys.path.append('/Users/mlees/Documents/RESEARCH/InSAR_processing/postprocessing_scripts')
sys.path.append('/home/mlees/InSAR_processing/postprocessing_scripts')

from InSAR_postSBAS import *
import seaborn as sns

stationslist = np.loadtxt('drummer1_repo/GPS_stations_CV_and_Sierras.txt',dtype='str')

plt.ioff()
plt.figure(figsize=(18,12))
sns.set_context('talk')

gpsstations = import_GPS_stations()

import simplekml
kml = simplekml.Kml()

# Do UNAVCO stations
for stn in stationslist:
    plot_individual_gps_station_vertical(stn,update=0)
    plt.savefig('GPSPLOTS/%s.jpg' % stn)
    plt.cla()
    logical=gpsstations['# ID']==stn

    kml.newpoint(name="%s" % stn,coords=[(gpsstations['Longitude'][logical].values[0],gpsstations['Latitude'][logical].values[0])],description='' % stn )

newstationslist = ['CAHA','CAWO','LIND','CRCN','LEMA','HELB','DONO','RAPT']

newstations = pd.read_csv('South_Central_valley_stations.csv')
#%%
# Do NGL stations
for stn in newstationslist:
    plot_individual_gps_station_vertical(stn,sln_type='ngl',update=0)
    plt.savefig('GPSPLOTS/%s_ngl.jpg' % stn)
    plt.cla()
    idx = np.argwhere(np.isin(newstations['Station_Name'],stn))[0]

    kml.newpoint(name="%s_ngl" % stn,coords=[(newstations['Lon'][idx].values[0],newstations['Lat'][idx].values[0])],description='' % stn )

kml.save("CentralValleyplus_Sierra_GPS_timeseries_NEW.kml")

cmd ='/Applications/MATLAB_R2018b.app/bin/matlab -nosplash -nodesktop -nodisplay -r "GIS_kml2kmz(\'CentralValleyplus_Sierra_GPS_timeseries_NEW.kml\')"'
cmd ='matlab -nosplash -nodesktop -nodisplay -r "GIS_kml2kmz(\'CentralValleyplus_Sierra_GPS_timeseries_NEW.kml\')"'
print('Converting kml to kmz using MATLAB script..this might not work..')
print(cmd)
os.system(cmd)


from poseModel.Node import Node
from poseModel.Person import Person
from poseModel.Pose import Pose
from utils.Comparator import Comparator

file = open("/data/data.txt", 'r')
output = []
output = open("/data/output.txt", 'w')
person = []
comparator = Comparator()

def existPerson(pose):
    if len(person) == 0:
        return False
    else:
        for p in person:
            if comparator.isPoseBelongsPerson(pose, p):
                return p
        return False

for line in file:
    line.replace("\n", "")
    numbers = line.split(" ")
    for i in range(1, len(numbers), 54):
        pose = Pose()
        count = 0
        for j in range(i, i + 54, 3):
            if j + 2 > len(numbers)-1:
                break
            print(count, numbers[j], numbers[j+1], numbers[j+2])
            pose.addNode(Node(count, float(numbers[j]), float(numbers[j+1]), float(numbers[j+2])))
            count += 1
        if pose.getAveConfidence() >= 0.4:
            if existPerson(pose) != False:
                existPerson(pose).addPose(pose)
            else:
                newPerson = Person()
                newPerson.addPose(pose)
                person.append(newPerson)
for i in range(len(person)):
    output.write(str(i) + "\n")
    person[i].outputPerson(output)
file.close()
output.close()


from django.urls import  URLPattern, path
from .views import actor_home,actor_details,actor_delete,actor_create,actor_update
app_name='actor'

urlpatterns=[
   path('home/',actor_home,name='home'),
   path('details/<int:id>',actor_details,name='details'),
   path('delete/<int:id>',actor_delete,name='delete'),
   path('create/',actor_create,name='create'),
   path('update/<int:id>',actor_update,name='update'),

]