import tcod
import random
import copy
import constants as const
import entity
import render
import numpy as np
import random_loot as rloot

class Room:
    """
    A room! Wow.
    """
    def __init__(self, x, y, w, h):
        self.x = x # upper left point
        self.y = y # upper left point
        self.w = w
        self.h = h
        self.n_loot = 0
        self.neighbors = []

class GameMap:
    def __init__(self, width, height, con, show_map=False):
        self.sample = None
        self.width = width
        self.con = con
        self.height = height
        self.tcod_empty_map = tcod.map.Map(self.width, self.height)
        self.show_map = show_map
        for x in range(self.width):
            for y in range(self.height):
                self.tcod_empty_map.transparent[y,x] = True
                self.tcod_empty_map.walkable[y,x] = True

    def get_sample(self):
        """
        Used to color the walls and the floor
        """
        ogrid = [np.arange(self.width, dtype=np.float32), np.arange(self.height, dtype=np.float32)]

        noise = tcod.noise.Noise(
            dimensions=2,
            algorithm=tcod.NOISE_PERLIN,
            implementation=tcod.noise.TURBULENCE,
            hurst=0.9,
            lacunarity=1.6,
            octaves=5)
        min_lum = 0.5
        max_lum = 1
        self.sample = noise.sample_ogrid(ogrid)*(max_lum-min_lum) + min_lum

    def add_loot(self, turns, player, entities):
        """
        Add loot to a new level
        """
        n_slot = {}
        for fslot in const.FeatureSlot:
            # 2d4 features of each slot
            n_slot[fslot] = sum([random.randint(1,4) for i in range(2)])
        for wslot in const.WeaponSlot:
            # 1d4 weapons of each slot
            n_slot[wslot] = sum([random.randint(1,4) for i in range(1)])

        for slot in n_slot:
            n_generated = n_slot.get(slot)
            for n in range(n_generated):
                n_try = 50
                while n_try > 0:
                    n_try -= 1
                    # loot is more probable in room with low arity
                    arity = random.choice([1,1,1,2,2,3,4,5])
                    rlist = [r for r in self.rooms_with_arity(arity) if r.n_loot < const.max_item_per_room]
                    if rlist:
                        room = random.choice(rlist)
                        (x,y) = self.random_cell_in_room(room)
                        if not self.tiles[x][y].item:
                            room.n_loot += 1
                            self.tiles[x][y].put_item(rloot.get_random_loot(slot, turns, player), entities)
                            break

    def rooms_with_arity(self, max_arity):
        """
        Return the list of room with at most max_arity neighbors
        """
        return [r for r in self.room_list if len(r.neighbors) <= max_arity]

    def make_boss_map(self, turns, entities, player):
        """
        An arena
        """
        self.get_sample()
        self.tiles = [[entity.Tile(x,y,color_coeff=self.sample[x][y]) for y in range(self.height)] for x in range(self.width)]
        self.tcod_map = tcod.map.Map(self.width, self.height)
        center_x = self.width / 2
        center_y = self.height / 2
        a = 30
        b = 15
        self.room_list = [Room(int(center_x - a), int(center_y - b), 2*a, 2*b)]
        for x in range(self.width):
            for y in range(self.height):
                if ((x - center_x)/a)**2 + ((y - center_y)/b)**2 <= 1: # ellipse equation
                    self.set_unblocked(x, y)
        (player.x, player.y) = (int(center_x / 2), int(center_y))
        boss = entity.Boss(int(center_x * 1.5), int(center_y))
        entities.append(boss)
        turns.add_turn(boss.speed_mov, const.TurnType.ENEMY, boss)
        self.recompute_fov(player.x, player.y)
        return boss

    def make_map_bsp(self, turns, entities, player):
        self.get_sample()
        self.tiles = [[entity.Tile(x,y,color_coeff=self.sample[x][y]) for y in range(self.height)] for x in range(self.width)]
        self.room_list = None
        self.tcod_map = tcod.map.Map(self.width, self.height)
        map_width = self.width
        map_height = self.height
        if self.show_map:
            for x in range(map_width):
                for y in range(map_height):
                    self.tiles[x][y].is_seen = True
        # we garantee a wall on the north and the west
        # this is necessary due to the generation the room
        bsp = tcod.bsp.BSP(1,1,map_width-1, map_height-1)
        bsp.split_recursive(6,6,6,1,1)
        self.room_list = self.recursive_make_rooms(bsp)

        # After the BSP generation, the dungeon is a tree
        # Create some loops
        rlist = self.rooms_with_arity(2)
        for i in range(6):
            for j in range(10):
                c = random.choice(range(len(rlist)))
                best = self.closest_rooms([rlist[c]], self.room_list)
                if best:
                    astar = tcod.path.AStar(self.tcod_map)
                    score_tuple = None
                    best_tuple = []
                    for tuple_param in best:
                        (x1, y1, x2, y2, _, _) = tuple_param
                        path = astar.get_path(x1, y1, x2, y2)
                        tmp_score = int(len(path)/3)
                        if not score_tuple or tmp_score > score_tuple:
                            score_tuple = tmp_score
                            best_tuple = [tuple_param]
                        elif tmp_score == score_tuple:
                            best_tuple.append(tuple_param)
                    self.connect_rooms(random.choice(best_tuple))
                    del rlist[c]
                    break

        # Initialization
        (player.x, player.y) = self.random_cell()
        (x, y) = self.random_cell()
        self.place_stairs(x,y)

        (x, y) = self.random_cell()
        self.place_boss_stairs(x,y)
        # self.place_boss_stairs(player.x,player.y) # DEBUG
        self.add_loot(turns, player, entities)
        self.recompute_fov(player.x, player.y)

    def recompute_fov(self, x, y, light_walls=True, radius=0):
        self.tcod_map.compute_fov(x, y, algorithm=2, radius=radius, light_walls=light_walls)

    def is_visible(self, x, y):
        return self.tcod_map.fov[y,x]

    def spawn_boss(self, entities, fslot, level, player):
        for i in range(50):
            (x,y) = self.random_cell()
            if not any([entity for entity in entities if entity.x == x and entity.y == y]):
                if (fslot == const.FeatureSlot.i and level >= 3) or (fslot != const.FeatureSlot.i and level >= 2):
                    class_name = fslot.value.get("bug_class")
                    the_class = getattr(entity, class_name)
                    monster = the_class(x, y, level, player.fequiped.get(fslot), fslot)
                else:
                    monster = entity.Monster(x, y, level, None, fslot)
                entities.append(monster)
                return monster
        return None

    def spawn(self, entities, feature):
        # We try at most 50 times to spawn it
        for i in range(50):
            (x,y) = self.random_cell()
            if not self.is_visible(x,y) and not any([entity for entity in entities if entity.x == x and entity.y == y]):
                level = random.randint(1, 3)
                if feature.n_bugs[level - 1] < const.n_bugs_max[feature.level - 1][level - 1]:
                    # mapgen bug are OP. Give their abitity to level 3 bug only
                    if (feature.fslot == const.FeatureSlot.i and level >= 3) or (feature.fslot != const.FeatureSlot.i and level >= 2):
                        class_name = feature.fslot.value.get("bug_class")
                        the_class = getattr(entity, class_name)
                        monster = the_class(x, y, level, feature)
                    else:
                        monster = entity.Monster(x, y, level, feature)
                    entities.append(monster)
                    return monster
        return None

    def iterator_perimeter_room(self, r):
        for x in range(r.x, r.x + r.w):
            yield (x, r.y)
            yield (x, r.y + r.h - 1)
        # y has a shorter range because the corners are already yielded
        for y in range(r.y + 1, r.y + r.h - 1):
            yield (r.x, y)
            yield (r.x + r.w - 1, y)

    def closest_rooms(self, l1, l2):
        best = []
        score_best = None
        for r1 in l1:
            for r2 in l2:
                if r1 != r2 and r1 not in r2.neighbors:
                    for (x1, y1) in self.iterator_perimeter_room(r1):
                        for (x2, y2) in self.iterator_perimeter_room(r2):
                            dx = abs(x1-x2)
                            dy = abs(y1-y2)
                            # This is not a hack. It is… hand-crafted mapgen
#                            if dx >= 4 and dy >= 4:
#                                score = max(abs(x1-x2),abs(y1-y2)) # Chebyshev distance
#                            else:
                            score = abs(x1-x2) + abs(y1-y2) # Manhattan distance
                            if score_best == None or score < score_best:
                                score_best = score
                                best = [(x1,y1,x2,y2,r1,r2)]
                            elif score == score_best:
                                best.append((x1,y1,x2,y2,r1,r2))
        return best

    def random_cell(self):
        return self.random_cell_in_room(random.choice(self.room_list))

    def random_cell_in_room(self, r):
        while True:
            x = random.randrange(r.x, r.x + r.w)
            y = random.randrange(r.y, r.y + r.h)
            if self.is_floor(x,y):
                return (x,y)

    def recursive_make_rooms(self, bsp):
        if not bsp.children:
            w = random.randrange(max(3,int(bsp.w/3)),bsp.w-2)
            h = random.randrange(max(3,int(bsp.h/3)),bsp.h-2)
            upper_left_x = random.randrange(bsp.x, bsp.x + bsp.w - w)
            upper_left_y = random.randrange(bsp.y, bsp.y + bsp.h - h)

            for x in range(0,w):
                for y in range(0,h):
                    self.set_unblocked(upper_left_x + x, upper_left_y + y)

            # Sometimes, add a central pillar
            if (w % 2) == 1 and (h % 2) == 1:
                if random.randrange(0,10) == 0:
                    center_x = upper_left_x + int((w-1)/2)
                    center_y = upper_left_y + int((h-1)/2)
                    self.set_blocked(center_x, center_y)

            # And rarely a big one (rare because big rooms aren't common)
            if (w % 2) == 0 and (h % 2) == 0 and w >= 10 and h >= 10 and random.randrange(0,2) == 0:
                center_x = upper_left_x + int(w/2) - 1
                center_y = upper_left_y + int(h/2) - 1
                for x in range(0,2):
                    for y in range(0,2):
                        self.set_blocked(center_x + x, center_y + y)

            return [Room(upper_left_x, upper_left_y, w, h)]

        else:
            l1 = self.recursive_make_rooms(bsp.children[0])
            l2 = self.recursive_make_rooms(bsp.children[1])
            # it is garanteed to connect
            self.connect_rooms(random.choice(self.closest_rooms(l1,l2)))
            return l1+l2

    def connect_rooms(self, tuple_param, force=False):
        (x1, y1, x2, y2, r1, r2) = tuple_param
        r1.neighbors.append(r2)
        r2.neighbors.append(r1)
        door_chance = 4
        if x1 == x2:
            if y1 > y2:
                y1 -= 1
                y2 += 1
            else:
                y1 += 1
                y2 -= 1
            self.create_v_tunnel(y1, y2, x1)
            if random.randint(0,door_chance) == 0:
                self.place_door(x1, y1)
            elif random.randint(0,door_chance) == 0:
                self.place_door(x2, y2)
        elif y1 == y2:
            if x1 > x2:
                x1 -= 1
                x2 += 1
            else:
                x1 += 1
                x2 -= 1
            self.create_h_tunnel(x1, x2, y1)
            if random.randint(0,door_chance) == 0:
                self.place_door(x1, y1)
            elif random.randint(0,door_chance) == 0:
                self.place_door(x2, y2)
#        elif abs(x1-x2) < 3 or abs(y1-y2) < 3:
        else:
            if random.randint(0, 1) == 1:
                if x1 > x2:
                    x1 -= 1
                else:
                    x1 += 1
                if y1 > y2:
                    y2 += 1
                    y3 = y1 - 1
                else:
                    y2 -= 1
                    y3 = y1 + 1

                self.create_h_tunnel(x1, x2, y1)
                self.create_v_tunnel(y3, y2, x2)
                if random.randint(0,door_chance) == 0 and abs(x1-x2) > 1:
                    self.place_door(x1, y1)
                elif random.randint(0,door_chance) == 0 and abs(y1-y2) > 1:
                    self.place_door(x2, y2)

            else:
                if x1 > x2:
                    x2 += 1
                    x3 = x1 - 1
                else:
                    x2 -= 1
                    x3 = x1 + 1
                if y1 > y2:
                    y1 -= 1
                else:
                    y1 += 1

                self.create_v_tunnel(y1, y2, x1)
                self.create_h_tunnel(x3, x2, y2)
                if random.randint(0,door_chance) == 0 and abs(y1-y2) > 1:
                    self.place_door(x1, y1)
                elif random.randint(0,door_chance) == 0 and abs(x1-x2) > 1:
                    self.place_door(x2, y2)

    def create_h_tunnel(self, x1, x2, y):
        for x in range(min(x1, x2), max(x1, x2) + 1):
            self.set_unblocked(x,y)

    def create_v_tunnel(self, y1, y2, x):
        for y in range(min(y1, y2), max(y1, y2) + 1):
            self.set_unblocked(x,y)

    def get_copy_map(self):
        return copy.deepcopy(self.tcod_map)

    def get_copy_empty_map(self):
        return copy.deepcopy(self.tcod_empty_map)

    def set_tile_type(self, x, y, ttype):
        self.tiles[x][y] = entity.Tile(x, y, color_coeff=self.sample[x][y], ttype=ttype)
        if self.show_map:
            self.tiles[x][y].is_seen = True
        self.tcod_map.transparent[y,x] = ttype.value.get("transparent")
        self.tcod_map.walkable[y,x] = not ttype.value.get("collision")

    def is_over_map(self, x, y):
        return x >= 0 and y >= 0 and x < self.width and y < self.height

    def set_blocked(self, x, y):
        self.set_tile_type(x, y, const.TileType.WALL)

    def set_unblocked(self, x, y):
        self.set_tile_type(x, y, const.TileType.FLOOR)

    def place_door(self, x, y):
        self.set_tile_type(x, y, const.TileType.DOOR)

    def place_stairs(self, x, y):
        self.set_tile_type(x, y, const.TileType.STAIRS)

    def place_boss_stairs(self, x, y):
        self.set_tile_type(x, y, const.TileType.BOSS_STAIRS)

    def is_floor(self, x, y):
        return self.tiles[x][y].ftype == const.TileType.FLOOR

    def is_door(self, x, y):
        return self.tiles[x][y].ftype == const.TileType.DOOR

    def is_stairs(self, x, y):
        return self.tiles[x][y].ftype == const.TileType.STAIRS

    def is_boss_stairs(self, x, y):
        return self.tiles[x][y].ftype == const.TileType.BOSS_STAIRS

    def is_blocked(self, x, y):
        return not self.tcod_map.walkable[y,x]

    def drop_item_on_floor(self, player, entities, item, drop_key):
        if not self.tiles[player.x][player.y].item:
            player.remove_from_inventory(item, drop_key)
            return self.tiles[player.x][player.y].put_item(item, entities)

    def is_weapon_on_floor_directly_equipable(self, player):
        item = self.tiles[player.x][player.y].item
        if item and isinstance(item, entity.Weapon) and not player.wequiped.get(item.wslot):
            return True
        return False

    def get_item_on_floor(self, player, entities):
        if self.tiles[player.x][player.y].item:
            item = self.tiles[player.x][player.y].take_item(entities)
            key = player.add_to_inventory(item)
            return (item,key)

    def description_item_on_floor(self, player):
        """
        Get the name of the item on the floor where the player is
        """
        if self.tiles[player.x][player.y].item:
            return self.tiles[player.x][player.y].item.name
        return None

    def is_there_item_on_floor(self, player):
        """
        Is there an item on the floor, where the player is?
        """
        return self.tiles[player.x][player.y].item != None


import sys
import pandas as pd
import numpy as np
import xml.dom.minidom

#from exercise 3
def output_gpx(points, output_filename):
    """
    Output a GPX file with latitude and longitude from the points DataFrame.
    """
    def append_trkpt(pt, trkseg, doc):
        trkpt = doc.createElement('trkpt')
        trkpt.setAttribute('lat', '%.8f' % (pt['lat']))
        trkpt.setAttribute('lon', '%.8f' % (pt['lon']))
        trkseg.appendChild(trkpt)

    doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'gpx', None)
    trk = doc.createElement('trk')
    doc.documentElement.appendChild(trk)
    trkseg = doc.createElement('trkseg')
    trk.appendChild(trkseg)

    points.apply(append_trkpt, axis=1, trkseg=trkseg, doc=doc)

    with open(output_filename, 'w') as fh:
        doc.writexml(fh, indent=' ')

def main(input_file):
    culture_tour = pd.read_csv('culture_tour.csv')
    dessert_tour = pd.read_csv('dessert_tour.csv')
    pub_crawl = pd.read_csv('pub_crawl.csv')
    scenic_tour = pd.read_csv('scenic_tour.csv')

    lodging_df = pd.read_csv(input_file)
    lodging_coordinates_df = lodging_df[['lat', 'lon']]
    output_gpx(lodging_coordinates_df, 'lodging.gpx')

    culture_interest = lodging_df['culture'].values[0]
    dessert_interest = lodging_df['dessert'].values[0]
    drinks_interest = lodging_df['drinks'].values[0]
    scenic_interest = lodging_df['scenic'].values[0]

    if (culture_interest == 'y'):
        culture_tour_subset_df = culture_tour[['lat', 'lon']]
        culture_tour_subset_df = culture_tour_subset_df.append(culture_tour_subset_df.iloc[0])
        output_gpx(culture_tour_subset_df, 'culture.gpx')
    if (dessert_interest == 'y'):
        dessert_tour_subset_df = dessert_tour[['lat', 'lon']]
        dessert_tour_subset_df = dessert_tour_subset_df.append(dessert_tour_subset_df.iloc[0])
        output_gpx(dessert_tour_subset_df, 'desserts.gpx')
    if (drinks_interest == 'y'):
        pub_crawl_subset_df = pub_crawl[['lat', 'lon']]
        pub_crawl_subset_df = pub_crawl_subset_df.append(pub_crawl_subset_df.iloc[0])
        output_gpx(pub_crawl_subset_df, 'drinks.gpx')
    if (scenic_interest == 'y'):
        scenic_tour_subset_df = scenic_tour[['lat', 'lon']]
        scenic_tour_subset_df = scenic_tour_subset_df.append(scenic_tour_subset_df.iloc[0])
        output_gpx(scenic_tour_subset_df, 'scenic.gpx')

if __name__ == '__main__':
    input_file = sys.argv[1]
    main(input_file)


# coding: utf-8

# # Heat Diffusion in Soils
#
# This Jupyter Notebook gives an example how to implement a 1D heat diffusion model in Python.
#
# First we need to import the packages which we will be using:
#

# In[1]:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

import CoupledHeatWaterFlowTHe as cfun
import MyTicToc as mt

sns.set()

## Main

# In[0:] Domain & Soil properties
nIN = 51
# soil profile until 15 meters depth
zIN = np.linspace(-2.0, 0, num=nIN).reshape(nIN, 1)
# nIN = np.shape(zIN)[0]
zN = np.zeros(nIN - 1).reshape(nIN - 1, 1)
zN[0, 0] = zIN[0, 0]
zN[1:nIN - 2, 0] = (zIN[1:nIN - 2, 0] + zIN[2:nIN - 1, 0]) / 2
zN[nIN - 2, 0] = zIN[nIN - 1]
nN = np.shape(zN)[0]

ii = np.arange(0, nN - 1)
dzN = (zN[ii + 1, 0] - zN[ii, 0]).reshape(nN - 1, 1)
dzIN = (zIN[1:, 0] - zIN[0:-1, 0]).reshape(nIN - 1, 1)

# collect model dimensions in a pandas series: mDim
mDim = {'zN' : zN,
        'zIN' : zIN,
        'dzN' : dzN,
        'dzIN' : dzIN,
        'nN' : nN,
        'nIN' : nIN
        }
mDim = pd.Series(mDim)

# ## Definition of material properties
# In this section of the code we define the material properties

# Soil Properties
# [J/(m3 K)] volumetric heat capacity of soil solids
zetaSol = 2.235e6
# [J/(m3 K)] volumetric heat capacity of water (Fredlund 2006)
zetaWat = 4.154e6

# rhoW = 1000  # [kg/m3] density of water
rhoS = 2650  # [kg/m3] density of solid phase
rhoB = 1700  # %[kg/m3] dry bulk density of soil
n = 1 - rhoB / rhoS  # [-] porosity of soil = saturated water content.
qCont = 0.75  # quartz content

# collect soil parameters in a pandas Series: sPar
sPar = {'vGA': np.ones(np.shape(zN)) * 1 / 2.0,  # alpha[1/m]
        'vGN': np.ones(np.shape(zN)) * 2.0,  # n[-]
        'vGM': np.ones(np.shape(zN)) * (1 - 1 / 2.0),  # m = 1-1/n[-]
        'thS': np.ones(np.shape(zN)) * 0.4,  # saturated water content
        'thR': np.ones(np.shape(zN)) * 0.03,  # residual water content
        'KSat': np.ones(np.shape(zN)) * 0.25,  # [m/day]
        'vGE': 0.5,  # power factor for Mualem-van Genuchten
        'Cv': 1.0e-8,  # compressibility of compact sand [1/Pa]
        'viscRef': cfun.ViscosityWaterT(283.15),
        'qCont': qCont, # quartz content
        }
sPar = pd.Series(sPar)

# In[1:] Definition of the Boundary Parameters

# Read meteodata
meteo_data  = pd.read_excel('WieringermeerData_Meteo.xlsx')
meteo_data['num_date'] = meteo_data['datetime'].astype(np.int64)/(1e9*3600*24)
meteo_data.set_index('datetime',inplace=True)

# set simulation time to numeric dates from boudary data...
t_range = meteo_data['num_date'][:-1]
taxis = meteo_data.index[:-1]

# collect boundary parameters in a named tuple boundpar...
def BndTTop(t, bPar):
    if np.size(t)==1:
        t = np.array([t])
    bndT = np.zeros(len(t))
    for ii in range(len(t)):
        xy, md_ind, t_ind = np.intersect1d(bPar.meteo_data['num_date'], np.ceil(t[ii]), return_indices=True)
        topT = bPar.meteo_data['temp'].iloc[md_ind].values

        bndT[ii] = 273.15 + topT

    return bndT

def BndqWatTop(t, bPar):
    if np.size(t)==1:
        t = np.array([t])
    qBnd = np.zeros(len(t))

    for ii in range(len(t)):
        xy, md_ind, t_ind = np.intersect1d(bPar.meteo_data['num_date'], np.ceil(t[ii]), return_indices=True)
        rf = bPar.meteo_data['rain_station'].iloc[md_ind].values

        qBnd[ii] = -rf
    return qBnd

bPar = {'topBndFuncHeat': BndTTop,
        'meteo_data': meteo_data,
        'topCond': 'Robin',
        'lambdaRobTop': 1e9,
        'lambdaRobBot': 0,
        'TBndBot': 273.15 + 10,
        'topBndFuncWat': BndqWatTop, #topBndFuncWat(t,bPar)
        'bottomTypeWat': 'Robin', # Robin condition or Gravity condition
        'kRobBotWat': 0.05,  # Robin resistance term for bottom
        'hwBotBnd': 1.0,  # pressure head at lower boundary
        }

bPar = pd.Series(bPar)

# In[3:] Define Initial Conditions
zRef = -1.0 # depth of water table
hwIni = zRef - zN

TIni = np.ones(np.shape(zN)) * (10.0 + 273.15)  # K

sVecIni = np.concatenate([hwIni, TIni], axis=0)

# Time Discretization
tOut = np.linspace(t_range[0],t_range[365],365*5)
#tplot = taxis[0:50]
nOut = np.shape(tOut)[0]

nOut = len(tOut)
# tOut = np.sort(np.hstack((tOut1, bTime)))  # time

# copy initial vector to hw0. Apply squeeze to compress it to one dimension

mt.tic()
int_result = cfun.IntegrateCHWF(tOut, sVecIni, sPar, mDim, bPar)
mt.toc()

hWSim = int_result.y[0:nN]
TSim = int_result.y[nN:2*nN]
thSim = cfun.thFun(hWSim,sPar)
qWSim = cfun.WatFlux(tOut,hWSim,TSim,sPar,mDim,bPar)
qHSim = cfun.HeatFlux(tOut, TSim, hWSim, sPar, mDim, bPar)

#mt.tic()
#TOutPic, hwOutPic = himp.HalfImplicitPicar(tOut2, hw0, T0, sPar, mDim, bPar, tPar)
#mt.toc()

sns.set()
plt.close('all')
fig1, ax1 = plt.subplots(figsize=(7, 4))
ii = np.arange(nN-1, 0, -10)
ax1.plot(tOut, TSim[ii,].T, '-')
ax1.set_title('Temperature (ODE)')
ax1.set_xlabel('time (days)')
ax1.set_ylabel('temperature [K]')
ax1.legend(zN[ii])

fig2, ax2 = plt.subplots(figsize=(7, 7))
jj = np.arange(0, nOut)
ax2.plot(TSim[:, jj], zN, '-')
ax2.set_title('Temperature vs. depth (ODE)')
ax2.set_ylabel('depth [m]')
ax2.set_xlabel('temperature [K]')

fig3, ax3 = plt.subplots(figsize=(7, 4))
# plot fluxes after 2nd output time (initial rate is extreme due to initial conditions)
ax3.plot(tOut, qHSim[ii,:].T, '-')
ax3.set_title('Heat Flux vs. depth (ODE)')
ax3.set_ylabel('depth [m]')
ax3.set_xlabel('temperature [J/m2]')
ax3.legend(zN[ii])

fig4, ax4 = plt.subplots(figsize=(7, 4))
# plot the pressure head for different depths as a function of time
# in this case we plot every 20th layer.
ax4.plot(tOut, hWSim[ii,:].T, '-')
ax4.set_ylabel('pressure head [m]')
ax4.set_xlabel('time [d]')

#plot pressure head as a function of depth. Here we plot every time step
fig5, ax5 = plt.subplots(figsize=(7, 7))
ax5.plot(hWSim, zN, '-')
ax5.grid(b=True)
ax5.set_xlabel('pressure head [m]')
ax5.set_ylabel('depth [m]')

# plt.savefig('myfig.png')

fig6, ax6 = plt.subplots(figsize=(7, 7))
ax6.plot(thSim, zN, '-')
ax6.grid(b=True)
ax6.set_xlabel('water content [-]')
ax6.set_ylabel('depth [m]')

fig7, ax7 = plt.subplots(figsize=(7, 4))
# plot the pressure head for different depths as a function of time
# in this case we plot every 20th layer.
ax7.plot(tOut, thSim[ii,:].T, '-')
ax7.set_ylabel('water content [-]')
ax7.set_xlabel('time [d]')
ax7.legend(zN[ii])

fig8, ax8 = plt.subplots(figsize=(7, 4))
# plot fluxes after 2nd output time (initial rate is extreme due to initial conditions)
ax8.plot(tOut, qWSim[ii,:].T, '-')
ax8.set_title('Water Flux ')
ax8.set_ylabel('depth [m]')
ax8.set_xlabel('water flow [m/d]')
ax8.legend(zN[ii])

fig1.savefig('./figures_scenarios/3_figure1.png')
fig2.savefig('./figures_scenarios/3_figure2.png')
fig3.savefig('./figures_scenarios/3_figure3.png')
fig4.savefig('./figures_scenarios/3_figure4.png')
fig5.savefig('./figures_scenarios/3_figure5.png')
fig6.savefig('./figures_scenarios/3_figure6.png')
fig7.savefig('./figures_scenarios/3_figure7.png')
fig8.savefig('./figures_scenarios/3_figure8.png')
# import shelve

# filename='/tmp/shelve.out'
# my_shelf = shelve.open(filename,'n') # 'n' for new

# for key in dir():
#     try:
#         my_shelf[key] = globals()[key]
#     except TypeError:
#         #
#         # __builtins__, my_shelf, and imported modules can not be shelved.
#         #
#         print('ERROR shelving: {0}'.format(key))
# my_shelf.close()


""" Problem 71: Ordered Fractions

https://projecteuler.net/problem=71

Goal: By listing the set of reduced proper fractions for d <= N in ascending
order of size, find the numerator and denominator of the fraction immediately to
the left of n/d.

Constraints: 1 <= n < d <= 1e9, gcd(n, d) == 1, d < N <= 1e15

Reduced Proper Fraction: A fraction n/d, where n & d are positive integers,
n < d, and gcd(n, d) == 1.

Farey Sequence: A sequence of completely reduced fractions, either between 0 and
1, or which when in reduced terms have denominators <= N, arranged in order of
increasing size. The sequence optionally begins with 0/1 and ends with 1/1 if
restricted. The middle term of a Farey sequence is always 1/2 for N > 1.

        e.g. if d <= 8, the Farey sequence would be ->
             1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5,
             5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

e.g.: N = 8, n = 3, d = 7
      ans = 2/5
"""
from fractions import Fraction
from math import gcd

def left_farey_neighbour(limit: int, n: int, d: int) -> tuple[int, int]:
    """
    Solution finds Farey sequence neighbours based on the following:

    If a/b and n/d are neighbours, with a/b < n/d, then their difference:

    n/d - a/b = (nb - ad)/(db)

    with nb - ad = 1, it becomes ->

    n/d - a/b = 1/(db)

    A mediant fraction can be found between 2 neighbours using:

    p/q = (a + n)/(b + d)

    This solution could also be implemented similarly using a Stern-Brocot Tree
    fraction search algorithm that uses binary search to recursively find the
    target fraction n/d starting from the left & right ancestors, 0/1 & 1/0. Once
    found, the last left boundary is used with the target to find all mediants
    until a new mediant's denominator exceeds limit.

    SPEED (WORSE)
        12.03s for N = 1e7
    SPEED (Impossible for N > 1e10)

    :returns: Tuple of (numerator, denominator) representing the fraction to the
        left of n/d.
    """

    upper_bound = Fraction(n, d)
    lower_bound = Fraction(n, d + 1) if d != limit else Fraction(n - 1, d)
    half = Fraction(1, 2)
    if lower_bound < half < upper_bound:
        lower_bound = half
    neighbour = Fraction()
    while True:
        delta = upper_bound - lower_bound
        neighbour_delta = Fraction(1, lower_bound.denominator * d)
        if delta == neighbour_delta:
            neighbour = lower_bound
        lower_bound = Fraction(
            lower_bound.numerator + n,
            lower_bound.denominator + d
        )
        if lower_bound.denominator > limit and neighbour != Fraction():
            break
    return neighbour.numerator, neighbour.denominator

def compare_fractions(
        fraction_a: tuple[int, int],
        fraction_b: tuple[int, int]
) -> int:
    """
    Rather than compare Doubles, whole numbers are compared based on the
    property that:

    if a/b < n/d, then ad < bn

    :returns: -1 if fraction_a < fraction_b; 1 if fraction_a > fraction_b; 0 if
        both equal.
    """

    left = fraction_a[0] * fraction_b[1]
    right = fraction_a[1] * fraction_b[0]
    if left == right:
        return 0
    return -1 if left < right else 1

def reduce_fraction(numerator: int, denominator: int) -> tuple[int, int]:
    divisor = gcd(numerator, denominator)
    return numerator // divisor, denominator // divisor

def left_farey_neighbour_improved(limit: int, n: int, d: int) -> tuple[int, int]:
    """
    Solution improved based on the following:

    For each denominator b up to N, the only fraction that needs to be considered
    is the one with the largest numerator a for which a/b < n/d.

    a/b < n/d becomes ad < bn, which means ad <= bn - 1

    a <= floor((bn - 1)/d)

    for b <= N, floor((bn - 1)/d)/b is the largest fraction.

    Fractions with larger denominators are spaced more closely than those with
    smaller denominators, so iterating backwards starting at N means the largest
    neighbour below n/d will be found sooner. The loop is broken based on the
    aforementioned property that:

    the difference between 2 neighbours is given as 1/(db)

    for a new fraction r/s to be closer to n/d than a/b ->

    1/(ds) < (nb - da)/(db) -> s > b/(nb - da)

    if delta = nb - da = 1, this means s > b, & the loop can be broken as all
    denominators between b and N have already been examined.

    N.B. Using the Fraction class from the fractions library is helpful as an
    instance intrinsically reduces itself & comparisons & arithmetic operations
    are more easily implemented; however, its use reduced the execution speed to
    405.98s for N = 1e15, a ~4x reduction in performance.

    SPEED (BETTER)
        3.9e4ns for N = 1e7
    SPEED (BETTER)
        93.99s for N = 1e15

    :returns: Tuple of (numerator, denominator) representing the fraction to the
        left of n/d.
    """

    closest_neighbour = 0, 1
    b = limit  # current denominator starts at provided limit
    min_b = 1
    while b >= min_b:
        a = (b * n - 1) // d  # current numerator
        current = a, b
        # if closest_a / closest_b < current_a / current_b
        if compare_fractions(closest_neighbour, current) == -1:
            closest_neighbour = reduce_fraction(a, b)
            delta = n * b - d * a
            min_b = b // delta + 1
        b -= 1
    return closest_neighbour

def extended_gcd(n1: int, n2: int) -> tuple[int, int, int]:
    """
    Implements the Extended Euclidean Algorithm that calculates, in addition to
    gcd(n1, n2), the coefficients of Bezout's identity, integers x and y
    such that:

    ax + by = gcd(a, b)

    :returns: Tuple of (gcd, x, y).
    :raises ValueError: If either n1 or n2 is less than 0.
    """

    if n1 < 0 or n2 < 0:
        raise ValueError("Integers should not be negative")
    if n1 == 0:
        return n2, 0, 1
    e_gcd, x, y = extended_gcd(n2 % n1, n1)
    return e_gcd, y - n2 // n1 * x, x

def left_farey_neighbour_optimised(limit: int, n: int, d: int) -> tuple[int, int]:
    """
    Solution optimised by taking advantage of the Extended Euclidean Algorithm
    that generates coefficients x and y, in addition to the gcd.

    When a and b are co-prime, x will be the modular multiplicative inverse of
    a % b and y will be the modular multiplicative inverse of b % a. Remember
    that the modular multiplicative inverse of an integer a is an integer x such
    that the product ax is congruent to 1 with respect to the modulus b.

    SPEED (BEST)
        5700ns for N = 1e7
    SPEED (BEST)
        1.9e4ns for N = 1e15

    :returns: Tuple of (numerator, denominator) representing the fraction to the
        left of n/d.
    """

    # Python modulus intrinsically handles cases when x is negative
    mod_inverse_of_n = extended_gcd(n, d)[1] % d
    new_d = limit % d - mod_inverse_of_n
    if new_d < 0:
        new_d += d
    neighbour_denom = limit - new_d
    neighbour_num = (neighbour_denom * n - 1) // d
    return neighbour_num, neighbour_denom


import requests
from bs4 import BeautifulSoup
import re

def get_vote_links(current_page):
    """Finds the vote page links on the main folktingspage.

    Args:
        main_page_soup (_type_): Takes in the main page with all the vote subpages as a soap object

    Returns:
        _type_: Returns a list of soap Objects with the links to the respective subpages
    """
    prefix = 'https://www.ft.dk/'
    a = current_page.find_all(attrs={'class':'column-documents__link'})

    a = [prefix+x['href'] for x in a]
    return a

def get_soup_page(url_page):
    """Converts URL into a BeautifulSoup object.

    Args:
        url_page (_type_): takes a URL page as input parsed as a string.

    Returns:
        _type_: returns a BeautifulSoup object.
    """
    response = requests.get(url_page)
    page = BeautifulSoup(response.content, 'html.parser')
    return page

def get_votes_by_party(vote_page) -> dict:
    """ Takes a BeautifulSoup object and retrieves the votes by party
        section, then strips it and modifies it so that it is returned in a fixed sized
        dictionary containing parties, For, Against, Neutral counts.

    Args:
        vote_page (_type_): URL for the folketings vote_page
        (e.g., https://www.ft.dk/samling/20042/afstemning/64.htm)

    Returns:
        dict: fixed sized dictionary containing parties, For, Against, Neutral, absent counts for each party
    """

    table = vote_page.find("div", {"id":"tingdok_accordion_vote-2"})
    dict = {'parties': [], 'For': [], 'Against':[], 'Neutral':[], 'Absent':[]}
    regex_party = re.compile(r"\w* \(\w+\)")
    regex_vote_num = re.compile(r"\d+")

    for child in table.table.tbody.children:
        if re.search(regex_party, child.text.strip()):
            lst = child.text.strip().split("\r\n")
            votes = []
            for i in lst:
                i = i.strip()
                if re.search(regex_party,i):
                    party = i
                    dict['parties'].append(party)

                elif re.search(regex_vote_num, i):
                    votes.append(i)

            dict['For'].append(votes[0])
            dict['Against'].append(votes[1])
            dict['Neutral'].append(votes[2])
            dict['Absent'].append(votes[3])

    return dict

def get_votes(vote_page):

    vote_section = vote_page.find("div", {"id": "tingdok_accordion_vote-3"})

    votes = {
        'politician': [],
        'party': [],
        'vote': []
    }

    for child in vote_section.tbody.children:
        lst = child.text.strip().split("\n\r")
        if len(lst) == 3:
            person, party, vote = [x.strip() for x in lst]
            votes['politician'].append(person)
            votes['party'].append(party)
            votes['vote'].append(vote)

    return votes

def get_description_page(vote_page):
    description_link = vote_page.find("a", {"class":"tingdok-backarrow"})
    prefix = 'https://www.ft.dk/'
    response = requests.get(prefix + description_link['href'])
    description_page = BeautifulSoup(response.content, 'html.parser')

    return description_page

def get_vote_info(description_page):
    description_texts = description_page.find('div', {"class":"tingdok__caseinfospot-a__container"}).text.strip().splitlines()
    info = []
    for line in description_texts:
        if line.strip() != "":
            info.append(line.strip())
    return info

def get_vote_id(vote_page):
    return vote_page.h2.text

def get_title(description_page):
    top_header = description_page.find("div", {"class":"tingdok__caseinfotopspot-a__container"})
    return top_header.h1.text.strip()

def get_vote_caller(description_page):
    top_header = description_page.find("div", {"class":"tingdok__caseinfotopspot-a__container"})
    hosts_section = top_header.find("div", {"class":"tingdok-normal"})

    meeting_hosts = []

    for line in hosts_section:
        clean_line = line.text.strip()
        if len(clean_line)>5:
            meeting_hosts.append(clean_line)

    return meeting_hosts

def get_next_page(current_page):
    next_page_url = current_page.find("a", {"title":"Næste"})['href']
    prefix = "https://www.ft.dk/dokumenter/dokumentlister/afstemninger"
    np_response = requests.get(prefix + next_page_url)
    return BeautifulSoup(np_response.content, 'html.parser')

def exists_next_page(current_page):
    if current_page.find("a", {"title":"Næste"})['href'] != None:
            return True
    else:
        False


from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt

import  ball_endmill
from utility import mm_to_inch
from utility import plot_circle

def plot_spheremill_toolpos(params):

    # Extract parameters
    diam_tool = params['diam_tool']
    diam_sphere = params['diam_sphere']
    tab_thickness = params['tab_thickness']
    offset_z = params['center_z'] + 0.5*diam_sphere
    margin = params['margin']

    # Plot sphere
    cx_sphere = 0.0
    cy_sphere = -0.5*diam_sphere + offset_z
    plot_circle(cx_sphere, cy_sphere, 0.5*diam_sphere)
    plot_circle(cx_sphere, cy_sphere, 0.5*diam_sphere+margin,'c')
    plt.plot([-diam_sphere,diam_sphere],[cy_sphere, cy_sphere], 'k')
    plt.plot([-diam_sphere,diam_sphere],[cy_sphere+0.5*tab_thickness, cy_sphere+0.5*tab_thickness], 'b')
    plt.plot([-diam_sphere,diam_sphere],[cy_sphere-0.5*tab_thickness, cy_sphere-0.5*tab_thickness], 'b')

    # Plot ball nose end mills
    toolpath_annulus_data = ball_endmill.get_toolpath_annulus_data(params)
    for data in toolpath_annulus_data:
        for sgn in (1,-1):
            radius = sgn*data['radius']
            step_z = data['step_z']
            plot_circle(radius, step_z+0.5*diam_tool, 0.5*diam_tool,color='g')
            plt.plot([radius], [step_z+0.5*diam_tool], '.g')
            plt.plot([radius], [step_z], 'xr')
            #plt.plot([radius, 0.0], [step_z+0.5*diam_tool,params['center_z']], 'r')

    # Plot material boundaries
    dx = 2*params['diam_sphere']
    dy = 2*params['center_z']
    plt.plot([-dx, dx], [0, 0],'k')
    plt.plot([-dx, dx], [dy, dy], 'k')

# -----------------------------------------------------------------------------
if __name__ == '__main__':

    params = {
            'diam_sphere'   : mm_to_inch(12.0),
            'diam_tool'     : 1.0/8.0 ,
            'margin'        : 0.0,
            'step_size'     : 0.01,
            'tab_thickness' : 0.02,
            'center_z'      : -0.75/2.0,
            }

    fig_num = 1
    plt.figure(fig_num)
    plot_spheremill_toolpos(params)
    plt.axis('equal')
    plt.grid('on')
    plt.show()


import os
import cv2  # commutator vision
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

mnist = tf.keras.datasets.mnist  # The hand number nad what it is
(x_train, y_train), (x_test, y_test) = mnist.load_data()  # split to training data and test data || x is the pixle data y is what Number

x_train = tf.keras.utils.normalize(x_train, axis=1)  #  make all valus 0 to 1 instaed of 1-255
x_test = tf.keras.utils.normalize(x_test, axis=1)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))  # makes grid of pixles into one big line of 7840 pixles
model.add(tf.keras.layers.Dense(236, activation='relu'))  # rectify linior unit
model.add(tf.keras.layers.Dense(10, activation="softmax"))   # output layer || softmax = pick the most confident nuron
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=3)  # Train model || epoch = how many time brain sees same data
model.save('HandWriteModel.model')

#model = tf.keras.models.load_model('HandWriteModel')

image_number = 1
while  os.path.isfile(f"DigetsByMe\\diget{image_number}.png"):
    try:
        img = cv2.imread(f"DigetsByMe\\diget{image_number}.png")[:,:,0]  # rgb?
        img = np.invert(np.array([img]))
        prediction = model.predict(img)
        print(f"The number is {np.argmax(prediction)}")
        plt.imshow(img[0], cmap=plt.cm.binary)
        plt.show()

    except:
        print("Img is probable not 28 by 28")
    finally:
        image_number += 1

loss, accuracy = model.evaluate(x_test, y_test)

print(loss)
print(accuracy)


__author__ = 'christiaanleysen'
import features.featureMaker as fm
from sklearn.metrics import mean_absolute_error
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn import preprocessing
'''
This file is used to calculate the linear regression
'''

def predictConsumption(trainSetX, trainSetY, testSetX, testSetY,tune_params=True,scaled=False):
    """
    predicts the consumption

    Parameters:
    -----------
    trainSetX: training feature set
    trainSetY: training value set
    testSetX: test feature set
    testSetY: test value set

    Returns:
    --------
    a prediction of the consumption
    """

    if scaled:
        trainSetX = np.asarray([preprocessing.scale(element)for element in trainSetX])
        #trainSetY =preprocessing.scale(trainSetY,axis=0)

        testSetX = np.asarray([preprocessing.scale(element )for element in testSetX])
        #testSetY =preprocessing.scale(testSetY,axis=0)

    OLS = LinearRegression()
    OLS.fit(trainSetX,trainSetY)# fit default model (mean zero & rbf kernel) with data

    predictedSetY = OLS.predict(testSetX)
    MAE = mean_absolute_error(testSetY,predictedSetY)
    if np.mean(np.mean(testSetY)) == 0:
        MRE = 50
    else:
        MRE = (MAE/(np.mean(testSetY)))*100

    return  predictedSetY,testSetY,MAE,MRE


from flask import Flask, render_template
from shp_display import *

app = Flask(__name__)

def script():
    return ['hades2']

def get_table(db):
    db = db

    script = "
"
    # Header Generator
    code = "
"
    for s in db:
        if str(s) != "MULTIPOLYGON" and str(s) != 'geometry':
            code = code + "" + str(s) + "	"
    script = script + code

    # Data Generator
    for i in range(len(db.index)):
        code = "
"
        for item in list(db.loc[i]):
            if not str(item).startswith("MULTIPOLYGON") and not str(item).startswith("POLYGON "):
                code = code + "" + str(item) + "	"
        code = code + "
"
        script = script + code
    script = script + "
"
    return script

@app.route('/')
def index():
    value = script()

    return render_template('index.html',
                           entry1=value[0],
                           path_to_image=some[0],
                           lis=some[1].shape,
                           table_n=get_table(some[1])
                           )

@app.route('/up_pop')
def up_pop():
    some = get_file()
    return render_template('up_population.html',
                           table_n=get_table(some[1]),
                           path_to_image=some[0])

if __name__ == "__main__":
    app.run(debug=True, host='10.68.69.29')


import os
import os.path as osp
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import pandas as pd
import argparse
from dataset import collate_fn, MergedMatchingDataset
from torch.utils.data import DataLoader
from EmbedModel import EmbedModel
from GCN import gcn
from logger import set_logger
from utils import _read_csv, accuracy

def fetch_edge(batch):
    edges = []
    types = []
    for ex in batch:
        type = ex["type"]
        center_id = ex["center"][0]
        neighbors = []
        if "neighbors_mask" in ex:
            for i, n in enumerate(ex["neighbors"]):
                if ex["neighbors_mask"][i] == 0:
                    continue
                neighbors.append(n)
        else:
            neighbors = ex["neighbors"]
        if type == 'l':
            edges += [[center_id, n[0]] for n in neighbors]
            types += [0] * len(neighbors)
        elif type == 'r':
            edges += [[n[0], center_id] for n in neighbors]
            types += [1] * len(neighbors)
        else:
            raise NotImplementedError
    return edges, types

def calculate_f1(edges, scores, labels, types, score_type='left'):
    score_dict={}

    for i, edge in enumerate(edges):
        score = scores[i]
        label = labels[i]
        e = tuple(edge)
        if e in score_dict:
            assert score_dict[e][1] == label
            if score_type == 'max':
                score_dict[e] = (max(score_dict[e][0],score),label)
            elif score_type == 'mean':
                score_dict[e] = ((score_dict[e][0] + score) / 2.0, label)
            elif score_type == 'min':
                score_dict[e] = (min(score_dict[e][0], score), label)
            else:
                raise NotImplementedError
        else:
            score_dict[e] = (score,label)
    score_label = score_dict.values()
    scores = np.asarray([i[0] for i in score_label])
    label = np.asarray([i[1] for i in score_label])
    pred = (scores > 0.5).astype('int')

    TP = np.sum((pred == 1) * (label == 1))
    TN = np.sum((pred == 0) * (label == 0))
    FP = np.sum((pred == 1) * (label == 0))
    FN = np.sum((pred == 0) * (label == 1))
    acc = (TP + TN) * 1.0 / (TP + TN + FN + FP)
    if TP == 0:
        p = r = f1 =0.0
    else:
        p = TP * 1.0 / (TP + FP)
        r = TP * 1.0 / (TP + FN)
        f1 = 2 * p * r / (p + r)
    return p, r, f1, acc, score_dict

def test(iter,logger,model,embed_model,crit,test_step=None,tf_logger=None,score_type='mean', prefix='Test'):
    model.eval()
    embed_model.eval()

    edges = []
    scores = []
    labels = []
    types = []
    for j, batch in enumerate(iter):
        with torch.no_grad():
            edge,type = fetch_edge(batch)
            feature, A, label, masks = embed_model(batch)
            masks = masks.view(-1)
            label = label.view(-1)[masks == 1].long()
            pred = model(feature, A)
            pred = pred[masks == 1]
            loss = crit(pred, label)
            pred = F.softmax(pred, dim=1)
            p, r, acc = accuracy(pred, label)
            logger.info(
                '{}\t[{:d}/{:d}]\tLoss {:.3f}\tAccuracy {:.3f}\tPrecison {:.3f}\tRecall {:.3f}'.format(prefix,j+1,len(iter),loss,acc,
                                                                                p, r))
            assert pred.shape[0] == label.shape[0]
            scores += pred[:,1].detach().cpu().numpy().tolist()
            edges += edge
            labels += label.detach().cpu().numpy().tolist()
            types += type

    edges = np.asarray(edges)
    scores = np.asarray(scores)
    labels = np.asarray(labels)
    types = np.asarray(types)

    if not isinstance(score_type,list):
        score_type = [score_type]
    f1s = []
    for t in score_type:
        p, r, f1, acc, score_dict = calculate_f1(edges, scores, labels, types, score_type=t.lower())
        f1s.append(f1)
        logger.info('{}\t{}\tPrecison {:.3f}\tRecall {:.3f}\tF1-score {:.3f}\tAccuracy {:.3f}'.format(prefix, t, p, r, f1, acc))
        if tf_logger:
            tf_logger.add_scalar('{}/{}/Precision'.format(prefix, t), p, test_step)
            tf_logger.add_scalar('{}/{}/Recall'.format(prefix, t), r, test_step)
            tf_logger.add_scalar('{}/{}/f1Score'.format(prefix, t), f1, test_step)
            tf_logger.add_scalar('{}/{}/Accuracy'.format(prefix, t), acc, test_step)
    return f1s

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    # misc
    working_dir = osp.dirname(osp.abspath(__file__))
    parser.add_argument('--seed', default=1, type=int)
    parser.add_argument('--score_type', type=str, nargs='+')

    # Test args
    parser.add_argument('--batch_size', type=int, default=8)
    parser.add_argument('--tableA_path', type=str)
    parser.add_argument('--tableB_path', type=str)
    parser.add_argument('--train_path', type=str)
    parser.add_argument('--test_path', type=str)
    parser.add_argument('--val_path', type=str)
    parser.add_argument('--checkpoint_path', type=str)

    # Device
    parser.add_argument('--gpu', type=int, default=[0], nargs='+')

    # Model
    parser.add_argument('--gcn_layer', default=1, type=int)

    args = parser.parse_args()

    torch.manual_seed(args.seed)
    torch.cuda.manual_seed_all(args.seed)
    np.random.seed(args.seed)

    tableA = _read_csv(args.tableA_path)
    tableB = _read_csv(args.tableB_path)
    useful_field_num = len(tableA.columns) - 1
    gcn_dim = 768

    test_dataset = MergedMatchingDataset(args.test_path, tableA, tableB, other_path=[args.train_path, args.val_path])

    test_iter = DataLoader(test_dataset, batch_size=args.batch_size, collate_fn=collate_fn, shuffle=False)

    embedmodel = EmbedModel(useful_field_num=useful_field_num,device=args.gpu)

    model = gcn(dims=[gcn_dim]*(args.gcn_layer + 1))

    criterion = nn.CrossEntropyLoss().to(embedmodel.device)

    logger = set_logger()

    if args.checkpoint_path:
        checkpoint = torch.load(args.checkpoint_path)
        if len(args.gpu) == 1:
            new_state_dict = {k.replace('module.', ''): v for k, v in checkpoint["embed_model"].items()}
            embedmodel.load_state_dict(new_state_dict)
        else:
            embedmodel.load_state_dict(checkpoint["embed_model"])
        model.load_state_dict(checkpoint["model"])
        test_type = [checkpoint["type"]]
        logger.info("Test Type:\t{}".format(checkpoint["type"]))
    else:
        test_type = args.test_type

    embedmodel = embedmodel.to(embedmodel.device)
    model = model.to(embedmodel.device)

    test(iter=test_iter, logger=logger, model=model, embed_model=embedmodel, crit=criterion, score_type=test_type)


import cv2
import numpy as np

from analyzers.analyseContour import AnalyseContour
from analyzers.contour import Contour

class AnalyseSafran(AnalyseContour):
    """
    Class qui mesure la taille du safran qui sort de l'eau.

    Attributs:
        x1RefPoint (int): coordonnée x du premier point de référence correspond au point le plus haut du safran.
        y1RefPoint (int): coordonnée y du premier point de référence correspond au point le plus haut du safran.
        x2RefPoint (int): coordonnée x du deuxième point de référence pour calculer la droite du safran.
        y2RefPoint (int): coordonnée y du deuxième point de référence pour calculer la droite du safran.
    """

    def __init__(self, x1, y1, x2, y2, x1RefPoint, y1RefPoint, x2RefPoint, y2RefPoint, qualityLimit):
        super().__init__(x1, y1, x2, y2, qualityLimit)
        self.x1RefPoint = x1RefPoint - x1
        self.y1RefPoint = y1RefPoint - y1
        self.x2RefPoint = x2RefPoint - x1
        self.y2RefPoint = y2RefPoint - y1

    def compute(self, frame):
        """
        Méthode qui mesure la taille du safran qui sort de l'eau.
        """

        m = (self.y2RefPoint - self.y1RefPoint) / (self.x2RefPoint - self.x1RefPoint)
        p = self.y1RefPoint - m * self.x1RefPoint

        cropFrame = frame[self.y1:self.y2, self.x1:self.x2]

        qualityIndex = self.embrunDetection.detection(cropFrame)

        # Conversion en noir et blanc et floutage
        gray_img_safran = cv2.cvtColor(cropFrame, cv2.COLOR_BGR2GRAY)
        gray_img_safran = cv2.GaussianBlur(gray_img_safran, (3, 7), 0)

        # Dessins de toutes les bordures
        median_pix = np.median(gray_img_safran)
        lower = int(max(0, 0.5*median_pix))
        upper = int(min(255, 1.3*median_pix))
        edged = cv2.Canny(gray_img_safran, lower, upper)

        # Détection des contours
        # La variable de hiérarchie contient des informations sur la relation entre chaque contour. (si un contour est dans un contour)
        contours_list_safran, hierarchy = cv2.findContours(edged, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

        if contours_list_safran:
            contourSafran = None

            for c in contours_list_safran:
                # Si un contour est à moins de 15 pixel du point (point sur le bord avant du safran)
                if abs(cv2.pointPolygonTest(c, (self.x1RefPoint + 1, self.y1RefPoint + 3), True)) < 15:
                    contourSafran = c
                    tOffSetSafran = (self.x1, self.y1)

                    points = []

                    # Regarde si les points correspondent plus ou moins à l'équation du safran
                    # Equation qui représente la droite au niveau du safran
                    for point in c:
                        x = point[0][0]
                        y = point[0][1]
                        # Résultat de l'équation
                        resultEquation = m * x - y + p

                        if resultEquation > -15 and resultEquation < 15:
                            points.append((x, y))

                    if len(points) >= 2:
                        # firstPointSafran = min(points, key=lambda x:x[1]) # Plus petite valeur en y
                        firstPointSafran = (self.x1RefPoint, self.y1RefPoint)
                        # Plus grande valeur en y
                        secondPointSafran = max(points, key=lambda x: x[1])

                        # Ajout du décalage pour correspondre sur l'image original
                        firstPointSafranOffSet = tuple(map(lambda x, y: x + y, firstPointSafran, tOffSetSafran))
                        secondPointSafranOffSet = tuple(map(lambda x, y: x + y, secondPointSafran, tOffSetSafran))
                        hauteurSafran = secondPointSafran[1] - firstPointSafran[1]

                        # Décalage des coordonnées du contour pour correspondre sur l'image original (frame)
                        contourSafranOffset = contourSafran + (self.x1, self.y1)

                        return Contour(hauteurSafran, contourSafranOffset, firstPointSafranOffSet, secondPointSafranOffSet, qualityIndex)

        return Contour(None, None, None, None, qualityIndex)


import torch

def get_device(model=None):
    """Returns two-tuple containing a PyTorch device (CPU or GPU(s)), and number of available GPUs.

    Returns a two-tuple containing a  PyTorch device (CPU or GPU(s)) and number of available CUDA
    devices. If `model` is not None, and a CUDA device is available, the model is placed on the
    CUDA device with `model.to(device)`. If multiple GPUs are available, the model is parallized
    with `torch.nn.DataParallel(model)`.

    Args:
        (Torch.nn.Module) PyTorch model, if CUDA device is available this function will place the
        model on the CUDA device with `model.to(device)`. If multiple CUDA devices are available,
        the model is parallized with `torch.nn.DataParallel(model)`.

    Returns:
        A two-tuple containing a PyTorch device (CPU or GPU(s)), and number of available GPUs.
    """
    n_gpu = 0

    # use a GPU if available
    if torch.cuda.is_available():
        device = torch.device("cuda")
        n_gpu = torch.cuda.device_count()
        # if model is provided, we place it on the GPU and parallize it (if possible)
        if model:
            model.to(device)
            if n_gpu > 1:
                model = torch.nn.DataParallel(model)
        model_names = ', '.join([torch.cuda.get_device_name(i) for i in range(n_gpu)])
        print('Using CUDA device(s) with name(s): {}.'.format(model_names))
    else:
        device = torch.device("cpu")
        print('No GPU available. Using CPU.')

    return device, n_gpu

def preprocess_query(query):
    """Preprocesses `query` to look more like natural language.

    Preprocess `query` to look more like natural language by puntuating it with a question mark and
    rearanging into a subject-verb-object (SVO) topology.

    Args:
        query (str): Query from Wiki- or Medhop.

    Returns:
        `query`, punctuated by a question mark and re-arranged into an SVO topology.
    """
    return ' '.join(query.split(' ')[1:] + query.split(' ')[0].split('_')).replace('?', '') + '?'


import os, sys

proj_path = "/home/webuser/webapps/tigaserver/"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tigaserver_project.settings")
sys.path.append(proj_path)

os.chdir(proj_path + "util_scripts/")

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

from django.db.models import Count
from tigaserver_app.models import EuropeCountry, Report, ExpertReportAnnotation, Categories

current_progress = Report.objects.exclude(creation_time__year=2014).exclude(note__icontains="#345").exclude(hide=True).exclude(photos=None).filter(type='adult').annotate(n_annotations=Count('expert_report_annotations')).filter(n_annotations__lt=3).exclude(n_annotations=0).order_by('-server_upload_time')
reports_filtered = filter(lambda x: not x.deleted and x.latest_version, current_progress)
for c in current_progress:
    country = 'None'
    if c.country is not None:
        country = c.country.name_engl
    print("Report in progress {0} - country {1} - date {2}".format(c.version_UUID, country, c.server_upload_time  ))
    assigned_to = ExpertReportAnnotation.objects.filter(report=c)
    for a in assigned_to:
        print("\t - assigned to {0} from country , regional manager , country has regional manager ".format( a.user.username ))


__author__ = "Meet Dave"
__version__ = "1.0"
__maintainer__ = "Meet Dave"
__email__ = "meetkirankum@umass.edu"

# Load libraries

import matplotlib.pyplot as plt
import torch
import cv2
import numpy as np
from torchvision import models
from torchvision import transforms
from make_video import make_video

# Load pretrained model
deeplapv3_101 = models.segmentation.deeplabv3_resnet101(pretrained=True).eval()

# Load background image

background_path = "../images/books-seats.png"
background = cv2.imread(background_path)
background = cv2.cvtColor(background, cv2.COLOR_BGR2RGB)

video_path = "../images/test1.avi"

# Webcam stream

cap = cv2.VideoCapture(0)

ret, img = cap.read()
height = img.shape[0]
width = img.shape[1]

video_download = make_video(video_path,width,height)

background = cv2.resize(background, (width,height))
background = background.astype(float)

# Preprocess class

preprocess = transforms.Compose([
    transforms.ToPILImage(),
    transforms.Resize((256,256)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

while(True):

    ret, img = cap.read()

    if ret:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

        # Preprocess image
        input_img = preprocess(img)
        # Creating a batch dimension
        input_batch = input_img.unsqueeze(0)

        # Inference
        output = deeplapv3_101(input_batch)['out'][0]
        final_output = output.argmax(dim=0)

        # Just keep person class and make everything else background
        person_output = torch.zeros_like(final_output)
        person_output[final_output == 15] = 1

        img_resize = cv2.resize(img,(256,256))
        # Get person segmentation
        foreground = img_resize * person_output.numpy()[:,:,None]
        foreground = foreground.astype(float)
        foreground_orig_size = cv2.resize(foreground,(width,height))

        # Create alpha mask for blending
        th, alpha = cv2.threshold(foreground_orig_size,0,255, cv2.THRESH_BINARY)
        # Smooth the edges for smooth blending
        alpha = (cv2.GaussianBlur(alpha, (7,7),0))/255

        final = foreground_orig_size * alpha + background * (1 - alpha)
        final = final[...,::-1]
        final = (final).astype(np.uint8)
        cv2.imshow('frame',final)
        video_download.write(final)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()


from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LoadCredentialsFile("mycreds.txt")

if gauth.credentials is None:
  gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
  gauth.Refresh()
else:
  gauth.Authorize()

gauth.SaveCredentialsFile("mycreds.txt")

drive = GoogleDrive(gauth)

file1 = drive.CreateFile({'title': 'Automata.txt'})  # Create GoogleDriveFile instance with title 'Hello.txt'.
file1.SetContentString('Automataaa') # Set content of the file from given string.
file1.Upload()
print(drive)


import datetime
import jpholiday
from django import template

register = template.Library() # Djangoのテンプレートタグライブラリ

# カスタムフィルタとして登録する

@register.filter
def get_dict_value(dictionary, key):
    return dictionary.get(key)

@register.filter
def append_string(dest, src):
    return dest + src

@register.filter
def get_day_class(date):
    day_class = ''
    # dateは年/月/日形式の文字列
    #d = datetime.strptime(date,'%Y/%m/%d')
    # strptimeを使用すると、is_holidayが正しく動作しないためのワークアラウンド
    # datetime.date(2020,7,23,0,0)になるのが原因？
    sp = date.split('/')
    day = datetime.date(int(sp[0]), int(sp[1]), int(sp[2]))
    if day.weekday() == 5:
        # 土曜日
        day_class = 'text-primary'
    elif day.weekday() == 6 or jpholiday.is_holiday(day):
        # 日曜 or 祝日
        day_class = 'text-danger'
    return day_class

@register.filter
def get_monthly_max(monthly_list):
    max_count = 0
    for date, count in monthly_list:
        max_count = max(max_count, count)

    return max_count


import sys
import os
import random
from PIL import Image

'''
Simple image carver. Right now it will assemble any and all JPEGS found including partial fragmented files. It does not find the rest of the file.
You must have pillow installed. You can do that by `pip install pillow`.

YOU MUST HAVE PYTHON 3 NOT 2! THE Pillow version used is the python version 3 and I can't guarantee any of this works on python 2.
'''
def main():
	if len(sys.argv) < 2:
		print("Invalid input, you must specify a file as the first argument.")
		exit(0)
	readFile(sys.argv[1])

# Reads file and creates the list of SOI AND EOI markers
def readFile(filename):
	startMarkerArr = []
	endMarkerArr = []
	sosArr = []
	counter = 0
	fileSize = os.stat(filename).st_size
	file = open(filename, 'rb')
	fileBuffer = bytearray(file.read())
	while counter < fileSize:
		byte1 = bytes([fileBuffer[counter]])
		byte2 = bytes([fileBuffer[counter+1]])
		if findStart(byte1, byte2):
				startMarkerArr.append(counter)
		if findEnd(byte1, byte2):
			endMarkerArr.append(counter)
		counter += 2
	print("Found markers")
	pairs = findPairs(startMarkerArr, endMarkerArr, sosArr)
	validCount = buildFile(pairs)

#Finds SOI
def findStart(byte1, byte2):
	if byte1 == b'\xFF' and byte2 == b'\xD8':
		return True
	return False
#Finds EOI
def findEnd(byte1, byte2):
	if byte1 == b'\xFF' and byte2 == b'\xD9':
		return True
	return False

#Creates the pairs of SOI and EOI markers
def findPairs(startMarkerArr, endMarkerArr, sosArr):
	markerPairs = []
	for startI in range(0, len(startMarkerArr)):
		for endI in range(0, len(endMarkerArr)):
			if startMarkerArr[startI] < endMarkerArr[endI] + 2:
				markerPairs.append((startMarkerArr[startI], endMarkerArr[endI]))
	print("Found pairs list size is " + str(len(markerPairs)))
	return markerPairs

#Tests all pairs and tests/ deletes invalid images using Pillow/ PIL
# Also tests to see if the discovered file is the smallest of the ones generated from the same SOI
def buildFile(markerPairs):
	file = open(sys.argv[1], 'rb')
	byteBuffer = file.read()
	counter = 0
	smallestHashMap = {}
	while counter < len(markerPairs):
		jpegBytes = bytearray()
		start = markerPairs[counter][1]
		jpegBytes.extend(byteBuffer[markerPairs[counter][0]:markerPairs[counter][1]+2])
		name = str(random.random())
		jpegFile = open(name + ".jpg", 'wb+')
		jpegFile.write(jpegBytes)
		try:
			Image.open(name + ".jpg")
		except IOError:
			os.remove(name + ".jpg")
			print("Invalid image removed")
		else:
			if smallestHashMap.get(markerPairs[counter][0]) != None:
				print(len(jpegBytes), smallestHashMap[markerPairs[counter][0]][0])
			if counter != 0 and smallestHashMap.get(markerPairs[counter][0]) != None and len(jpegBytes) < smallestHashMap[markerPairs[counter][0]][0]:
				print("Smaller image found, duplicate removed!")
				os.remove(smallestHashMap[markerPairs[counter][0]][1])
				smallestHashMap[markerPairs[counter][0]] = (len(jpegBytes), name + ".jpg")
			if smallestHashMap.get(markerPairs[counter][0]) != None and len(jpegBytes) > smallestHashMap[markerPairs[counter][0]][0]:
				os.remove(name + ".jpg")
				print("Original is the smallest duplicate removed")
			if smallestHashMap.get(markerPairs[counter][0]) == None:
				smallestHashMap[markerPairs[counter][0]] = (len(jpegBytes), name + ".jpg")
			print("One valid image has been added or replaced")
		counter += 1
# No idea what this does
if __name__ == '__main__':
	main()


from copy import copy, deepcopy
from itertools import izip

from burrahobbit.util import all

SENTINEL = object()

SHIFT = 5
BMAP = (1 << SHIFT) - 1
BRANCH = 2 ** SHIFT

MAXBITMAPDISPATCH = 16

def relevant(hsh, shift):
    """ Return the relevant part of the hsh on the level shift. """
    return hsh >> shift & BMAP

POPCOUNT_TBL = [0] * (2 ** 16)
for idx in xrange(2 ** 16):
    POPCOUNT_TBL[idx] = (idx & 1) + POPCOUNT_TBL[idx >> 1]

def bit_count(v):
    return (POPCOUNT_TBL[v & 0xffff] +
            POPCOUNT_TBL[(v >> 16) & 0xffff])

def doc(docstring):
    """ Decorator to set docstring of function to docstring. """
    def deco(fn):
        """ Implementation detail. """
        fn.__doc__ = docstring
        return fn
    return deco

ASSOC = "\n".join([
    "Add AssocNode node whose key's hash is hsh to the node or its children.",
    "shift refers to the current level in the tree, which must be a multiple",
    "of the global constant BRANCH. If a node with the same key already",
    "exists, override it.",
])

IASSOC = "\n".join([
    "Modify so that the AssocNode whose key's hash is hsh is added to it.",
    "USE WITH CAUTION.",
    "shift refers to the current level in the tree, which must be a multiple",
    "of the global constant BRANCH. If a node with the same key already",
    "exists, override it.",
])

GET = "\n".join([
    "Get value of the AssocNode with key whose hash is hsh in the subtree.",
    "shift refers to the current level in the tree, which must be a multiple",
    "of the global constant BRANCH.",
])

WITHOUT = "\n".join([
    "Remove AssocNode with key whose hash is hsh from the subtree.",
    "shift refers to the current level in the tree, which must be a multiple",
    "of the global constant BRANCH.",
])

IWITHOUT = "\n".join([
    "Modify so that the AssocNode whose key's hash is hsh is removed from it.",
    "USE WITH CAUTION.",
    "shift refers to the current level in the tree, which must be a multiple",
    "of the global constant BRANCH.",
])

class Node(object):
    __slots__ = []
    def __and__(self, other):
        new = NULLNODE

        for node in other:
            try:
                self.get(hash(node.key), 0, node.key)
            except KeyError:
                pass
            else:
                new = new._iassoc(hash(node.key), 0, node)
        return new

    def __xor__(self, other):
        new = self
        for node in other:
            new = new.xor(node.hsh, 0, node)
        return new

    def __or__(self, other):
        new = self
        for node in other:
            new = new.assoc(node.hsh, 0, node)
        return new

    def __eq__(self, other):
        return all(node == othernode for node, othernode in izip(self, other))

    def __neq__(self, other):
        return any(node != othernode for node, othernode in izip(self, other))

class NullNode(Node):
    """ Dummy node being the leaf of branches that have no entries. """
    __slots__ = []
    def xor(self, hsh, shift, node):
        return node

    _ixor = xor

    @doc(ASSOC)
    def assoc(self, hsh, shift, node):
        # Because there currently no node, the new node
        # is the node to be added.
        return node

    # The NullNode does not need to be modified if a new association is
    # created because it only returns the new node, hence _iassoc = assoc.
    _iassoc = assoc

    def get(self, hsh, shift, key):
        # There is no entry with the searched key because the hash leads
        # to a branch ending in a NullNode.
        raise KeyError(key)

    @doc(WITHOUT)
    def without(self, hsh, shift, key):
        # There is no entry with the key to be removed because the hash leads
        # to a branch ending in a NullNode.
        raise KeyError(key)

    _iwithout = without

    def __iter__(self):
        # There are no keys contained in a NullNode. Hence, an empty
        # iterator is returned.
        return iter([])

    # Likewise, there are no values and items in a NullNode.
    iteritems = itervalues = __iter__

    def __copy__(self):
        return self

    def cutoff(self, hsh):
        return self

# We only need one instance of a NullNode because it does not contain
# any data.
NULLNODE = NullNode()

class HashCollisionNode(Node):
    """ If hashes of two keys collide, store them in a list and when a key
    is searched, iterate over that list and find the appropriate key. """
    __slots__ = ['children', 'hsh']
    def __init__(self, nodes):
        self.children = nodes
        self.hsh = hash(nodes[0].hsh)

    def xor(self, hsh, shift, node):
        if not any(node.key == child.key for child in self.children):
            return HashCollisionNode(self.children + [node])
        return self

    def _ixor(self, hsh, shift, node):
        if not any(node.key == child.key for child in self.children):
            self.children.append(node)
        return self

    @doc(GET)
    def get(self, hsh, shift, key):
        # To get the child we want we need to iterate over all possible ones.
        # The contents of children are always AssocNodes,
        # so we can safely access the key member.
        for node in self.children:
            if key == node.key:
                return node
        raise KeyError(key)

    @doc(ASSOC)
    def assoc(self, hsh, shift, node):
        # If we have yet another key with a colliding key, return a new node
        # with it added to the children, otherwise return a DispatchNode.
        if hsh == self.hsh:
            return HashCollisionNode(self.children + [node])
        return DispatchNode.make(shift, [self, node])

    @doc(IASSOC)
    def _iassoc(self, hsh, shift, node):
        # If we have yet another key with a colliding key, add it to the
        # children, otherwise return a DispatchNode.
        if hsh == self.hsh:
            self.children.append(node)
            return self
        return DispatchNode.make(shift, [self, node])

    @doc(WITHOUT)
    def without(self, hsh, shift, key):
        # Remove the node whose key is key from the children. If it was the
        # last child, return NULLNODE. If there was no member with a
        # matching key, raise KeyError.
        newchildren = [node for node in self.children if node.key != key]
        if not newchildren:
            return NULLNODE

        if newchildren == self.children:
            raise KeyError(key)

        return HashCollisionNode(newchildren)

    @doc(IWITHOUT)
    def _iwithout(self, hsh, shift, key):
        newchildren = [node for node in self.children if node.key != key]
        if not newchildren:
            return NULLNODE

        if newchildren == self.children:
            raise KeyError(key)

        self.children = newchildren
        return self

    def __iter__(self):
        for node in self.children:
            for elem in node:
                yield elem

    def __copy__(self):
        return HashCollisionNode(map(copy, self.children))

    def cutoff(self, hsh):
        if self.hsh <= hsh:
            return NULLNODE
        return self

class ListDispatch(Node):
    """ Light weight dictionary like object for a little amount of items.
    Only feasable for a little amount of items as a list of length nitems
    is always stored.

    Only accepts integers as keys. """
    __slots__ = ['items']

    def __init__(self, nitems=None, items=None):
        if items is None:
            items = [SENTINEL for _ in xrange(nitems)]
        self.items = items

    def replace(self, key, item):
        """ Return a new ListDispatch with the the keyth item replaced
        with item. """
        return ListDispatch(
            None,
            self.items[:key] +
            [item] +
            self.items[key + 1:]
        )

    def _ireplace(self, key, item):
        """ Replace keyth item with item.

        USE WITH CAUTION. """
        self.items[key] = item
        return self

    def __getitem__(self, key):
        value = self.items[key]
        if value is SENTINEL:
            raise KeyError(key)
        return value

    def get(self, key, default):
        """ Get keyth item. If it is not present, return default. """
        value = self.items[key]
        if value is not SENTINEL:
            return value
        return default

    def remove(self, key):
        """ Return new ListDispatch with keyth item removed.
        Will not raise KeyError if it was not present. """
        return self.replace(key, SENTINEL)

    def _iremove(self, key):
        """ Remove keyth item. Will not raise KeyError if it was not present.

        USE WITH CAUTION. """
        self._ireplace(key, SENTINEL)
        return self

    def to_bitmapdispatch(self):
        dispatch = BitMapDispatch()
        for key, value in enumerate(self.items):
            if value is not SENTINEL:
                dispatch._ireplace(key, value)
        return dispatch

    def __iter__(self):
        return (item for item in self.items if item is not SENTINEL)

    def __copy__(self):
        return ListDispatch(items=self.items[:])

    def __deepcopy__(self):
        return ListDispatch(items=map(deepcopy, self.items))

    def map(self, fn):
        newitems = []
        for elem in self.items:
            if elem is not SENTINEL:
                elem = fn(elem)
            newitems.append(elem)
        return ListDispatch(items=newitems)

class BitMapDispatch(Node):
    """ Light weight dictionary like object for a little amount of items.
    Best used for as most as many items as an integer has bits (usually 32).
    Only accepts integers as keys.

    The items are stored in a list and whenever an item is added, the bitmap
    is ORed with (1 << key) so that the keyth bit is set.
    The amount of set bits before the nth bit is used to find the index of the
    item referred to by key in the items list.
    """
    __slots__ = ['bitmap', 'items']
    def __init__(self, bitmap=0, items=None):
        if items is None:
            items = []
        self.bitmap = bitmap
        self.items = items

    def replace(self, key, item):
        """ Return a new BitMapDispatch with the the keyth item replaced
        with item. """
        # If the item already existed in the list, we need to replace it.
        # Otherwise, it will be added to the list at the appropriate
        # position.
        if len(self.items) >= MAXBITMAPDISPATCH:
            new = self.to_listdispatch(BRANCH)
            return new._ireplace(key, item)

        notnew = bool(self.bitmap & 1 << key)
        newmap = self.bitmap | 1 << key
        idx = bit_count(self.bitmap & ((1 << key) - 1))
        return BitMapDispatch(
            newmap,
            # If notnew is True, the item that is replaced by the new item
            # is left out, otherwise the new item is inserted. Refer to
            # _ireplace for a more concise explanation.
            self.items[:idx] + [item] + self.items[idx+notnew:]
        )

    def _ireplace(self, key, item):
        """ Replace keyth item with item.

        USE WITH CAUTION. """
        if len(self.items) >= MAXBITMAPDISPATCH:
            new = self.to_listdispatch(BRANCH)
            return new._ireplace(key, item)

        notnew = bool(self.bitmap & 1 << key)
        self.bitmap |= 1 << key
        idx = bit_count(self.bitmap & ((1 << key) - 1))
        if idx == len(self.items):
            self.items.append(item)
        elif notnew:
            self.items[idx] = item
        else:
            self.items.insert(idx, item)

        return self

    def get(self, key, default=None):
        """ Get keyth item. If it is not present, return default. """
        if not self.bitmap & 1 << key:
            return default
        return self.items[bit_count(self.bitmap & ((1 << key) - 1))]

    def remove(self, key):
        """ Return new BitMapDispatch with keyth item removed.
        Will not raise KeyError if it was not present. """
        idx = bit_count(self.bitmap & ((1 << key) - 1))
        return BitMapDispatch(
            # Unset the keyth bit.
            self.bitmap & ~(1 << key),
            # Leave out the idxth item.
            self.items[:idx] + self.items[idx+1:]
        )

    def _iremove(self, key):
        """ Remove keyth item. Will not raise KeyError if it was not present.

        USE WITH CAUTION. """
        idx = bit_count(self.bitmap & ((1 << key) - 1))
        self.bitmap &= ~(1 << key)
        self.items.pop(idx)
        return self

    def __getitem__(self, key):
        if not self.bitmap & 1 << key:
            raise KeyError(key)
        return self.items[bit_count(self.bitmap & ((1 << key) - 1))]

    def to_listdispatch(self, nitems):
        """ Return ListDispatch with the same key to value connections as this
        BitMapDispatch. """
        return ListDispatch(
            None, [self.get(n, SENTINEL) for n in xrange(nitems)]
        )

    def __iter__(self):
        return iter(self.items)

    def __nonzero__(self):
        return bool(self.items)

    def __copy__(self):
        return BitMapDispatch(self.bitmap, self.items[:])

    def __deepcopy__(self):
        return BitMapDispatch(self.bitmap, map(deepcopy, self.items))

    def map(self, fn):
        return BitMapDispatch(
            self.bitmap,
            [fn(elem) for elem in self.items]
        )

class DispatchNode(Node):
    """ Dispatch to children nodes depending of the hsh value at the
    current level. """
    __slots__ = ['children']
    def __init__(self, children=None):
        if children is None:
            children = BitMapDispatch()

        self.children = children

    def xor(self, hsh, shift, node):
        rlv = relevant(hsh, shift)
        newchild = self.children.get(rlv, NULLNODE).xor(hsh, shift + SHIFT, node)
        if newchild is NULLNODE:
            # This makes sure no dead nodes remain in the tree after
            # removing an item.
            newchildren = self.children.remove(rlv)
            if not newchildren:
                return NULLNODE
        else:
            newchildren = self.children.replace(
                rlv,
                newchild
            )

        return DispatchNode(newchildren)

    def _ixor(self, hsh, shift, node):
        rlv = relevant(hsh, shift)
        newchild = self.children[rlv].xor(hsh, shift + SHIFT, node)
        if newchild is NULLNODE:
            self.children = self.children._iremove(rlv)
            if not self.children:
                return NULLNODE
        else:
            self.children = self.children._ireplace(rlv, newchild)

        return self

    @doc(ASSOC)
    def assoc(self, hsh, shift, node):
        # We need not check whether the return value of
        # self.children.get(...).assoc is NULLNODE, because assoc never
        # returns NULLNODE.
        rlv = relevant(hsh, shift)
        return DispatchNode(
            self.children.replace(
                rlv,
                self.children.get(rlv, NULLNODE).assoc(
                    hsh, shift + SHIFT, node
                )
            )
        )

    @doc(IASSOC)
    def _iassoc(self, hsh, shift, node):
        rlv = relevant(hsh, shift)
        self.children = self.children._ireplace(
            rlv,
            self.children.get(rlv, NULLNODE)._iassoc(hsh, shift + SHIFT, node)
        )
        return self

    @classmethod
    def make(cls, shift, many):
        # Because the object we create in this function is not yet exposed
        # to any other code, we may safely call _iassoc.
        dsp = cls()
        for elem in many:
            dsp = dsp._iassoc(elem.hsh, shift, elem)
        return dsp

    @doc(GET)
    def get(self, hsh, shift, key):
        return self.children.get(relevant(hsh, shift), NULLNODE).get(
            hsh, shift + SHIFT, key
        )

    @doc(WITHOUT)
    def without(self, hsh, shift, key):
        rlv = relevant(hsh, shift)
        newchild = self.children[rlv].without(hsh, shift + SHIFT, key)
        if newchild is NULLNODE:
            # This makes sure no dead nodes remain in the tree after
            # removing an item.
            newchildren = self.children.remove(rlv)
            if not newchildren:
                return NULLNODE
        else:
            newchildren = self.children.replace(
                rlv,
                newchild
            )

        return DispatchNode(newchildren)

    @doc(IWITHOUT)
    def _iwithout(self, hsh, shift, key):
        rlv = relevant(hsh, shift)
        newchild = self.children[rlv]._iwithout(hsh, shift + SHIFT, key)
        if newchild is NULLNODE:
            self.children = self.children._iremove(rlv)
            if not self.children:
                return NULLNODE
        else:
            self.children = self.children._ireplace(rlv, newchild)

        return self

    def __iter__(self):
        for child in self.children:
            for elem in child:
                yield elem

    def __copy__(self):
        return DispatchNode(self.children.map(copy))


# Standard library imports
import serial
import time
import sys
import zerorpc
import datetime

# Application library imports
from MySQLhandler import *
import Utility

SCRIPT_NAME = "RFIDhandler"
TIME_BEFORE_ACTIVATION = 60 * 5

print("Initialize serial connection with Arduino")
try:
    s = serial.Serial('/dev/ttyACM0', 9600)
except:
    error_msg = "Unable to connect to the Arduino"
    print(error_msg)
    Utility.launch_fatal_process_alert(SCRIPT_NAME, error_msg)
    time.sleep(50000)  # Wait a moment for a possible fix
    sys.exit()  # Close the process and hope for a restart (-> supervisor)

# Each variables store an object capable of inserting, updating and deleting
# in the given t
timeshot = 0

while True:
    line = s.readline()  # Get the line sent by the Arduino
    try:
        db_devices = MySQL('devices')
        db_alarms = MySQL('alarms')
        db_users = MySQL('users')
    except:
        error_msg = "Unable to connect to the database"
        print(error_msg)
        Utility.launch_fatal_process_alert(SCRIPT_NAME, error_msg)
        time.sleep(50000)
        sys.exit()
    user = db_users.get('RFID', line.split('\r')[0])
    # [user] represents the owner's row of the RFID tag passed
    # if it exists
    if user:
        Utility.switch_led_info(0)
        Utility.sound(0)
        c = zerorpc.Client()
        c.connect("tcp://127.0.0.1:4242")
        c.RFID()
        alarms = db_alarms.all()
        state = bool(alarms[0]['state'])
        is_one_alarm_up = False
        for alarm in alarms:
            is_one_alarm_up = is_one_alarm_up or bool(alarm['state'])
        if is_one_alarm_up and not state:
            for alarm in alarms:
                db_alarms.modify(alarm['id'], 'state', state)
        elif not state:
            print("[{}]: Waiting {} sec before activation".format(datetime.datetime.now().strftime("%d/%b/%Y %H:%M:%S"), TIME_BEFORE_ACTIVATION))
            time.sleep(TIME_BEFORE_ACTIVATION)
            for alarm in alarms:
                db_alarms.modify(alarm['id'], 'state', not state)
        elif state:
            print("[{}]: Deactivating".format(datetime.datetime.now().strftime("%d/%b/%Y %H:%M:%S")))
            for alarm in alarms:
                db_alarms.modify(alarm['id'], 'state', not state)
    else:
        print("[{}]: Unauthorized tag".format(datetime.datetime.now().strftime("%d/%b/%Y %H:%M:%S")))
        c = zerorpc.Client()
        c.connect("tcp://127.0.0.1:4242")
        c.RFIDError()


import sys
import os
import yaml
import json

CUSTOM_WORD_LIST_FILENAME = '.wordlist.txt'

def find_wordlist_files(path):
    wordlist_paths = []
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith(CUSTOM_WORD_LIST_FILENAME):
                wordlist_paths.append(os.path.join(root, file))
    return wordlist_paths

if __name__ == '__main__':
    spell_check_yaml_path = sys.argv[1]
    markdown_base_path = sys.argv[2]

    spell_check_yaml = None

    with open(spell_check_yaml_path, 'r') as read_file:
        spell_check_yaml = yaml.load(read_file, Loader=yaml.FullLoader)

    wordlist_paths = find_wordlist_files(markdown_base_path)

    print("Adding wordlists: ")
    print("\n".join(wordlist_paths))

    spell_check_yaml['matrix'][0]['dictionary']['wordlists'].extend(wordlist_paths)

    with open(spell_check_yaml_path + ".tmp", 'w') as write_file:
        #yaml.dump doesn't work in Python >3, so we dump to JSON instead & convert using yq in the outer script
        #yaml.dump(write_file, spell_check_yaml, Dumper=yaml.Dumper)
        json.dump(spell_check_yaml, write_file, indent=4)


import imageio
import torch
import torch.nn.functional as F
import numpy as np
import os, argparse
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
from net.bgnet import Net
from utils.tdataloader import test_dataset

parser = argparse.ArgumentParser()
parser.add_argument('--testsize', type=int, default=416, help='testing size')
parser.add_argument('--pth_path', type=str, default='./checkpoints/best/BGNet.pth')

for _data_name in ['CAMO','CHAMELEON','COD10K','NC4K']:
    data_path = './data/TestDataset/{}/'.format(_data_name)
    save_path = './results/BGNet/{}/'.format(_data_name)
    opt = parser.parse_args()
    model = Net()
    model.load_state_dict(torch.load(opt.pth_path))
    model.cuda()
    model.eval()

    os.makedirs(save_path, exist_ok=True)
    os.makedirs(save_path+'edge/', exist_ok=True)
    image_root = '{}/Imgs/'.format(data_path)
    gt_root = '{}/GT/'.format(data_path)
    test_loader = test_dataset(image_root, gt_root, opt.testsize)

    for i in range(test_loader.size):
        image, gt, name = test_loader.load_data()
        gt = np.asarray(gt, np.float32)
        gt /= (gt.max() + 1e-8)
        image = image.cuda()

        _, _, res, e = model(image)
        res = F.upsample(res, size=gt.shape, mode='bilinear', align_corners=False)
        res = res.sigmoid().data.cpu().numpy().squeeze()
        res = (res - res.min()) / (res.max() - res.min() + 1e-8)
        imageio.imwrite(save_path+name, (res*255).astype(np.uint8))
        # e = F.upsample(e, size=gt.shape, mode='bilinear', align_corners=True)
        # e = e.data.cpu().numpy().squeeze()
        # e = (e - e.min()) / (e.max() - e.min() + 1e-8)
        # imageio.imwrite(save_path+'edge/'+name, (e*255).astype(np.uint8))


import datetime
import json
import os
import time

import pandas as pd
import requests

from mystockdata import config, db
from mystockdata.db import DatetimeIndexMixin, PrefixedDfDb
from mystockdata.exceptions import HistoryDataError

class ShSeDb(DatetimeIndexMixin, PrefixedDfDb):
    prefix = 'sh_se_'

class CybSeDb(DatetimeIndexMixin, PrefixedDfDb):
    prefix = 'cyb_se_'

class SzSeDb(DatetimeIndexMixin, PrefixedDfDb):
    prefix = 'sz_se_'

class SzzbSeDb(DatetimeIndexMixin, PrefixedDfDb,):
    prefix = 'szzb_se_'

class ZxqySeDb(DatetimeIndexMixin, PrefixedDfDb, ):
    prefix = 'zxqy_se_'

class SSE:
    sedb = ShSeDb()

    def read_cache(self):
        df = self.sedb.read()
        return df

    def write_cache(self, df):
        df = self.sedb.save(df)

    def get_sse_overview_day(self):
        '''
           source: http://www.sse.com.cn/market/stockdata/overview/day/
        '''

        def _fetch(date):
            url = ('http://query.sse.com.cn/marketdata/tradedata',
                   '/queryTradingByProdTypeData.do?jsonCallBack=jsonpCallback74321',
                   '&searchDate=[DAY]&prodType=gp&_=1456558103149')
            headers = {
                'Host': 'www.sse.com.cn',
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36',
                'Referer': 'http://www.sse.com.cn/market/stockdata/overview/day/',
            }

            real_url = ''.join(url).replace('[DAY]', date.strftime("%Y-%m-%d"))
            rst = requests.get(url=real_url, headers=headers).text

            json_str = rst[19:len(rst) - 1]

            rst_list = json.loads(json_str)
            rst_list = rst_list['result']

            headers = ['istVol', 'SH_profitRate1', 'SH_negotiableValue1', 'SH_trdAmt1', 'SH_trdVol1', 'SH_trdTm1',
                       'A_istVol', 'A_profitRate1', 'A_negotiableValue1', 'A_trdAmt1', 'A_trdVol1', 'A_trdTm1',
                       'B_istVol', 'B_profitRate1', 'B_negotiableValue1', 'B_trdAmt1', 'B_trdVol1', 'B_trdTm1']

            tmp_dict = dict()

            for key, value in rst_list[0].items():
                tmp_dict['A_' + key] = value if value else None
            for key, value in rst_list[1].items():
                tmp_dict['B_' + key] = value if value else None
            for key, value in rst_list[2].items():
                tmp_dict['SH_' + key] = value if value else None
            return pd.DataFrame([tmp_dict, ], index=[date, ])

        def _fetch_dates(begin, end, to_df=True):
            tmp = []
            print(begin, end)
            dates = pd.date_range(begin, end)
            if len(dates) == 1:
                return None
            for date in dates:

                tmp.append(_fetch(date))
                # print(tmp[-1])
                if len(dates) > 1:
                    print('sleep')
                    time.sleep(0.5)
            # print(pd.concat(tmp))
            return pd.concat(tmp)

        cache_df = self.read_cache()
        if cache_df is None or cache_df.empty:
            raise HistoryDataError()
        else:
            start = max(cache_df.index) + datetime.timedelta(days=-1)
        new_df = _fetch_dates(
            start, datetime.datetime.now())
        if new_df is not None:
            cache_df = cache_df.drop(new_df.index, errors='ignore')
        df = pd.concat([cache_df, new_df])

        if len(df) > len(cache_df):
            self.write_cache(df)
        return df

class SZSE:

    dbs = {'sz': SzSeDb(), 'cyb': CybSeDb(),
           'zxqy': ZxqySeDb(), 'szzb': SzzbSeDb()}

    def read_cache(self, category):
        df = self.dbs[category].read()
        return df

    def write_cache(self, df, category):
        df = self.dbs[category].save(df)

    def get_szse_overview_day(self, category):
        '''
        source: http://www.szse.cn/main/marketdata/tjsj/jbzb/
        '''

        def _fetch(date, category):
            urls = {
                'sz':
                ('http://www.szse.cn/szseWeb/ShowReport.szse?',
                 'SHOWTYPE=EXCEL&CATALOGID=1803&txtQueryDate=%s&ENCODE=1&TABKEY=tab1'),

                #  深圳主板
                'szzb':
                ('http://www.szse.cn/szseWeb/ShowReport.szse?',
                 'SHOWTYPE=EXCEL&CATALOGID=1803&txtQueryDate=%s&ENCODE=1&TABKEY=tab2'),

                #  中小企业板
                'zxqy':
                ('http://www.szse.cn/szseWeb/ShowReport.szse?',
                 'SHOWTYPE=EXCEL&CATALOGID=1803&txtQueryDate=%s&ENCODE=1&TABKEY=tab3'),

                #  创业板
                'cyb':
                ('http://www.szse.cn/szseWeb/ShowReport.szse?',
                 'SHOWTYPE=EXCEL&CATALOGID=1803&txtQueryDate=%s&ENCODE=1&TABKEY=tab4')}
            df = pd.read_html(''.join(urls[category]) % date.strftime(
                "%Y-%m-%d"), encoding='gbk', header=0)[0]
            if df.columns[0] == '没有找到符合条件的数据！':
                return None
            if category in ('szzb', 'cyb', 'zxqy'):
                del df['比上日增减']
                del df['本年最高']
                del df['最高值日期']

            if category == 'sz':
                del df['比上日增减']
                del df['幅度%']
                del df['本年最高']
                del df['最高值日期']

            df = pd.pivot_table(df, columns='指标名称')
            df.index = pd.DatetimeIndex([date.strftime("%Y-%m-%d")])
            return df

        def _fetch_dates(begin, end, category):
            tmp = []
            print(begin, end)
            dates = pd.date_range(begin, end)
            if len(dates) == 1:
                return None
            for date in dates:
                tmp.append(_fetch(date, category))
                if len(dates) > 1:
                    print('sleep')
                    time.sleep(0.5)

            return pd.concat(tmp)

        cache_df = self.read_cache(category)
        if cache_df is None or cache_df.empty:
            raise HistoryDataError()
        else:
            start = max(cache_df.index) + datetime.timedelta(days=-1)
        new_df = _fetch_dates(start, datetime.datetime.now(), category)
        if new_df is not None:
            cache_df = cache_df.drop(new_df.index, errors='ignore')
        df = pd.concat([cache_df, new_df])

        if len(df) > len(cache_df):
            self.write_cache(df, category)
        return df

class SE:

    @classmethod
    def get_overview_day_field(cls, f_sha, f_shb, f_sh, f_sz, f_cyb, f_zxqy, f_szzb):
        sh, sz, cyb, zxqy, szzb = ShSeDb(), SzSeDb(), CybSeDb(), ZxqySeDb(), SzzbSeDb()
        sh = sh.read(columns=[f_sha, f_shb, f_sh])
        sh.columns = ['SHA', 'SHB', 'SH']
        sz = sz.read(columns=[f_sz])
        sz.columns = ['SZ']

        cyb = cyb.read([f_cyb])
        cyb.columns = ['CYB']

        zxqy = zxqy.read([f_zxqy])
        zxqy.columns = ['ZXQY']

        szzb = szzb.read([f_szzb])
        szzb.columns = ['SZZB']

        df = pd.concat([sh, sz, cyb, zxqy, szzb, ], axis=1)
        df = df.fillna(method='bfill')
        return df

    @classmethod
    def get_pe(cls):
        return cls.get_overview_day_field('A_profitRate1', 'B_profitRate1', 'SH_profitRate1',
                                          '股票平均市盈率', '平均市盈率(倍)', '平均市盈率(倍)', '平均市盈率(倍)',)

    @classmethod
    def get_market_val(cls):
        df = cls.get_overview_day_field('A_marketValue1', 'B_marketValue1', 'SH_marketValue1',
                                        '股票总市值（元）', '上市公司市价总值(元)', '上市公司市价总值(元)', '上市公司市价总值(元)',)

        df[['SZ', 'CYB', 'ZXQY']] = df[['SZ', 'CYB', 'ZXQY']] / 100000000
        return df

    @classmethod
    def get_negotiable_val(cls):
        df = cls.get_overview_day_field('A_negotiableValue', 'B_negotiableValue', 'SH_negotiableValue',
                                        '股票流通市值（元）', '上市公司流通市值(元)', '上市公司流通市值(元)', '上市公司流通市值(元)',)
        df[['SZ', 'CYB', 'ZXQY']] = df[['SZ', 'CYB', 'ZXQY']] / 100000000
        return df

    @classmethod
    def get_avg_price(cls):
        sh, sz, cyb, zxqy, szzb = self.get_overview_day()

        sh_a = sh['A_trdAmt'].apply(
            float) * 10000 / sh['A_trdVol'].apply(float)
        sh_a.name = 'SHA'
        sh_b = sh['B_trdAmt'].apply(
            float) * 10000 / sh['B_trdVol'].apply(float)
        sh_b.name = 'SHB'
        sh_sh = sh['SH_trdAmt'].apply(
            float) * 10000 / sh['SH_trdVol'].apply(float)
        sh_sh.name = 'SH'

        sz = sz['平均股票价格（元）']
        sz.name = 'SZ'

        cyb = cyb['总成交金额(元)'] / cyb['总成交股数']
        cyb.name = 'CYB'

        zxqy = zxqy['总成交金额(元)'] / zxqy['总成交股数']
        zxqy.name = 'ZXQY'

        szzb = szzb['总成交金额(元)'] / szzb['总成交股数']
        szzb.name = 'SZZB'

        df = pd.concat([sh_a, sh_b, sh_sh, sz, cyb, zxqy, szzb, ], axis=1)
        return df

def load_old_file():
    def read_file(file):
        path = os.path.abspath(os.path.dirname(__file__))
        df = pd.read_csv(os.path.join(path, file))
        df.index = pd.DatetimeIndex(df.date)
        del df['date']
        return df
    ShSeDb().save(read_file('files/se/sh_sse_day_overview.csv'))
    SzSeDb().save(read_file('files/se/sz_day_overview.csv'))
    CybSeDb().save(read_file('files/se/cyb_day_overview.csv'))
    SzzbSeDb().save(read_file('files/se/szzb_day_overview.csv'))
    ZxqySeDb().save(read_file('files/se/zxqy_day_overview.csv'))

    for key in db.DfDb().keys():
        print(key)