import requests
from PIL import Image
import io
import base64

# FILTER

import re
def clean_string(input_string):
    # Lowercase the string and remove non-alphabetic characters
    cleaned_string = re.sub(r'[^a-z]', '', input_string.lower())
    return cleaned_string
with open("invalid_searches.txt", 'r') as f:
	invalid = f.readlines()
	invalid = [clean_string(i) for i in invalid]
	invalid = [i for i in invalid if i != ""]
	invalid.append("")
def check_invalid(word):
	word = clean_string(word)
	return word in invalid

# GETTING THE KEYS

# from keys import *
import os
HF_TOKEN = os.environ.get('HF_TOKEN')
DICTIONARY_API_KEY = os.environ.get('DICTIONARY_API_KEY')

def get_definition(word):

	url = 'https://siwar.ksaa.gov.sa/api/alriyadh/exact-search'
	headers = {
		'accept': 'application/json',
		'apikey': DICTIONARY_API_KEY
	}
	params = {'query': word}
	response = requests.get(url, params=params, headers=headers)
	print(response)

	# word not found
	define = response.json()
	if len(define) == 0:
		return "", "",  []

	define = define[0]

	word = define['lemma']['formRepresentations'][0]['form']
	english = None
	meanings_examples = []

	for i, sense in enumerate(define['senses']):
		meaning = sense['definition']['textRepresentations'][0]['form']
		example = None
		for ex in sense['examples']:
			if ex['form'] != "":
				example = ex['form']
		for ex in sense['translations']:
			if ex['form'] != "" and not english:
				english = ex['form']

		meanings_examples.append({
			"i": i+1,
			"meaning": meaning,
			"example": example
		})

	return word, english, meanings_examples

def get_translation(word):

	if word == "":
		return ""

	API_URL = "https://api-inference.huggingface.co/models/Helsinki-NLP/opus-mt-ar-en"
	headers = {"Authorization": f"Bearer {HF_TOKEN}"}

	response = requests.post(API_URL, headers=headers, json={
		"inputs": word,
	})
	print(response)
	response = response.json()
	print(response)

	# error in response
	if type(response) == dict:
		return ""

	return response[0]['translation_text']

def get_image(word):

	print(word)

	if check_invalid(word):
		return None
		# blank image
		return "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="

	API_URL = "https://api-inference.huggingface.co/models/runwayml/stable-diffusion-v1-5"
	headers = {"Authorization": f"Bearer {HF_TOKEN}"}

	response = requests.post(API_URL, headers=headers, json={
		"inputs": word,
	})
	print(response)
	image_bytes = response.content

	image = Image.open(io.BytesIO(image_bytes))

	# Convert image to base64
	image_base64 = ""
	with io.BytesIO() as buffer:
		image.save(buffer, format="JPEG")
		image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')

	return image_base64

if __name__ == "__main__":
	pass


from fastapi import APIRouter, HTTPException

from api.exceptions import KeyExistsError
from api.payload_validators import is_empty_field, is_within_valid_battery_range
from api.updatedevice.models.battery_level import DeviceBatteryInfo
from api.utils.response import ResponsePacket, build_response, ServiceCode
from database.shared_cache import update_device_battery_info

router = APIRouter()

@router.put('/update', response_model=ResponsePacket)
def update_battery_info(battery_info: DeviceBatteryInfo):
    try:
        if is_empty_field(battery_info.device_id) or is_empty_field(battery_info.current_battery_level):
            raise HTTPException(status_code=422,
                                detail=build_response(ServiceCode.FIELD_EMPTY,
                                                      'Missing Parameters!').dict())

        if not is_within_valid_battery_range(battery_info.current_battery_level):
            raise HTTPException(status_code=422,
                                detail=build_response(ServiceCode.INVALID_BATTERY_RANGE,
                                                      'Invalid Battery Range!').dict())
        update_device_battery_info(battery_info)
    except KeyExistsError:
        raise HTTPException(status_code=400,
                            detail=build_response(ServiceCode.BATTERY_LEVEL_ERROR,
                                                  'Device Does Not Exists!').dict())

    return build_response(ServiceCode.BATTERY_LEVEL_RECEIVED)


"""
1. 아이디어
bfs
    -걷기
    -순간이동
    heap으로 가장 빠른 시간부터 처리하도록
2. 시간복잡도
n = 1e5 O(nlgn)
"""
import sys; input = sys.stdin.readline
from heapq import heappush,heappop

def bfs():
    move[n] = 0
    heap = []
    heappush(heap,(0, n))

    while heap:
        cnt, cur = heappop(heap)
        if cur == k:
            print(cnt)
            return
        for opt, c in [(cur+1,1), (cur-1,1), (2*cur,0)]:
            if 0 <= opt <= 100000:
                clock = cnt + c
                if move[opt] > clock:
                    move[opt] = clock
                    heappush(heap,(clock,opt))

n, k = map(int,input().split())
move = [float('inf')] * 100001
bfs()


'''
This code is for FFM model in PAN.
'''
import tensorflow as tf

__all__ = ['FFM']

class FFM(tf.keras.Model):
    def __init__(self):
        super(FFM, self).__init__()

    def _upsample(self, x, size, scale=1):
        _, Hout, Wout, _ = size
        _, Hx, Wx, _ = x.shape
        return tf.keras.layers.UpSampling2D(size=(2*scale, 2*scale), interpolation='bilinear')(x)

    def call(self, f1_1, f2_1, f3_1, f4_1, f1_2, f2_2, f3_2, f4_2):
        f1 = f1_1 + f1_2
        f2 = f2_1 + f2_2
        f3 = f3_1 + f3_2
        f4 = f4_1 + f4_2
        f2 = self._upsample(f2, f1.shape, scale=1)
        f3 = self._upsample(f3, f1.shape, scale=2)
        f4 = self._upsample(f4, f1.shape, scale=4)
        f = tf.concat([f1, f2, f3, f4], 3)

        return f

# unit testing
if __name__ == '__main__':
    batch_size = 32
    Height = 640
    Width = 640
    Channel = 128
    f1_1 = tf.random.uniform(shape=[batch_size,Height//4,Width//4,Channel])
    f2_1 = tf.random.uniform(shape=[batch_size,Height//8,Width//8,Channel])
    f3_1 = tf.random.uniform(shape=[batch_size,Height//16,Width//16,Channel])
    f4_1 = tf.random.uniform(shape=[batch_size,Height//32,Width//32,Channel])

    f1_2 = tf.random.uniform(shape=[batch_size,Height//4,Width//4,Channel])
    f2_2 = tf.random.uniform(shape=[batch_size,Height//8,Width//8,Channel])
    f3_2 = tf.random.uniform(shape=[batch_size,Height//16,Width//16,Channel])
    f4_2 = tf.random.uniform(shape=[batch_size,Height//32,Width//32,Channel])

    ffm_model = FFM()
    f = ffm_model(f1_1, f2_1, f3_1, f4_1, f1_2, f2_2, f3_2, f4_2)
    print("FFM input layer 1 shape:", f1_1.shape)
    print("FFM input layer 2 shape:", f2_1.shape)
    print("FFM input layer 3 shape:", f3_1.shape)
    print("FFM input layer 4 shape:", f4_1.shape)
    print("FFM output shape:", f.shape)


"""
Sandbox workflows
"""
import os
from glob import glob

import numpy as np
import nibabel as nb

import nipype.pipeline.engine as pe  # pypeline engine
from nipype.interfaces import utility as niu
from nipype.interfaces import fsl
import nipype.interfaces.io as nio
from nipype.interfaces.utility import Function
from niworkflows.func.util import init_skullstrip_bold_wf

from utils import copy_files

def split_file(in_file, volume):
    import os.path as op
    from nilearn.image import index_img
    from nipype.utils.filemanip import split_filename

    _, base, _ = split_filename(in_file)
    out_file = op.abspath(base + '_vol{0:05d}.nii.gz'.format(volume))
    img = index_img(in_file, volume)
    img.to_filename(out_file)
    return out_file

def join_files(in_files):
    import os.path as op
    from nilearn.image import concat_imgs
    from nipype.utils.filemanip import split_filename

    _, base, _ = split_filename(in_files[0])
    base = '_'.join(base.split('_')[:-1])
    out_file = op.abspath(base + '.nii.gz')
    img = concat_imgs(in_files)
    img.to_filename(out_file)
    return out_file

def divide_files(in_file1, in_file2):
    import os.path as op
    import nibabel as nb
    from nipype.utils.filemanip import split_filename

    _, base, _ = split_filename(in_file1)
    out_file = op.abspath(base + '_divided.nii.gz')
    img1 = nb.load(in_file1)
    dat1 = img1.get_data()
    dat2 = nb.load(in_file2).get_data()
    div_dat = dat1 / dat2
    img = nb.Nifti1Image(div_dat, img1.affine, header=img1.header)
    img.to_filename(out_file)
    return out_file

def init_test_division_wf(name):
    workflow = pe.Workflow(name=name)
    # name the nodes
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['bold_file', 'phase_file']),
        name='inputnode')
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['out_file']),
        name='outputnode')
    dividenode = pe.Node(
        interface=Function(['in_file1', 'in_file2'], ['out_file'], divide_files),
        name='dividenode')
    workflow.connect(inputnode, 'bold_file', dividenode, 'in_file1')
    workflow.connect(inputnode, 'phase_file', dividenode, 'in_file2')
    workflow.connect(dividenode, 'out_file', outputnode, 'out_file')
    return workflow

def init_skullstrip_wf_3d(name, num_trs):
    workflow = pe.Workflow(name=name)
    # name the nodes
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['bold_file', 'phase_file']),
        name='inputnode')
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['mask_file', 'div_file']),
        name='outputnode')

    buffernode = pe.Node(
        niu.IdentityInterface(fields=['bold_file', 'phase_file', 'volume']),
        name='buffernode')
    buffernode.iterables = [('volume', np.arange(5, dtype=int))]
    workflow.connect(inputnode, 'bold_file', buffernode, 'bold_file')
    workflow.connect(inputnode, 'phase_file', buffernode, 'phase_file')

    split_bold = pe.Node(
        interface=Function(['in_file', 'volume'], ['out_file'], split_file),
        name='split_bold')
    workflow.connect(buffernode, 'bold_file', split_bold, 'in_file')
    workflow.connect(buffernode, 'volume', split_bold, 'volume')

    split_phase = pe.Node(
        interface=Function(['in_file', 'volume'], ['out_file'], split_file),
        name='split_phase')
    workflow.connect(buffernode, 'phase_file', split_phase, 'in_file')
    workflow.connect(buffernode, 'volume', split_phase, 'volume')

    divide_wf = init_test_division_wf(name='divide_wf')
    workflow.connect(split_bold, 'out_file', divide_wf, 'inputnode.bold_file')
    workflow.connect(split_phase, 'out_file', divide_wf, 'inputnode.phase_file')

    merge_divided = pe.JoinNode(
        interface=Function(['in_files'], ['out_file'], join_files),
        name='merge_divided',
        joinfield=['in_files'],
        joinsource='buffernode')
    workflow.connect(divide_wf, 'outputnode.out_file', merge_divided, 'in_files')
    workflow.connect(merge_divided, 'out_file', outputnode, 'div_file')

    bold_skullstrip_wf = init_skullstrip_bold_wf(name='bold_skullstrip_wf')
    workflow.connect(split_bold, 'out_file', bold_skullstrip_wf, 'inputnode.in_file')

    mask_merger = pe.JoinNode(
        interface=Function(['in_files'], ['out_file'], join_files),
        name='mask_merger',
        joinfield=['in_files'],
        joinsource='buffernode')
    workflow.connect(bold_skullstrip_wf, 'outputnode.mask_file', mask_merger, 'in_files')
    workflow.connect(mask_merger, 'out_file', outputnode, 'mask_file')
    return workflow

def init_sandbox_wf(name, output_dir, bold_mag_files, bold_phase_files, num_trs):
    workflow = pe.Workflow(name=name)
    # name the nodes
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['bold_mag_files', 'bold_phase_files']),
        name='inputnode',
        iterables=[
            ('bold_mag_files', bold_mag_files),
            ('bold_phase_files', bold_phase_files)],
        synchronize=True)
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['mask_file']),
        name='outputnode')

    skullstrip_wf_3d = init_skullstrip_wf_3d(name='skullstrip_wf_3d', num_trs=num_trs)
    workflow.connect(inputnode, 'bold_mag_files', skullstrip_wf_3d, 'inputnode.bold_file')
    workflow.connect(inputnode, 'bold_phase_files', skullstrip_wf_3d, 'inputnode.phase_file')

    # Output mask files
    derivativesnode = pe.MapNode(
        interface=Function(['in_file', 'output_dir'], ['out_file'], copy_files),
        name='derivativesnode',
        iterfield=['in_file'])
    derivativesnode.inputs.output_dir = output_dir
    workflow.connect(skullstrip_wf_3d, 'outputnode.mask_file', derivativesnode, 'in_file')

    derivativesnode2 = pe.MapNode(
        interface=Function(['in_file', 'output_dir'], ['out_file'], copy_files),
        name='derivativesnode2',
        iterfield=['in_file'])
    derivativesnode2.inputs.output_dir = output_dir
    workflow.connect(skullstrip_wf_3d, 'outputnode.div_file', derivativesnode2, 'in_file')

    return workflow

if __name__ == '__main__':
    # Each input is a list of lists
    bold_mag_files = [
        sorted(glob('/bids_dataset/sub-PILOT/ses-01/func/sub-PILOT_ses-01_task-localizerDetection_run-01_echo-*_bold.nii.gz')),
        sorted(glob('/bids_dataset/sub-PILOT/ses-01/func/sub-PILOT_ses-01_task-localizerEstimation_run-01_echo-*_bold.nii.gz'))
        ]
    bold_phase_files = [
        sorted(glob('/bids_dataset/sub-PILOT/ses-01/func/sub-PILOT_ses-01_task-localizerDetection_run-01_echo-*_phase.nii.gz')),
        sorted(glob('/bids_dataset/sub-PILOT/ses-01/func/sub-PILOT_ses-01_task-localizerEstimation_run-01_echo-*_phase.nii.gz'))
        ]
    output_dir = '/outputs/'
    work_dir = '/work/'

    wf = pe.Workflow(name='sandbox_wf')
    wf.base_dir = work_dir
    for i_run, run_bold_files in enumerate(bold_mag_files):
        f = run_bold_files[0]
        num_trs = nb.load(f).shape[-1]
        run_wf = init_sandbox_wf('sandbox_wf_run-{}'.format(i_run),
                                 output_dir, run_bold_files,
                                 bold_phase_files[i_run],
                                 num_trs)
        wf.add_nodes([run_wf])
    wf.config['execution']['crashdump_dir'] = os.path.join(
        output_dir, 'log'
    )

    # Defaults
    plugin_settings = {
        'plugin': 'MultiProc',
        'plugin_args': {'raise_insufficient': False, 'maxtasksperchild': 1},
    }

    try:
        wf.run(**plugin_settings)
    except RuntimeError as e:
        if 'Workflow did not execute cleanly' in str(e):
            print('Workflow did not execute cleanly')
        else:
            raise e


import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import sklearn.metrics as mt

data = pd.read_csv('data.csv')
cols = list(data)
for i in cols:
	val = data[i]
	vals = list(set(val))
	for j in range(len(val)):
		data[i][j] = vals.index(data[i][j])

features = list(data)[:-1]
print(features)
X = data[features]
Y = data.Buys.astype('int')

Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,Y,test_size=0.3,random_state=1)

classifier = DecisionTreeClassifier()
classifier = classifier.fit(Xtrain,Ytrain)

Ypred = classifier.predict(Xtest)

print(mt.accuracy_score(Ytest,Ypred))


import numpy as np
from cv2 import cv2

image = cv2.imread('butterfly.jpg')
cv2.imshow("Original Image",image)

#Gaussian Filter / Gaussian Blur = This filter uses neighbour pixel to average the value of a pixel to smooth it and remove noise
blur = cv2.GaussianBlur(image,(5,55),0) #Blur in each direction [x,y].they have to be odd number
cv2.imshow("Blurred image",blur)

#Erosion and Dilation
#Erosion = Removes boundary pixels to objects in image, turns white into black
#Dilation = Adds boundary pixels, turns black pixels into white
#Kernel is a small pixel box move around image to get the dilationa dn erosion done
temple= cv2.imread('pic1.png',1)
cv2.imshow('Temple Original',temple)

kernel=np.ones((5,5),'uint8') #odd values in both dim, #more iterations means more effect can be seen
dilate=cv2.dilate(temple,kernel,iterations=1)
erode=cv2.erode(temple,kernel,iterations=1)
cv2.imshow('Dilate',dilate)
cv2.imshow('Erode',erode)

cv2.waitKey(0)
cv2.destroyAllWindows()

LyndaOpenCv Exercises and Assignments/Chap2/BlurDilationErosion.py


import pygame

from pygame.sprite import Group
from pygame.sprite import GroupSingle

import game_functions as gf
from settings import Settings
from ship import Ship
from parachute import Parachute
from hostile import Helicopter
from hostile import Rocket
from hostile import AdvancedHelicopter
from game_stats import GameStats
from button import Button
from scoreboard import Scoreboard
from timer import GameClock, UpgradeTimer
from background import Background
from sounds import ShipBulletSounds, ShipRailgunSounds, ShipMissileSounds, ShipExplodeSounds

from gf_universals import get_process_time

def run_game():
	# Initialize pygame
	pygame.init()
	# Initialize pygame mixer
	pygame.mixer.init()

	# Initializing all the game classes.
	ai_settings = Settings()
	stats = GameStats(ai_settings)
	screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
	pygame.display.set_caption("Plain Planes")

	bg = Background(ai_settings, screen)
	sb = Scoreboard(ai_settings, screen, stats)
	ship = Ship(ai_settings, screen, sb)
	gameclock = GameClock(ai_settings, screen)

	# Initializes all the sound classes.
	shipbullet_sounds = ShipBulletSounds()
	shiprailgun_sounds = ShipRailgunSounds()
	shipmissile_sounds = ShipMissileSounds()
	shipexplode_sounds = ShipExplodeSounds()
	# Sets the volume to 0.1, (range is from 0.0 to 1.0).
	low_volume = 0.03
	mid_volume = 0.3
	high_volume = 0.7
	shipbullet_sounds.firing.set_volume(mid_volume)
	shiprailgun_sounds.start.set_volume(low_volume)
	shiprailgun_sounds.firing.set_volume(low_volume)
	shiprailgun_sounds.end.set_volume(low_volume)
	shipmissile_sounds.firing.set_volume(low_volume)
	shipexplode_sounds.start.set_volume(high_volume)

	# Actually, there is no need to import their classes into this file.
	parachutes = Group()
	u_rail = Group()
	u_secondary = Group()
	u_missile = Group()
	u_laser = Group()

	u_i_rail = Group()
	u_i_secondary = Group()
	u_i_missile = Group()
	u_i_laser = Group()

	# Actually, there is no need to import their classes into this file.
	explosions = Group()

	# Actually, there is no need to import their classes into this file.
	helis = Group()
	rockets = Group()
	ad_helis = Group()
	shipbullets = Group()
	shipmissiles = Group()
	helibullets = Group()

	# Create buttons to be pressed.
	play_button_mm = Button(screen, 'Play')
	stats_button_mm = Button(screen, 'Statistics')
	quit_button_mm = Button(screen, 'Quit Game')

	resume_button_esc = Button(screen, 'Resume')
	restart_button_esc = Button(screen, 'Restart Game')
	stats_button_esc = Button(screen, 'Statistics')
	exit_button_esc = Button(screen, 'Exit to Main Menu')
	#settings_button = Button(screen, 'Settings')

	# Reposition Main menu buttons based on the button above it.
	space_btw_buttons = 8
	stats_button_mm.rect.y += space_btw_buttons + play_button_mm.rect.height
	stats_button_mm.msg_image_rect.centery = stats_button_mm.rect.centery
	quit_button_mm.rect.y = space_btw_buttons + stats_button_mm.rect.y + stats_button_mm.rect.height
	quit_button_mm.msg_image_rect.centery = quit_button_mm.rect.centery

	# Reposition Esc menu buttons based on the button above it.
	restart_button_esc.rect.y += space_btw_buttons + resume_button_esc.rect.height
	restart_button_esc.msg_image_rect.centery = restart_button_esc.rect.centery
	stats_button_esc.rect.y = space_btw_buttons + restart_button_esc.rect.y + restart_button_esc.rect.height
	stats_button_esc.msg_image_rect.centery = stats_button_esc.rect.centery
	exit_button_esc.rect.y = space_btw_buttons + stats_button_esc.rect.y + stats_button_esc.rect.height
	exit_button_esc.msg_image_rect.centery = exit_button_esc.rect.centery

	#settings_button.rect.y = space_btw_buttons +
	#settings_button.msg_image_rect.centery = settings_button.rect.centery

	#print(pygame.display.Info())

	# Creating list for rocket and ad_helis.
	rockets_hits_list = []
	ad_helis_hits_list = []

	# Ensures that the events, internals and screen is always running.
	while True:
		ai_settings.time_game = float('{:.1f}'.format(get_process_time()))

		# In charge of checking all game events prior to screen updates.
		gf.check_events(ai_settings, screen, ship, shipbullets, shipbullet_sounds, shiprailgun_sounds, shipmissiles, shipmissile_sounds, shipexplode_sounds, parachutes, u_rail, u_secondary, u_missile, u_laser, u_i_rail, u_i_secondary, u_i_missile, u_i_laser, helis, helibullets, rockets, rockets_hits_list, ad_helis, ad_helis_hits_list, explosions, stats, play_button_mm, stats_button_mm, quit_button_mm, resume_button_esc, restart_button_esc, stats_button_esc, exit_button_esc, sb, gameclock)

		# Updates all game internal functions prior to screen updates and only when game is active.
		if stats.game_active:
			#ai_settings.time_game_play = float('{:.1f}'.format(get_process_time()))
			# When the game is active, calculate the play time.
			ai_settings.time_game_total_play = ai_settings.time_game - ai_settings.time_game_start - ai_settings.time_game_total_pause

			gf.update_internals(ai_settings, screen, ship, shipbullets, shipbullet_sounds, shiprailgun_sounds, shipmissiles, shipmissile_sounds, shipexplode_sounds, parachutes, u_rail, u_secondary, u_missile, u_laser, u_i_rail, u_i_secondary, u_i_missile, u_i_laser, helis, helibullets, rockets, rockets_hits_list, ad_helis, ad_helis_hits_list, explosions, stats, sb, gameclock)
		elif stats.game_pause:
			# When the game is paused, only update/calculate the pause time.
			ai_settings.time_game_single_pause = ai_settings.time_game - ai_settings.time_game_pause_start

		# Updates the screen with all the objects and projectiles.
		gf.update_screen(ai_settings, screen, ship, shipbullets, shipmissiles, parachutes, u_rail, u_secondary, u_missile, u_laser, u_i_rail, u_i_secondary, u_i_missile, u_i_laser, helis, helibullets, rockets, ad_helis, explosions, stats, play_button_mm, stats_button_mm, quit_button_mm, resume_button_esc, restart_button_esc, stats_button_esc, exit_button_esc, sb, gameclock, bg)

run_game()


import torch
import torch.nn.functional as F
from torch import nn
import torch.optim as optim
import numpy as np
from network import d_net, g_net
import torchvision.utils as vutils
from opts_fine_tune_discriminator import parse_opts_ft
from opts import parse_opts
from fine_tune_dicriminator import fine_tune
from utils import gaussian
from dataloader import load_data
from sklearn import metrics
import os
import wandb

def check_auc(g_model_path, d_model_path, i):
    opt_auc = parse_opts()
    opt_auc.batch_shuffle = False
    opt_auc.drop_last = False
    opt_auc.data_path = './data/avenue_full/testing'
    dataloader = load_data(opt_auc)
    print_len = True
    # if i == 1 and print_len == True:
    #     print("Length of training data: {0}".format(len(dataloader)))
    #     print_len = False
    model = OGNet(opt_auc, dataloader)
    model.cuda()
    d_results, labels = model.test_patches(g_model_path, d_model_path, i)
    d_results = np.concatenate(d_results)
    labels = np.concatenate(labels)
    fpr1, tpr1, thresholds1 = metrics.roc_curve(labels, d_results, pos_label=1)  # (y, score, positive_label)
    fnr1 = 1 - tpr1
    eer_threshold1 = thresholds1[np.nanargmin(np.absolute((fnr1 - fpr1)))]
    EER1 = fpr1[np.nanargmin(np.absolute((fnr1 - fpr1)))]
    d_f1 = np.copy(d_results)
    d_f1[d_f1 >= eer_threshold1] = 1
    d_f1[d_f1 < eer_threshold1] = 0
    f1_score = metrics.f1_score(labels, d_f1, pos_label=0)
    AUC = metrics.auc(fpr1, tpr1)
    print("AUC: {0}, EER: {1}, EER_thr: {2}, F1_score: {3}".format(AUC, EER1,
                                                                  eer_threshold1,f1_score))
    return AUC, f1_score, d_results

class OGNet(nn.Module):
    @staticmethod
    def name():
        return 'Old is Gold: Redefining the adversarially learned one-class classification paradigm'

    def __init__(self, opt, dataloader):
        super(OGNet, self).__init__()
        self.adversarial_training_factor  = opt.adversarial_training_factor
        self.g_learning_rate = opt.g_learning_rate
        self.d_learning_rate = opt.d_learning_rate
        self.epoch = opt.epoch
        self.batch_size = opt.batch_size
        self.n_threads = opt.n_threads
        self.sigma_noise = opt.sigma_noise
        self.dataloader = dataloader
        self.c = opt.nc
        self.g = g_net(self.c).cuda()
        self.d = d_net(self.c).cuda()
        self.image_grids_numbers = opt.image_grids_numbers
        self.filename = ''
        self.n_row_in_grid = opt.n_row_in_grid
        self.wandb = opt.wandb

    def train(self, normal_class):

        if self.wandb:
            wandb.init(project="VGIS10_OGNet",

            config={
                "g_learning_rate": self.g_learning_rate,
                "d_learning_rate" : self.d_learning_rate,
                "Sigma noise" : self.sigma_noise,
                "number of image channels" : self.c,
                "dataset": 'avenue',
                "epochs" : self.epoch,
                "batch size" : self.batch_size,
                "Dataloader size" : len(self.dataloader)
                },
                name="avenue_{4}_{0}_{1}_glr{2}_dlr{3}".format(self.epoch, self.batch_size, self.g_learning_rate, self.d_learning_rate, len(self.dataloader), len(self.dataloader)) # Name conversion: dataset_dataloaderLen_epoch_batchsize_glr_dlr
            )

        AUC_phase1 = []
        F1_score_phase1 = []

        AUC_phase2 = []
        F1_score_phase2 = []

        self.g.train()
        self.d.train()
        print("Length of dataloader:", len(self.dataloader))

        # Set optimizators
        g_optim = optim.Adam(self.g.parameters(), lr=self.g_learning_rate)
        d_optim = optim.Adam(self.d.parameters(), lr=self.d_learning_rate)

        fake = torch.ones([self.batch_size], dtype=torch.float32).cuda()
        valid = torch.zeros([self.batch_size], dtype=torch.float32).cuda()
        print('Training until high epoch...')
        for num_epoch in range(self.epoch):
            # print("Epoch {0}".format(num_epoch))
            for i, data in enumerate(self.dataloader):
                input, gt_label = data
                input = input.cuda()
                # print("Torch input tensor min/max values: ", (torch.min(input), torch.max(input)))

                g_optim.zero_grad()
                d_optim.zero_grad()
                sigma = self.sigma_noise ** 2
                input_w_noise = gaussian(input, 1, 0, sigma)  #Noise
                # Inference from generator
                g_output = self.g(input_w_noise)

                vutils.save_image(input[0:self.image_grids_numbers, :, :, :],
                                './results/%03d_real_samples_epoch.png' % (num_epoch), nrow=self.n_row_in_grid, normalize=True)
                vutils.save_image(g_output[0:self.image_grids_numbers, :, :, :],
                                './results/%03d_fake_samples_epoch.png' % (num_epoch), nrow=self.n_row_in_grid, normalize=True)
                vutils.save_image(input_w_noise[0:self.image_grids_numbers, :, :, :],
                                './results/%03d_noise_samples_epoch.png' % (num_epoch), nrow=self.n_row_in_grid, normalize=True)

                ##############################################

                d_fake_output = self.d(g_output)
                d_real_output = self.d(input)
                d_fake_loss = F.binary_cross_entropy(torch.squeeze(d_fake_output), fake)
                d_real_loss = F.binary_cross_entropy(torch.squeeze(d_real_output), valid)
                d_sum_loss = 0.5 * (d_fake_loss + d_real_loss)
                d_sum_loss.backward(retain_graph=True)
                g_optim.zero_grad()

                ##############################################
                g_recon_loss = F.mse_loss(g_output, input)
                g_adversarial_loss = F.binary_cross_entropy(d_fake_output.squeeze(), valid)
                g_sum_loss = (1-self.adversarial_training_factor)*g_recon_loss + self.adversarial_training_factor*g_adversarial_loss
                g_sum_loss.backward()

                d_optim.step()
                g_optim.step()

                if self.wandb:
                    wandb.log({'Loss_G' : g_sum_loss, 'Recon_G_loss': g_recon_loss, 'Loss_D_fake': d_fake_loss, 'Loss_D_real' : d_real_loss, 'G_adversarial_loss' : g_adversarial_loss})

                high_epoch_g_model_name = 'g_high_epoch'
                high_epoch_d_model_name = 'd_high_epoch'
                g_model_save_path = './models/' + high_epoch_g_model_name
                d_model_save_path = './models/' + high_epoch_d_model_name

                if i%1000 == 0:
                        opts_ft = parse_opts_ft() #opts for phase two
                        print("Epoch: [{0} / {1}], Loss G: {2}, G Recon Loss: {3}, G Adv. Loss: {4}, D loss: {7}, D loss real: {5}, D loss fake: {6}".format(num_epoch, opts_ft.high_epoch, g_sum_loss, g_recon_loss, g_adversarial_loss, d_real_loss, d_fake_loss, d_sum_loss))
                        # print("Loss G: {0}, G Recon Loss: {1}, G Adv. Loss: {2}, D loss real: {3}, D loss fake: {4}".format(g_sum_loss, g_recon_loss, g_adversarial_loss, d_real_loss, d_fake_loss))
                        if self.wandb:
                            pixels_gen = g_output[0].detach().cpu().permute(1,2,0).numpy()
                            pixels_noise = input_w_noise[0].detach().cpu().permute(1,2,0).numpy()
                            pixels_input = input[0].detach().cpu().permute(1,2,0).numpy()
                            np.rot90(pixels_gen, k=0, axes=(1,0))
                            np.rot90(pixels_noise, k=0, axes=(1,0))
                            np.rot90(pixels_input, k=0, axes=(1,0))

                            fake_image = wandb.Image(pixels_gen, caption="Generator Image epoch {0}".format(num_epoch))
                            noisy_image_fake = wandb.Image(pixels_noise, caption="Noisy input sample epoch {0}".format(num_epoch))
                            input_image = wandb.Image(pixels_input, caption="Input image epoch {0}".format(num_epoch))

                            wandb.log({'Input image': input_image, 'Noisy image sample': noisy_image_fake, 'Generator Image': fake_image})

                if i%1 == 0:
                    opts_ft = parse_opts_ft() #opts for phase two

                    if num_epoch == opts_ft.low_epoch:
                        g_model_name = 'g_low_epoch'
                        model_save_path = './models/' + g_model_name
                        torch.save({
                            'epoch': num_epoch,
                            'g_model_state_dict': self.g.state_dict(),
                            'g_optimizer_state_dict': g_optim.state_dict(),
                        }, model_save_path)

                    if num_epoch >= opts_ft.high_epoch:
                        g_model_name = 'g_high_epoch'
                        d_model_name = 'd_high_epoch'
                        model_save_path = './models/' + g_model_name
                        torch.save({
                            'epoch': num_epoch,
                            'g_model_state_dict': self.g.state_dict(),
                            'g_optimizer_state_dict': g_optim.state_dict(),
                        }, model_save_path)

                        model_save_path = './models/' + d_model_name
                        torch.save({
                            'epoch': num_epoch,
                            'd_model_state_dict': self.d.state_dict(),
                            'd_optimizer_state_dict': d_optim.state_dict(),
                        }, model_save_path)

                        print('Epoch {0} / Iteration {1}, before phase two: '.format(num_epoch, i))

                        auc, F1_score, results = check_auc(g_model_save_path, d_model_save_path,1)
                        AUC_phase1.append(auc)
                        # EER_phase1.append(EER_pre)
                        # EER_thres_phase1.append(eer_thres_pre)
                        F1_score_phase1.append(F1_score)

                        fine_tune() #Phase two
                        print('After phase two: ')

                        auc2, F1_score2, dresults = check_auc(g_model_save_path, d_model_save_path,1)
                        AUC_phase2.append(auc2)
                        # EER_phase2.append(EER_post)
                        # EER_thres_phase2.append(eer_thres_post)
                        F1_score_phase2.append(F1_score2)

                        if self.wandb:
                            wandb.log({'AUC_phase_1' : AUC_phase1 , 'F1_score_phase_1' : F1_score_phase1, 'AUC_phase_2' : AUC_phase2 , 'F1_score_phase_2' : F1_score_phase2 })
                        #     wandb.log({'AUC_phase_2' : AUC_phase2 ,'EER1_phase_2': EER_phase2, 'EER1_thresh_phase_2' : EER_thres_phase2, 'F1_score_phase_2' : F1_score_phase2}, step=i)

    def test_patches(self,g_model_path, d_model_path,i):  #test all images/patches present inside a folder on given g and d models. Returns d score of each patch
        test_opts = parse_opts()
        checkpoint_epoch_g = -1
        g_checkpoint = torch.load(g_model_path)
        self.g.load_state_dict(g_checkpoint['g_model_state_dict'])
        checkpoint_epoch_g = g_checkpoint['epoch']
        if checkpoint_epoch_g is -1:
            raise Exception("g_model not loaded")
        else:
            pass
        d_checkpoint = torch.load(d_model_path)
        self.d.load_state_dict(d_checkpoint['d_model_state_dict'])
        checkpoint_epoch_d = d_checkpoint['epoch']
        if checkpoint_epoch_g == checkpoint_epoch_d:
            pass
        else:
            raise Exception("d_model not loaded or model mismatch between g and d")

        self.g.eval()
        self.d.eval()
        labels = []
        d_results = []
        count = 0
        for input, label in self.dataloader:
            input = input.cuda()
            g_output = self.g(input)
            d_fake_output = self.d(g_output)

            if count%2000 == 0 and test_opts.wandb:
                pixels_gen = g_output[0].detach().cpu().permute(1,2,0).numpy()
                # pixels_d_fake = d_fake_output[0].detach().cpu().permute(1,2,0).numpy()
                pixels_input = input[0].detach().cpu().permute(1,2,0).numpy()
                np.rot90(pixels_gen, k=0, axes=(1,0))
                # np.rot90(pixels_d_fake, k=0, axes=(1,0))
                np.rot90(pixels_input, k=0, axes=(1,0))

                fake_image = wandb.Image(pixels_gen, caption="Generator Image")
                # noisy_image_fake = wandb.Image(pixels_d_fake, caption="Discriminator fake output")
                input_image = wandb.Image(pixels_input, caption="Input image")

                wandb.log({'Test_image_real': input_image, 'Test_image_fake': fake_image}) #'Discriminator image sample': noisy_image_fake, 'Test_Generator Image': fake_image})

            count +=1
            d_results.append(d_fake_output.cpu().detach().numpy())

            labels.append(label)
            # if test_opts.wandb:
            #     wandb.log({'Discriminator results': d_results, 'Labels': labels})
        return d_results, labels


print("Welcome to Samulator\n version 1.1 Al2O3 ")
print("/***\ /***\ |\  /|   |           TM ");
print("|___  |___| | \/ |   |   _|_      ");
print("    | |   | |    || ||/*\ | /*\|/ ");
print("\___/ |   | |    |\_/|\_/\| \_/|  ");
print("This project follows the GPL v3 lisence.C and Java edition also exist. Copyright® Sam.org\n");
print("issues and pull requests please go to NeXT286@Github or samorg-cpu. Don't be  modest!\n\n\n\n");
print("By SAM.org, bug report hotline:hansonchen600@gmail.com")
choice1=str(input("Do you want to see our update log?    "))
if choice1=="yes":
    print("0.1   Ac  Basic calculation")
def sim():
    H=str(input("the calculation（add the space）："))
    He=str.split()
    if He[1]=="+":
        Li=He[0]+He[1]
    if He[1]=="-":
        Li=He[0]-He[1]
    if He[1]=="*":
        Li=He[0]*He[1]
    if He[1]=="/":
        Li=He[0]/He[1]
    if He[1]=="**" or He[1]=="^":
        Li=He[0]**He[1]


# 소수 찾기

from itertools import permutations

def solution(numbers):
    items = list(str(numbers))
    combinations = []
    for i in range(1, len(items)+1):
        combinations += list(permutations(items, i))
        # print(combinations)
    combinations = [int("".join(c)) for c in combinations]

    result = True
    prime = 0
    for combination in combinations:
        # print(combination)
        for i in range(2, combination):
            if combination < 2 or combination % i == 0:
                print(combination, "False")
                # array.append(combination)
                break
        if result:
          # print(combination, "True")
          prime += 1

    return prime

print(solution(17))
# print(solution(011))


import spacy
from spacy.tokens import Doc

SPACY_LANGUAGE_MODEL_DICT = {
    "english": "en_core_web_trf",
    "spanish": "es_dep_news_trf",
}

SPACY_DICT = {

}

def get_spacy_model(language: str, whitespace_tokenizer = False) -> spacy.language.Language:
    """
    Provides an efficient way to get spacy's languages models.

    language: Language of the model to get
    """
    try:
        model = SPACY_LANGUAGE_MODEL_DICT[language]
    except KeyError:
        raise KeyError(f"{language} not supported. Supported languages: {', '.join(SPACY_LANGUAGE_MODEL_DICT)}")
    if model not in SPACY_DICT:
        nlp = spacy.load(model)
        if whitespace_tokenizer:
            nlp.tokenizer = WhitespaceTokenizer(nlp.vocab)
        SPACY_DICT[model] = nlp
    return SPACY_DICT[model]

class WhitespaceTokenizer:
    def __init__(self, vocab):
        self.vocab = vocab

    def __call__(self, text: str):
        words = text.split()
        # All tokens 'own' a subsequent space character in this tokenizer
        spaces = [True] * len(words)
        return Doc(self.vocab, words=words, spaces=spaces)


#Glacier Model
#Created February 16 2016

from __future__ import division
import numpy as np
from matplotlib import pyplot as plt

class Glacier:

    def start_conds(self, t_min, t_max, dt, x_min, x_max, dx, zmax, s, h0):
        self.timestep = np.arange(t_min, t_max+dt, dt)
        self.spacestep = np.arange(x_min, x_max, dx)
        self.zb = zmax-s*(self.spacestep)
        self.h=np.zeros(len(self.zb))+h0
        self.z=self.zb+self.h
        self.fb = plt.figure(figsize=(10,8)) #figure blueprint
        self.figure1 = plt.subplot(211)
        self.figure2 = plt.subplot(212)
        #inital plot of ELA line
        self.ELA=ELA_mean+ (Amp*np.sin(2*np.pi*(self.timestep/P)))
        self.figure2.plot(self.timestep, self.ELA, color='k')
        plt.ion()
        plt.show()

    def ELA_func(self, Amp, P, ELA_mean):
       self.ELA = ELA_mean + (Amp*np.sin(2*np.pi*(self.timestep[t]/P)))
       return self.ELA

    def b_func (self, gamma, Amp, P, ELA_mean):
        self.b = gamma*(self.z-glacier_model.ELA_func(Amp, P, ELA_mean))
        return self.b

    def slope_func (self, dx):
        self.slope = np.diff(self.z)/dx
        return self.slope

    def havg_func(self):
        self.havg=(self.h[0:-1]+self.h[1:])/2
        return self.havg

    def q_func(self, A, density_ice, g, dx):
        self.q=A*((density_ice*g*glacier_model.slope_func(dx))**3)*(glacier_model.havg_func()**5)/5
        self.q=np.insert(self.q,0,0)
        self.q=np.append(self.q,0)
        return self.q

    def dqdx_func(self, dx):
        self.dqdx=-(np.diff(glacier_model.q_func(A, density_ice, g, dx))/dx)
        return self.dqdx

    def run (self, gamma, Amp, P, ELA_mean, dt, dx):
        global t  #make global so that it can be used in ELA_func as index
        for t in range(len(self.timestep)):
            self.dqdx=glacier_model.dqdx_func(dx)
            self.dhdt=glacier_model.b_func(gamma, Amp, P, ELA_mean)-self.dqdx
            self.h+=self.dhdt*dt
            for i in range(0, len(self.h)): #make sure bottom limit of z does not go below zb
                if self.h[i]<0:
                    self.h[i]=0
            self.z=self.h+self.zb
            if self.timestep[t] % 10 ==0:
                #figure 1 Glacier accumulation
                self.figure1.clear()
                self.figure1.set_title('Glacier Accumulation & Ablation Over Time')
                self.figure1.set_xlabel('Distance (m)')
                self.figure1.set_ylabel('Elevation (m)')
                self.figure1.set_ylim(2000,4000) #make sure y axis doesn't change
                self.figure1.set_xlim(0, 15000) #make sure x axis doesn't change
                self.figure1.text(12500, 2900, 'Time [yrs]: %d\nELA=%d m' % (self.timestep[t], self.ELA))
                self.figure1.plot(self.spacestep, self.z, label='Glacier Height', color='b')
                self.figure1.plot(self.spacestep, self.zb, label='Bedrock Height', color='k')
                self.figure1.plot(self.spacestep, (np.zeros(len(self.spacestep))+self.ELA),  '--r', label='ELA')
                self.figure1.fill_between(self.spacestep, self.zb, self.z, color ='b', interpolate=True)
                self.figure1.fill_between(self.spacestep, 0, self.zb, color='k', interpolate=True)
                self.figure1.legend()
                #figure 2 ELA line
                self.figure2.set_title('ELA Oscillation')
                self.figure2.set_xlabel('Time (yrs)')
                self.figure2.set_ylabel('Elevation(m)')
                h=self.figure2.plot(self.timestep[t], self.ELA, 'ro')
                plt.pause(0.00001)
                l=h.pop(0) #remove last plot entry
                l.remove()
        plt.ioff()

    def finalize(self):
        self.fb.savefig('kwentz_pset5.png', bbox_inches='tight')

if __name__== "__main__":
        t_min=0.0 #years
        t_max=400.0 # years
        dt=0.001 #years
        x_min=0.0 #m
        x_max=16000.0 #m
        dx=100.0 #m
        zmax=2550 #m
        s=0.03 #slope of glacier elevation linear function
        h0=0.0 #m
        gamma=0.01 #m/yr
        ELA_mean= 2450 #m
        Amp=25 #m
        P=50 #years
        A=(2.1*10**(-16)) #Pa-3yr-1
        density_ice=917 #kgm-3
        g=9.81 #ms-2

        glacier_model=Glacier()

        #initiallize
        glacier_model.start_conds(t_min, t_max, dt, x_min, x_max, dx, zmax, s, h0)
        #run
        glacier_model.run(gamma, Amp, P, ELA_mean, dt, dx)
        #finalize
        glacier_model.finalize()


import csv
import cv2
import sklearn
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.utils import shuffle
from keras.models import Model, Sequential
from keras.callbacks import ModelCheckpoint
from keras.layers import Flatten, Dense, Lambda, Cropping2D, Input, Conv2D, MaxPooling2D, Dropout, Reshape
from keras.optimizers import Adamax, Adam

###Load data
#Load csv
def load_samples(file):
    lines = []
    with open(file) as csvfile:
        reader = csv.reader(csvfile)
        for line in reader:
            lines.append(line)
    return lines

#Compute number of samples
def compute_num_samples(num, flip=False, left_rigth_camera=False):
    samples = num
    if flip:
        samples = samples + num
    if left_rigth_camera:
        samples = samples + num*2
    return samples

#Generator of data for real time augmentation: flip and left/rigth cameras
def generator(path, samples, batch_size=32, flip=False, left_rigth_camera=False):
    #Open image
    def open_image(path, line):
        filename = line.split('/')[-1]
        filename_path = (path + 'IMG/' + filename)
        image = cv2.imread(filename_path, cv2.IMREAD_COLOR)
        #Adjust color space because OpenCv uses BGR and simulator RGB
        image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
        #Crop the image
        image = image[70:140, 0:320]
        #Resize to 200x66 pixels
        image = cv2.resize(image, (200, 66), interpolation=cv2.INTER_AREA)
        return image

    num_samples = len(samples)
    while 1:
        shuffle(samples)
        for offset in range(0,num_samples, batch_size):
            batch_samples = samples[offset:offset+batch_size]

            images = []
            measurements = []
            for line in batch_samples:
                image = open_image(path, line[0])
                images.append(image)
                measurement_center = float(line[3].replace(',','.'))
                measurements.append(measurement_center)
                if flip:
                    image = cv2.flip(image, 1)
                    images.append(image)
                    measurements.append(measurement_center*-1)
                if left_rigth_camera:
                    correction = 0.25
                    measurement_left  = min(measurement_center + correction,1) #min 1
                    measurement_right = max(measurement_center - correction,-1) #max -1
                    #Left
                    image = open_image(path, line[1])
                    images.append(image)
                    measurements.append(measurement_left)
                    #Right
                    image = open_image(path, line[2])
                    images.append(image)
                    measurements.append(measurement_right)
            X_train = np.array(images)
            y_train = np.array(measurements)
            yield sklearn.utils.shuffle(X_train, y_train)

#Get sample files (csv files)
samples1 = load_samples('videos/merge/new1.csv')
samples2 = load_samples('videos/merge/new2.csv')
samples3 = load_samples('videos/merge/new3.csv')
samples4 = load_samples('videos/merge/driving_log2.csv')
samples5 = load_samples('videos/merge/slow_log1.csv')
samples6 = load_samples('videos/merge/corner_log3.csv')
samples7 = load_samples('videos/merge/driving_log5.csv')
samples8 = load_samples('videos/merge/driving_log6.csv')
samples = samples1 + samples2 + samples3 + samples4 + samples5 + samples6 + samples7 + samples8

#Split dataset into training and validation
train_samples, validation_samples = train_test_split(samples, test_size=0.2)

#Recompute the number of samples because of the augmented images (flip, left and rigth images)
train_samples_size = compute_num_samples(len(train_samples), flip=True, left_rigth_camera=True)
validation_samples_size = compute_num_samples(len(validation_samples), flip=True, left_rigth_camera=True)

#Get Generators for training and validation
#Batch size depends on the augmented images (256 x 4 = 1028).
train_generator = generator('videos/merge/', train_samples, batch_size = 256, flip=True, left_rigth_camera=True)
validation_generator = generator('videos/merge/', validation_samples, batch_size = 256, flip=True, left_rigth_camera=True)

#Image input shape
input_shape = (66, 200, 3)

###Image Pre-Processing
#Normalization
normalize = Lambda(lambda x: ((x - 125.0) / 255.0), input_shape=input_shape, output_shape=input_shape)

###Nvidea Convolution Neural Network
model = Sequential()
model.add(normalize)
#Convolutions Layers
model.add(Conv2D(24, 5, 5, border_mode='valid', activation='relu', subsample=(2, 2)))
model.add(Conv2D(36, 5, 5, border_mode='valid', activation='relu', subsample=(2, 2)))
model.add(Conv2D(48, 5, 5, border_mode='valid', activation='relu', subsample=(2, 2)))
model.add(Conv2D(64, 3, 3, border_mode='valid', activation='relu', subsample=(1, 1)))
model.add(Dropout(0.2))
model.add(Conv2D(64, 3, 3, border_mode='valid', activation='relu', subsample=(1, 1)))
model.add(Dropout(0.2))
#Control Layers
model.add(Flatten())
model.add(Dense(1164, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(100, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(50, activation='relu'))
model.add(Dense(10, activation='relu'))
#Output
model.add(Dense(1, activation='tanh'))

##Training
adam = Adamax()
model.compile(loss='mse', optimizer=adam)
model.summary()
history_object = model.fit_generator(train_generator,
                                     samples_per_epoch=train_samples_size,
                                     validation_data=validation_generator,
                                     nb_val_samples=validation_samples_size,
                                     nb_epoch=5,
                                     verbose=1)

#save model
model.save('model_track2.h5')

### print the keys contained in the history object
print(history_object.history.keys())

### plot the training and validation loss for each epoch
plt.plot(history_object.history['loss'])
plt.plot(history_object.history['val_loss'])
plt.title('model mean squared error loss')
plt.ylabel('mean squared error loss')
plt.xlabel('epoch')
plt.legend(['training set', 'validation set'], loc='upper right')
plt.savefig('loss.png', dpi=100)
plt.show()


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome("chromedriver")

driver.get("https://web.whatsapp.com/")
wait = WebDriverWait(driver, 600)

with open("contact.txt") as f:
	for line in f:
		inp_xpath_search = "//input[@title='Search or start new chat']"
		input_box_search = wait.until(EC.presence_of_element_located((
			By.XPATH, inp_xpath_search)))
		try:
			name = (line.rstrip('\n'))
			var = name.split("/")
			text = """Hello {},
                        var1{}. var2{}, var3{}""".format(var[1], var[3], var[2], var[3], var[4])
			input_box_search.send_keys(var[0])
			time.sleep(10)

			emoji = driver.find_element_by_class_name('chat')

			if emoji:
				input_box_search.send_keys(Keys.ENTER)
				x_arg_contact = '//div[@class="chat-title"]'
				input_box_contact = wait.until(EC.presence_of_element_located((
					By.XPATH, x_arg_contact)))

				time.sleep(2)
				inp_xpath = "//div[@contenteditable='true']"
				input_box = wait.until(EC.presence_of_element_located((
					By.XPATH, inp_xpath)))
				input_box.send_keys(text + Keys.ENTER)

			time.sleep(5)
			print("send")
		except:
			input_box_search.send_keys(Keys.BACKSPACE * 20)
			time.sleep(5)
			print("error")


from django.shortcuts import render
from django.contrib.auth.decorators import login_required

# Create your views here.
from .models import Book

@login_required(login_url='/accounts/login/')
def book_list(request):
    books = Book.objects.all()
    print(books)
    return render(request, 'book_list.html', {
        "books":books
    })


from app.api.classes.day.models import Day
from app.db import db
from sqlalchemy.sql import text
from app.api.classes.observationperiod.services import setObsPerDayId

from flask import jsonify

from datetime import datetime

def addDay(day):
    d = Day.query.filter_by(day = day.day, observatory_id = day.observatory_id, is_deleted = 0).first()
    if  not d and day.observatory_id is not None and day.day is not None and day.observers is not None:
        db.session().add(day)
        db.session().commit()
    else:
        d.is_deleted = 1
        db.session().add(day)
        db.session.commit()
        setObsPerDayId(d.id, day.id)

def getDays():
    dayObjects = Day.query.filter_by(is_deleted=0).all()
    return dayObjects

def getDay(dayId):
    return Day.query.get(dayId)

def getDayId(day, observatory_id):
    d = Day.query.filter_by(day = day, observatory_id = observatory_id, is_deleted = 0).first()
    return d.id

def getLatestDays(observatory_id):
    stmt = text(" SELECT Day.day,"
                " COUNT(DISTINCT (CASE WHEN (Observationperiod.is_deleted = 0 AND Observation.is_deleted = 0) THEN  Observation.species ELSE NULL END)) AS species_count"
                " FROM Day"
                " LEFT JOIN Observationperiod ON Day.id = Observationperiod.day_id"
                " LEFT JOIN Observation ON Observationperiod.id = Observation.observationperiod_id"
                " WHERE Day.observatory_id = :observatory_id"
                " AND Day.is_deleted = 0 "
                " GROUP BY Day.day"
                " ORDER BY Day.day DESC").params(observatory_id = observatory_id)

    res = db.engine.execute(stmt)

    response = []
    i = 0
    for row in res:
        if i == 5:
            break
        i += 1
        dayDatetime = row[0]
        if not isinstance(dayDatetime, datetime):
            dayDatetime = datetime.strptime(dayDatetime, '%Y-%m-%d %H:%M:%S.%f')
        dayString = dayDatetime.strftime('%d.%m.%Y')
        response.append({
            "day": dayString,
            "speciesCount": row.species_count
            })

    return jsonify(response)


# Packages nécessaires
import numpy as np
import re

def clean_and_tokenize(text):
    """
    Cleaning a document with:
        - Lowercase
        - Removing anything that is not letters
    (Of course, we can use regular expression to do more elaborate pre-processing....)
    And separate the document into words by simply splitting at spaces
    Params:
        text (string): a sentence or a document
    Returns:
        tokens (list of strings): the list of tokens (word units) forming the document
    """
    # Lowercase
    text = text.lower()
    # Remove anything but letters
    text = re.sub(r"[^a-z]+", " ", text)

    tokens = text.split()
    return tokens

def vocabulary(corpus, voc_threshold=None):
    """
    Function using word counts to build a vocabulary
    Params:
        corpus (list of list of strings): corpus of sentences
        voc_threshold (int): maximum size of the vocabulary - 0 (default) indicates there is no max
    Returns:
        vocabulary (dictionary): keys: list of distinct words across the corpus
                                 values: indexes corresponding to each word sorted by frequency
        vocabulary_word_counts (dictionary): keys: list of distinct words across the corpus
                                             values: word counts in the corpus
    """
    word_counts = {}

    # Count the occurrences of each word in the corpus
    for sentence in corpus:
        for word in clean_and_tokenize(sentence):
            word_counts[word] = word_counts.get(word, 0) + 1

    # Sort the words based on their frequency
    sorted_word_counts = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)

    # Truncate the sorted word counts based on the vocabulary threshold if provided
    if voc_threshold and voc_threshold > 0:
        sorted_word_counts = sorted_word_counts[:voc_threshold]
    sorted_word_counts.append(('UNK', 1))

    # Create the vocabulary and vocabulary_word_counts dictionaries
    vocabulary = {word: index for index, (word, _) in enumerate(sorted_word_counts)}
    vocabulary_word_counts = {word: count for word, count in sorted_word_counts}

    return vocabulary, vocabulary_word_counts

def co_occurence_matrix(corpus, vocabulary, window=0, distance_weighting=False):
    """
    Params:
        corpus (list of list of strings): corpus of sentences
        vocabulary (dictionary): words to use in the matrix
        window (int): size of the context window; when 0, the context is the whole sentence
        distance_weighting (bool): indicates if we use a weight depending on the distance between words for co-oc counts
    Returns:
        matrix (array of size (len(vocabulary), len(vocabulary))): the co-oc matrix, using the same ordering as the vocabulary given in input
    """
    l = len(vocabulary)
    M = np.zeros((l, l))
    for sent in corpus:
        # Get the sentence:
        sent = clean_and_tokenize(sent)
        # Get the indexes of the sentence using the vocabulary:
        sent_idx = [vocabulary.get(word, -1) for word in sent]

        # Go through the sentence indexes and add 1 / dist(i, j) to M[i, j] if words with index i and j appear in the same window.
        for i, idx_i in enumerate(sent_idx):
            # Check if the word is recognized by the vocabulary:
            if idx_i > -1:
                # If we consider a limited context:
                if window > 0:
                    l_ctx_idx = sent_idx[max(0, i - window):i]
                # If we consider that the context is the entire sentence:
                else:
                    l_ctx_idx = sent_idx[:i]

                # Go through this list and update M[i, j]:
                for j, idx_j in enumerate(l_ctx_idx):
                    # ... making sure that the word corresponding to 'idx_j' is recognized by the vocabulary
                    if idx_j > -1:
                        # Calculate the weight:
                        if distance_weighting:
                            weight = 1.0 / (i - j)
                        else:
                            weight = 1.0
                        M[idx_i, idx_j] += weight
                        M[idx_j, idx_i] += weight
    return M


# spector.py
# ALS 2017/06/01

import sys
import numpy as np
import astropy.table as at
import matplotlib.pyplot as plt
import astropy.units as u
from astropy.io import fits
import astropy.constants as const
import modelBC03
import os

from ..obsobj import Operator
from .. import filters
from . import getconti
from . import extrap
from . import linelist
from . import lineflux

class Spector(Operator):

	def __init__(self, **kwargs):
		"""
		Spector, an operator on spectrum

		Params
		----------
		Operator params:
			/either
				obj (object of class obsobj): with attributes ra, dec, dir_obj
			/or
				ra (float)
				dec (float)
				/either
					dir_obj (string)
				/or
					dir_parent (string): attr dir_obj is set to dir_parent+'SDSSJXXXX+XXXX/'

		survey (str):
			survey of the photometric system
			if not provided, use self.obj.survey. Raise exception if self.obj.survey does not exist.
		z (float):
			redshift, if not provided, use obj.z or obj.sdss.z
		survey_spec (str):
			survey of the spectrum
			if not provided, use the instrument of sdss_xid.csv
		decompose_method = 'modelBC03' (str)
			'modelBC03' or 'running_median'
			the method for decomposing spectrum into continuum and lines, and extrapolate the continum.

		Attributes
		----------
		Operator Attributes:
			obj (instance of objObj)
			ra (float)
			dec (float)
			dir_obj (string)

		survey (str): e.g., 'hsc'
			survey of the photometric system
		survey_spec (str): e.g., 'sdss' or 'boss'
			survey of the spectrum
		bands (list):
			e.g., ['g', 'r', 'i', 'z', 'y'] for survey = 'hsc'
		z (float):
		decompose_method (str)
			'modelBC03' or 'running_median'
		conti_model
			if decompose_method is modelBC03 then this is an instance of modelBC03
		"""

		super(Spector, self).__init__(**kwargs)

		# set survey
		if hasattr(self.obj, 'survey'):
			default_survey = self.obj.survey
			self.survey = kwargs.pop('survey', default_survey)
		else:
			self.survey = kwargs.pop('survey')

		# set survey_spec
		self.survey_spec = kwargs.pop('survey_spec', 'auto')

		if self.survey_spec in ['sdss', 'boss', 'eboss', 'auto']:
			if self.survey_spec == 'auto':
				self.obj.add_sdss(toload_photoobj=False)
				self.survey_spec = self.obj.sdss.instrument.lower()

			# # sanity check - spec name consistent
			# if (self.survey_spec != self.obj.sdss.instrument.lower()):
			# 	raise Exception("[spector] survey_spec inconsistent with sdss_xid.csv:instrument")

		# set z
		if 'z' in kwargs:
			self.z = kwargs.pop('z')

		elif hasattr(self.obj, 'z'):
			self.z = self.obj.z

		elif self.survey_spec in ['sdss', 'boss', 'eboss', 'auto']:
			self.obj.add_sdss(toload_photoobj=False)
			self.z = kwargs.pop('z', self.obj.sdss.z)

		# set self.decompose_method
		self.decompose_method = kwargs.pop('decompose_method', 'modelBC03')
		self.conti_model = None

		# set others
		self.bands = filters.filtertools.surveybands[self.survey]
		self.waverange = filters.filtertools.waverange[self.survey]

		# define paths
		self.fp_spec = self.dir_obj+'spec.fits'
		self.fp_spec_decomposed = self.dir_obj+'spec_decomposed.ecsv'
		self.fp_spec_contextrp = self.dir_obj+'spec_contextrp.ecsv'
		self.fp_spec_mag = self.dir_obj+'spec_mag.csv'
		self.fp_spec_lineflux = self.dir_obj+'spec_lineflux.csv'
		self.fp_spec_linefrac = self.dir_obj+'spec_linefrac.csv'

		self.spec, self.ws = self.get_spec_ws()
		self.u_spec = 1.e-17*u.Unit('erg / (Angstrom cm2 s)') # default unit of spec
		self.u_ws = u.AA # default unit of ws

	def get_spec_ws(self, forceload_from_fits=False):
		"""
		read spec and ws, either from spec_decomposed.ecsv or spec.fits (if forced or spec_decomposed.ecsv does not exist)

		Param
		-----
		forceload_from_fits=False:
			if true, then load from fits.

		Return
		------
		spec (astropy table column with unit)
		ws (astropy table column with unit)

		Default units
		-------------
		u_spec = 1.e-17*u.Unit('erg / (Angstrom cm2 s)')
		u_ws = u.AA
		"""

		fn = self.fp_spec_decomposed

		if not os.path.isfile(fn) or forceload_from_fits:
			spec, ws, __ = self.__read_spec_ws_ivar_from_fits()
			return spec, ws
		else:
			tab = at.Table.read(fn, format='ascii.ecsv')
			return tab['spec'], tab['ws']

	def get_spec_ws_from_spectab(self, component, fn=None):
		"""
		read certain spec table.ecsv to get spec of a given component
		if fn not specified then use the default file that would contain the specified component,
		e.g.:
			'spec_decomposed.ecsv' for component = "all", "cont", "line"
			'spec_contextrp.ecsv'    for component = "contextrp"

		Param
		-----
		component:
			either ['all', 'line', 'cont', 'contextrp']
		fn='spec_decomposed.ecsv'

		Return
		------
		spec (astropy table column with unit)
		ws (astropy table column with unit)

		Default units
		-------------
		u_spec = 1.e-17*u.Unit('erg / (Angstrom cm2 s)')
		u_ws = u.AA
		"""
		if fn == None:
			if component in ['all', 'cont', 'line']:
				fn = self.fp_spec_decomposed
				self.make_spec_decomposed_ecsv(overwrite=False)
			elif component in ['contextrp']:
				fn = self.fp_spec_contextrp
				self.make_spec_contextrp_ecsv(overwrite=False)
			else:
				raise Exception("[spector] component not recognized")

		tab = at.Table.read(fn, format='ascii.ecsv')
		col = self.__get_spectab_colname(component)

		return tab[col], tab['ws']

	def make_spec_decomposed_ecsv(self, overwrite=False):
		"""
		saving seperated continuum and line spectrum in csv file

		Params
		------
		self
		overwrite=False

		Return
		------
		status

		note: this part of the code can be refactorized better.

		"""

		fn = self.fp_spec_decomposed

		if (not os.path.isfile(fn)) or overwrite:

			spec, ws = self.get_spec_ws()

			ws_uless = np.array((ws/self.u_ws).to(u.dimensionless_unscaled))
			spec_uless = np.array((spec/self.u_spec).to(u.dimensionless_unscaled))

			iscon, speccont, specline, __, model = getconti.decompose_cont_line_t2AGN(spec_uless, ws_uless, self.z, method=self.decompose_method)

			self.conti_model = model # modelBC03 instance if set method='modelBC03', otherwise None.

			tab = at.Table([ws_uless, spec_uless, speccont, specline, iscon], names=['ws', 'spec', 'speccont', 'specline', 'iscon'])
			tab['ws'].unit = self.u_ws
			tab['spec'].unit = self.u_spec
			tab['speccont'].unit = self.u_spec
			tab['specline'].unit = self.u_spec

			tab.write(fn, format='ascii.ecsv', overwrite=overwrite)

			# sanity check: units are identical
			units = [tab[col].unit for col in ['spec', 'speccont', 'specline']]
			if len(set(units)) > 1:
				raise Exception("[spector] units in table spec_decomposed are not identical")

		status = os.path.isfile(fn)
		return status

	def make_spec_contextrp_ecsv(self, overwrite=False, refit=False):
		"""
		extrapolate continuum to cover all of the wavelength range of filters
		there are two methods:
			for self.conti_model modelBC03: use the bestfit
			for running_median: polynomial fit

		"""
		fn = self.fp_spec_contextrp

		if (not os.path.isfile(fn)) or overwrite:
			speccont, ws = self.get_spec_ws_from_spectab(component='cont')
			ws_uless = np.array((ws/self.u_ws).to(u.dimensionless_unscaled))
			speccont_uless = np.array((speccont/self.u_spec).to(u.dimensionless_unscaled))

			l0, l1 = self.waverange

			if self.decompose_method == 'modelBC03':
				if self.conti_model is None or refit:
					m = modelBC03.modelBC03(extinction_law='none')
					m.fit(ws=ws_uless, spec=speccont_uless, z=self.z)
				else:
					m = self.conti_model # reuse
				speccon_ext = m.bestfit
				ws_ext = m.ws_bestfit

			elif self.decompose_method == 'running_median':
				speccon_ext, ws_ext = extrap.extrap_to_ends(ys=speccont_uless, xs=ws_uless, x_end0=l0, x_end1=l1, polydeg=1, extbase_length=2000.)
			else:
				raise Exception("method is not recognized")

			assert (np.min(ws_ext*self.u_ws) < l0) & (np.max(ws_ext*self.u_ws) > l1)
			col_contextrp = self.__get_spectab_colname('contextrp')
			tab = at.Table([ws_ext, speccon_ext], names=['ws', col_contextrp])
			tab['ws'].unit = self.u_ws
			tab[col_contextrp].unit = self.u_spec
			tab.write(fn, format='ascii.ecsv', overwrite=overwrite)

		status = os.path.isfile(fn)
		return status

	def make_spec_mag(self, overwrite=False):
		"""
		make table spec_mag.csv that contains the convolved spectral magnitude and fnu in each band

		Params
		------
		self
		overwrite=False

		Return
		------
		status
		"""
		#==========================================================================

		fn = self.fp_spec_mag

		self.make_spec_decomposed_ecsv(overwrite=False)

		if not os.path.isfile(fn) or overwrite:
			print("[spector] making spec_mag")
			tabmag = at.Table()
			tabfnu = at.Table()

			for component in ['all', 'cont', 'line', 'contextrp']:
				for band in self.bands:
					colfnu = self.__get_specmag_colname(band, component=component, fluxquantity='fnu')
					colmag = self.__get_specmag_colname(band, component=component, fluxquantity='mag')
					try:
						fnu = self._calc_Fnu_in_band(band=band, component=component)
					except KeyboardInterrupt:
						sys.exit(0)
					except:
						print(("[spector] skip calculating fnu of {} in band {}".format(component, band)))
					else:
						mag = fnu.to(u.ABmag)
						fnu_nm = fnu.to(u.nanomaggy)
						tabmag[colmag] = [mag.value]
						tabfnu[colfnu] = [fnu_nm.value]

			tab = at.hstack([tabmag, tabfnu])
			tab.meta['comments'] = [
									"survey_photo: {}".format(self.survey),
									"survey_spec: {}".format(self.survey_spec),
									"unit_mag: ABmag",
									"unit_fnu: nanomaggy",
									]

			tab.write(fn, comment='#', format='ascii.csv', overwrite=overwrite)
		else:
			print("[spector] skip making spec_mag as file exists")

		status = os.path.isfile(fn)
		return status

	def get_spec_mag_tab(self):
		""" return spec_mag table"""
		self.make_spec_mag(overwrite=False)
		return at.Table.read(self.fp_spec_mag, comment='#', format='ascii.csv')

	def get_spec_mag_value(self, band, component='all', fluxquantity='mag'):
		"""
		return requested value, reading from spec_mag.csv

		Params
		------
		component='line':
			or 'all', 'cont', 'contextrp'
		fluxquantity='mag'
		band='i'

		Return
		------
		x (float): the value
		"""
		tab = self.get_spec_mag_tab()
		col = self.__get_specmag_colname(band=band, component=component, fluxquantity=fluxquantity)

		return tab[col][0]

	def get_fnu_ratio_band1_over_band2(self, band1, band2, component='all'):
		"""
		return fnu_band1/fnu_band2

		Params
		------
		band1, band2, component='all'

		Return
		------
		x (float): the ratio
		"""
		fluxquantity = 'fnu'
		tab = self.get_spec_mag_tab()
		col1 = self.__get_specmag_colname(band=band1, component=component, fluxquantity=fluxquantity)
		col2 = self.__get_specmag_colname(band=band2, component=component, fluxquantity=fluxquantity)

		ratio = tab[col1][0]/tab[col2][0]

		return ratio

	def plot_spec(self, wfilters=True, wconti=True, wcontextrp=True, wline=True, wspec=True, overwrite=True):
		"""
		Params
		------
		self
		wfilters=True
		wconti=False

		Return
		------
		status (bool)
		"""
		fn = self.dir_obj+'spec.pdf'

		if not os.path.isfile(fn) or overwrite:
			plt.close('all')
			plt.figure(1, figsize=(12, 6))
			plt.clf()

			plt.plot(0., 0., ls='', color='black', label='z='+'%.3f'%self.z) # show z in legend

			if wfilters:
				for band in self.bands:
					trans, ws_trans = self._get_norm_trans_func(band=band)
					plt.plot(ws_trans, trans/max(trans), label=band)

			if wspec:
				spec, ws = self.get_spec_ws()
				norm = max(spec)
				plt.plot(ws, spec/norm, color='0.3', lw=1.5, label='__nolabel__')

			if wline:
				speccont, ws = self.get_spec_ws_from_spectab(component='cont')
				specline, ws = self.get_spec_ws_from_spectab(component='line')
				specplot = specline+speccont
				specplot[specline==0] = np.nan
				plt.plot(ws, specplot/norm, color='black', lw=1.5, label='line')

			if wconti:
				speccont, ws = self.get_spec_ws_from_spectab(component='cont')
				plt.plot(ws, speccont/norm, color='cyan', lw=2, label='continuum')

			if wcontextrp:
				speccextrp, ws = self.get_spec_ws_from_spectab(component='contextrp')
				plt.plot(ws, speccextrp/norm, color='grey', lw=0.5, label='extrapolated conti')

			plt.legend(loc='upper right')
			if self.survey_spec == 'sdss':
				plt.xlim(2980.0, 11230.0)
			elif self.survey_spec == 'boss':
				plt.xlim(3500.0, 12000.0)
			plt.ylim(0., 1.)
			plt.savefig(fn, overwrite=overwrite)

		status = os.path.isfile(fn)
		return status

	def calc_fline_over_fnuband(self, band, line):
		"""
		calculate the conversion ratio r = (flux_line / fnu_band), to convert continuum subtracted image to line intensity map

		by multiplying this ratio to the band image (in fnu [erg/s/cm^2/Hz]) one can obtain the observed flux of the line (in f [erg/s/cm^2]). Notice that this is flux in observed frame, for measurements one still needs to transform it to the rest frame (depending on z).

		r = (c / (T(w_k) * w_k)) * frac_k  := dnu * frac_k

			where
				dnu    =  (c / (T(w_k) * w_k))
				frac_k = (f_k * T(w_k) * w_k) / sum(f_i * T(w_i) * w_i)

		Params
		------
		self
		band (str)
		line (str)

		Return
		------
		ratio (quantity in unit of Hz)
		"""
		f, __ = self._get_line_flux(line=line, wunit=False)
		w = self._get_line_obs_wave(line=line, wunit=False)
		T = self._get_norm_trans(wavelength=w, band=band, bounds_error=True)

		dnu = const.c / (T * w * u.AA)

		frac = self._get_line_frac(band=band, line=line)

		# sanity check: all strong lines are considered
		tab_linefrac = at.Table.read(self.fp_spec_linefrac, format='ascii.csv', comment='#')
		stronglines = self._list_stronglines_in_band(band=band)
		for line in stronglines:
			if 'frac_{}'.format(line) not in tab_linefrac.colnames:
				raise Exception("[spector] strong line {} in band is not contained in spec_linefrac.csv".format(line))

		r = (dnu * frac).to(u.Hz)
		return r

	def _get_line_frac(self, band, line='OIII5008'):
		"""
		read line flux from file spec_linefrac.csv.

		Params
		------
		band, line='OIII5008', wunit=False

		Return
		------
		frac (float)
		"""
		fn = self.fp_spec_linefrac

		if not os.path.isfile(fn):
			self.make_linefrac(band=band, overwrite=False)

		tab = at.Table.read(fn, format='ascii.csv', comment='#')

		if tab['lineband'][0] != band:
			raise Exception("[spector] _get_line_frac the band required is not provided by the current spec_linefrac.csv")

		linetag = 'frac_{}'.format(line)
		frac = tab[linetag][0]

		return frac

	def make_linefrac(self, band, lines=['NeIII3870', 'NeIII3969', 'Hg', 'Hb', 'OIII4960', 'OIII5008', 'OI6302', 'OI6366'], tofixOIIIratio=True, overwrite=False):
		"""
		make file spec_linefrac.csv that contains the fraction each of the strong lines have in a specific band.
		Columns: f_{band}_{line}, T_{band}_{line}, w_{band}_{line}, frac_{band}_{line}

		The fraction is based on the f*T*w of the line. Only the strong lines are listed.

		If tofixOIIIratio = True, then the ratio between OIII5008 and OIII4960 is fixed to the theoretical ratio of 2.98, see
		Storey + 2000. http://adsabs.harvard.edu/abs/2000MNRAS.312..813S.

		Params
		------
		band
		lines=['NeIII3870', 'NeIII3969', 'Hg', 'Hb', 'OIII4960', 'OIII5008', 'OI6302', 'OI6366']
		tofixOIIIratio=True
		overwrite=False

		Return
		------
		status
		"""
		fn = self.fp_spec_linefrac

		self.make_lineflux(overwrite=overwrite)

		if not os.path.isfile(fn) or overwrite:
			print("[spector] making spec_linefrac")

			tab = at.Table([[band]], names=['lineband'])

			fwt_sum = 0.
			for line in lines:
				f, __ = self._get_line_flux(line=line, wunit=False)
				w = self._get_line_obs_wave(line=line, wunit=False)
				T = self._get_norm_trans(wavelength=w, band=band, bounds_error=False)

				fwt = max(f*w*T, 0)
				fwt_sum = fwt_sum + fwt

				col_new = at.Table([[f], [w], [T], [fwt]], names=['f_{}'.format(line), 'w_{}'.format(line), 't_{}'.format(line), 'fwt_{}'.format(line)])
				tab = at.hstack([tab, col_new])

			for line in lines:
				frac = tab['fwt_{}'.format(line)][0] / fwt_sum
				col_new = at.Table([[frac]], names=['frac_{}'.format(line)])
				tab = at.hstack([tab, col_new])

			if tofixOIIIratio:
				r = 2.98
				frac_OIIItotal = tab['frac_OIII4960'] + tab['frac_OIII5008']
				tab['frac_OIII5008'] = frac_OIIItotal * r / (1.+r)
				tab['frac_OIII4960'] = frac_OIIItotal * 1. / (1.+r)

			tab.write(fn, format='ascii.csv', overwrite=overwrite)

		else:
			print("[spector] skip making spec_linefrac as file exists")

		status = os.path.isfile(fn)
		return status

	def make_lineflux(self, lines=['NeIII3870', 'NeIII3969', 'Hg', 'Hb', 'OIII4960', 'OIII5008', 'OI6302', 'OI6366'], u_flux=u.Unit("1E-17 erg cm-2 s-1"), overwrite=False):
		"""
		make file spec_lineflux.csv that contains the flux of the specified lines. The fluxes are calculated by integrating the line component of the spectrum over a window of +/- 1400 km/s.

		WARNING: currently only Hb, and OIII lines are supported. For lines that are overlapped, e.g., Ha and NII, the current implemenation will double count the flux.

		Params
		------
		lines=['Hb', 'OIII4960', 'OIII5008']
		u_flux=u.Unit("1E-17 erg cm-2 s-1")
			the unit of the output
		overwrite=False

		Return
		------
		status (bool)
		"""
		fn = self.fp_spec_lineflux

		self.make_spec_decomposed_ecsv(overwrite=False)

		if not os.path.isfile(fn) or overwrite:
			print("[spector] making spec_lineflux")
			tab = at.Table()

			for line in lines:
				f, ferr = self._calc_line_flux(line=line, u_flux=u_flux, wunit=False)

				col_new = at.Table([[f], [ferr]], names=['f_{}'.format(line), 'ferr_{}'.format(line)])
				tab = at.hstack([tab, col_new])

			tab.meta['comments'] = ["unit_flux: {}".format(u_flux.to_string()),]

			tab.write(fn, comment='#', format='ascii.csv', overwrite=overwrite)

		else:
			print("[spector] skip making spec_lineflux as file exists")

		status = os.path.isfile(fn)
		return status

	def _calc_line_flux(self, line='OIII5008', dv=1400*u.km/u.s, u_flux=u.Unit("1E-17 erg cm-2 s-1"), wunit=False):
		"""
		calculate the flux of the line by trpz integrating the decomposed emission line component of the spectrum over a range of +/- dv

		WARNING: currently only Hb, and OIII lines are supported. For lines that are overlapped, e.g., Ha and NII, the current implemenation will double count the flux.

		WARNING: the errors of the flux is propogated from the variance ('ivar' column) of the sdss spectrum. However, sdss's noise could be correlated between neighbors but such a covariance is not quantified, which will result in 10-20% in the error estimates.  We here artifically boost the flux error by 20% to incoporate such uncertainty on the error, see:
		http://www.sdss.org/dr12/spectro/caveats/

		Params
		------
		line='OIII5008' (str)

		dv=1400*u.km/u.s (quantity)
			half of the width over which the spectrum is integrated to calculate flux

		u_flux=u.Unit("1E-17 erg cm-2 s-1")
			the unit of the output

		wunit=False
			whether the output to come with unit or not

		Return
		------
		f (float or quantity)
			unit is in the dimension of erg cm-2 s-1
		ferr (float or quantity)
			same unit as f
		"""

		# sanity check
		if line not in ['NeIII3870', 'NeIII3969', 'Hg', 'Hb', 'OIII4960', 'OIII5008', 'OI6302', 'OI6366']:
			raise Exception("[spector] _calc_line_flux does not support lines other than Hb and OIII as those are not tested. ")

		# get w range
		beta = (dv/const.c).to_value(u.dimensionless_unscaled)
		w = self._get_line_obs_wave(line=line, wunit=False)
		w0 = w*(1-beta)
		w1 = w*(1+beta)

		# get spectrum
		spec, ws = self.get_spec_ws_from_spectab(component='line')
		__, __, ivar = self.__read_spec_ws_ivar_from_fits()

		f, ferr = lineflux.calc_line_flux(spec, ws, ivar, w0, w1, u_flux)

		# artificially boost the error to account for pixel covariance
		ferr = ferr * 1.2

		if wunit:
			return f, ferr
		else:
			return f.to_value(u_flux), ferr.to_value(u_flux)

	def _get_line_flux(self, line='OIII5008', wunit=False):
		"""
		read line flux from file spec_lineflux.csv. For details, see make_spec_lineflux().

		Params
		------
		line='OIII5008', wunit=False

		Return
		------
		f, ferr
		"""
		fn = self.fp_spec_lineflux

		if not os.path.isfile(fn):
			self.make_lineflux(overwrite=False)

		tab = at.Table.read(fn, format='ascii.csv', comment='#')

		f = tab['f_{}'.format(line)][0]

		ferr = tab['ferr_{}'.format(line)][0]

		if not wunit:
			return f, ferr

		else:
			u_flux = u.Quantity(tab.meta['comments'][0].split(': ')[1])
			return f*u_flux, ferr*u_flux

	def _get_line_flux_sdss(self, line='OIII5008', wunit=False):
		"""
		Flux of line from SDSS spec.fits higher extensions
		It is measured by Gaussian fit, for details, see:
		http://classic.sdss.org/dr7/dm/flatFiles/spZline.html

		PARAMS
		------
		line = 'OIII5008' (str)
		wunit = False

		Return
		------
		f (float):
			flux
			or astropy quantify with units u.Unit("1E-17 erg cm-2 s-1")
		ferr (float)
			error on flux
			or astropy quantify with units u.Unit("1E-17 erg cm-2 s-1")
		"""

		# get sdss linename
		linename = linelist.sdssLINENAME[line]

		# read flux
		table = self.obj.sdss.get_spec()[3].data
		i = [table['LINENAME']==linename]
		f = table[i]['LINEAREA'][0]
		ferr = table[i]['LINEAREA_ERR'][0]

		if not wunit:
			return f, ferr
		else:
			return f*u.Unit("1E-17 erg cm-2 s-1"), ferr*u.Unit("1E-17 erg cm-2 s-1")

	def _get_line_obs_wave(self, line='OIII5008', wunit=False):
		"""
		PARAMS
		------
		line = 'OIII5008' (str)
		wunit = False

		Return
		------
		w (float):
			redshifted wavelength of line
			or astropy quantify with units u.Unit("AA")
		"""
		w = filters.getllambda(ion=line, vacuum=True) * (1. + self.z)

		try: len(w)
		except:
			pass
		else:
			if len(w) == 1:
				w = w[0]
			else:
				raise Exception('got more than one wavelength')

		if not wunit:
			return w
		else:
			return w*u.Unit("AA")

	def _list_stronglines_in_band(self, band, threshold=0.01):
		"""
		return a list of strong lines in band where the filter transmission function is higher than threshold (in fraction)

		Params
		------
		self
		band (str)
		threshold (float):
			the fractional threshold (relative to the filter peak) that defines the wavelength boundary of a band
		wunit (bool)

		Return
		------
		llist (array of str)
			e.g., ['OIII5008', 'OIII4960', 'Hb', ...]
		"""
		w1, w2 = filters.filtertools.getFilterBoundaries(threshold=threshold, band=band, survey=self.survey, withunit=False)

		llist = []
		for line in linelist.strongline:
			w = self._get_line_obs_wave(line=line, wunit=False)
			if (w > w1) & (w < w2):
				llist += [line]

		return llist

	def __read_spec_ws_ivar_from_fits(self, u_spec=1.e-17*u.Unit('erg / (Angstrom cm2 s)'), u_ws=u.AA, wunit=True):
		"""
		Params
		------
		self
		u_spec=1.e-17*u.Unit('erg / (Angstrom cm2 s)')
		u_ws=u.AA
		wunit=True

		Return
		------
		spec (nparray)
		ws (nparray)
		ivar (nparray)

		Default units
		-------------
		u_spec = 1.e-17*u.Unit('erg / (Angstrom cm2 s)')
		u_ws = u.AA
		"""
		fn = self.fp_spec
		if self.survey_spec in ['sdss', 'boss', 'boss']:
			if os.path.isfile(fn):
				hdus = fits.open(fn)
			else:
				raise IOError("[Spector] spec fits file does not exist")

			hdus[0].header
			spectable = hdus[1].data
			spec, ws, ivar = spectable['flux'], 10.**spectable['loglam'], spectable['ivar']

			if wunit:
				spec = spec*u_spec
				ws = ws*u_ws
				ivar = ivar / (u_spec**2)

			# instrument_header = at.Table(hdus[2].data)['INSTRUMENT'][0].lower()
			# if self.survey_spec != instrument_header:
			# 	self.survey_spec = instrument_header
			# 	print("[Spector] updating survey_spec to reflect instrument in spec.fits header -- {}".format(instrument_header))

			return at.Column(spec, name=['spec']), at.Column(ws, name=['ws']), at.Column(ivar, name=['ivar'])
		else:
			raise NameError("[Spector] survey_spec not recognized")

	def _get_norm_trans_func(self, band='i'):
		"""
		return normalized transmission function and its wavelength coordinate
		the normalization is such that int{ trans{l} * dlnl} = 1.

		Params
		------
		self
		band='i'

		Return
		------
		trans  (array)
		ws_trans (array)
		"""
		trans, ws_trans = filters.filtertools.getNormTransFunc(band=band, survey=self.survey)
		return trans, ws_trans*u.AA

	def _get_norm_trans(self, wavelength, band='i', bounds_error=False):
		"""
		return normalized transmission function at a specific wavelenth, see filters.getNormTrans()
		the normalization is such that int{ trans{l} * dlnl} = 1.

		Params
		------
		self
		wave (float): wavelength to evaluate the function at
		band='i'
		bounds_error (bool):
			whether to raise error when interpolation outside of array is attempted

		Return
		------
		trans  (float)
		"""
		trans = filters.filtertools.getNormTrans(wavelength, band=band, survey=self.survey, bounds_error=bounds_error)
		return trans

	def _calc_Fnu_in_band(self, band, component='all'):
		"""
		Params
		------
		band=band
		component='all': from ['all', 'cont', 'line']
			which spectral component to operate on

		Return
		------
		Fnu (quantity in units "erg s-1 cm-2 Hz-1")
		"""

		spec, ws = self.get_spec_ws_from_spectab(component=component)

		trans, ws_trans = self._get_norm_trans_func(band=band)

		Fnu = filters.inttools.calc_Fnu_in_band_from_fl(fl=spec, ws=ws, trans=trans, ws_trans=ws_trans, isnormed=True)
		return Fnu

	def _calc_mAB_in_band(self, band, component='all'):
		Fnu = self._calc_Fnu_in_band(band=band, component='all')
		return Fnu.to(u.ABmag)

	def __get_specmag_colname(self, band, component, fluxquantity):
		"""
		band : e.g. 'i'
		component: from ['all', 'cont', 'line']
		fluxquantity: from ['fnu', 'mag']
		"""
		tag_component = {'all': '', 'cont': 'cont', 'line': 'line', 'contextrp': 'contextrp'}
		tag_quantity = {'fnu': 'Fnu', 'mag': 'Mag'}
		return 'spec{0}{1}_{2}'.format(tag_component[component], tag_quantity[fluxquantity], band)

	def __get_spectab_colname(self, component):
		"""
		band : e.g. 'i'
		component: from ['all', 'cont', 'line']
		fluxquantity: from ['fnu', 'mag']
		"""
		if component == 'ws':
			return 'ws'
		else:
			tag_component = {'all': '', 'cont': 'cont', 'line': 'line', 'contextrp': 'contextrp'}
			return 'spec{0}'.format(tag_component[component])


import tkinter as tk
import sqlite3 as sql
import os
import random as rnd
from tkinter.messagebox import *
import time

LARGE_FONT= ("Verdana", 12)
PATH = ".{}database".format(os.sep)
PATH_1 = ".{}database{}data.db".format(os.sep, os.sep)

class PuzzleApp(tk.Tk):

    def __init__(self, *args, **kwargs):

        file_path, db_path = self.control_resources()
        if file_path and db_path:
            pass
        elif not file_path:
            os.mkdir(PATH)
            Operations.create_table()
        elif file_path and not db_path:
            Operations.create_table()

        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "Language Skills")
        self.resizable(width=False, height=False)
        self.geometry('{}x{}'.format(372, 372))

        container = tk.Frame(self)
        container.pack()

        self.frames = {}

        for F in (StartPage, AddWords, FindWords, Dictionary, WordQuiz,
                  DeleteWord):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

    def control_resources(self):

        x = os.path.exists(PATH)
        y = os.path.exists(PATH_1)

        return x, y

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        self.head_label = tk.Label(self, text="Language Skılls",
                            relief = tk.GROOVE, borderwidth=5,
                            width=20,fg="black",
                            bg="gray", font=("Helvetica", 24))
        self.head_label.grid(row = 0, column = 0)

        self.option_1 = tk.Button(self, text="Add Words",
                            relief=tk.RAISED, width=20,
                            borderwidth=2,
                            command=lambda: controller.show_frame(AddWords),
                            font=("Helvetica", 12))
        self.option_1.grid(row=1, column=0)

        self.option_2 = tk.Button(self, text="Find Words",
                            relief=tk.RAISED, width=20,
                            borderwidth=2,
                            font=("Helvetica", 12),
                            command=lambda: controller.show_frame(FindWords))
        self.option_2.grid(row=2, column=0)

        self.option_3 = tk.Button(self, text="Dictionary",
                            relief=tk.RAISED, width=20,
                            borderwidth=2,
                            font=("Helvetica", 12),
                            command=lambda: controller.show_frame(Dictionary))
        self.option_3.grid(row=3, column=0)

        self.option_4 = tk.Button(self, text="Word Quiz",
                            relief=tk.RAISED, width=20,
                            borderwidth=2,
                            font=("Helvetica", 12),
                            command=lambda: controller.show_frame(WordQuiz))
        self.option_4.grid(row=4, column=0)
        self.option_5 = tk.Button(self, text="Remove Words",
                                  relief=tk.RAISED, width=20,
                                  borderwidth=2,
                                  font=("Helvetica", 12),
                                  command=lambda: controller.show_frame(DeleteWord))
        self.option_5.grid(row=5, column=0)

        info_text = "There are {} words in database."
        self.info_box = tk.Label(self, text=info_text.format(str(len(
                                 Operations.get_all()))),
                                 font=("Helvetica", 12))
        self.info_box.grid(row=6, column=0)

class AddWords(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        entry = tk.Entry(self, relief = tk.RIDGE,
                         borderwidth=5, width=20,
                         bg="gray", font=("Helvetica", 24))
        entry.grid(row=0, column=0, columnspan=3)

        entry_1 = tk.Entry(self, relief = tk.RIDGE,
                         borderwidth=5, width=20,
                         bg="gray", font=("Helvetica", 24))
        entry_1.grid(row=1, column=0, columnspan=3)

        def add_data():
            word_in_dict = Operations.control_word_in_db(entry.get())
            word = str(entry.get())
            mean = str(entry_1.get())
            if str(entry.get()) != "" and str(entry_1.get()) != "":
                if word_in_dict == None:
                    data = (word, mean)
                    Operations.insert_in_db(data)
                    showinfo("Success", "'{}' successfully added to database.".format(word))
                else:
                    if askyesno("Word is already exists !",
                                'This word is already in your dictionary.\nDo you want to change ?\n'):
                        Operations.change_meaning_in_db(word, mean)
                        showinfo("Success", "Meaning of this word is successfully changed.")
                    else:
                        showinfo("Nothing", "This word stays same.")

                entry.delete(0, tk.END)
                entry_1.delete(0, tk.END)
            else:
                showerror("Error", "You must fill all blanks !")
                entry.delete(0, tk.END)
                entry_1.delete(0, tk.END)

        button = tk.Button(self, text="Add",
                           command=add_data)
        button.grid(row=2, column=1)

        def chance_page():
            new_start = StartPage(parent, controller)
            new_dict = Dictionary(parent, controller)
            new_quiz = WordQuiz(parent, controller)
            controller.frames[StartPage] = new_start
            controller.frames[Dictionary] = new_dict
            controller.frames[WordQuiz] = new_quiz
            new_start.grid(row=0, column=0, sticky="nsew")
            new_dict.grid(row=0, column=0, sticky="nsew")
            new_quiz.grid(row=0, column=0, sticky="nsew")

            controller.show_frame(StartPage)

        button1 = tk.Button(self, text="Back to Home",
                            command=chance_page)
        button1.grid(row=4, column=1)

class DeleteWord(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        entry = tk.Entry(self, relief=tk.RIDGE,
                         borderwidth=5, width=20,
                         bg="gray", font=("Helvetica", 24))
        entry.grid(row=0, column=0, columnspan=3)

        def remove_data():
            word = str(entry.get())
            word_1 = Operations.control_word_in_db(word)
            if word != "":
                if word_1 != None:
                    if askyesno("Are you sure", "Are you sure for delete '{}' from your database ?".format(word)):
                        Operations.delete_from_db(word)
                        showinfo("Success", "'{}' successfully deleted from database.".format(word))
                        entry.delete(0, tk.END)
                    else:
                        showinfo("Message", "'{}' is not deleted".format(word))
                        entry.delete(0, tk.END)
                else:
                    showinfo("Unknown word", "This word is not in your database.")
                    entry.delete(0, tk.END)
            else:
                showerror("Error!", "You must fill the blank!")

        button = tk.Button(self, text="Remove",
                           command=remove_data)
        button.grid(row=2, column=1)

        def chance_page():
            new_start = StartPage(parent, controller)
            new_dict = Dictionary(parent, controller)
            new_quiz = WordQuiz(parent, controller)
            controller.frames[StartPage] = new_start
            controller.frames[Dictionary] = new_dict
            controller.frames[WordQuiz] = new_quiz
            new_start.grid(row=0, column=0, sticky="nsew")
            new_dict.grid(row=0, column=0, sticky="nsew")
            new_quiz.grid(row=0, column=0, sticky="nsew")

            controller.show_frame(StartPage)

        button1 = tk.Button(self, text="Back to Home",
                            command=chance_page)
        button1.grid(row=4, column=1)

class FindWords(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        prompt_label = tk.Label(self, text="Lang1 ---> Lang2")
        prompt_label.grid(row=0, column=1)
        prompt_label_1 = tk.Label(self, text="Lang2 ---> Lang1")
        prompt_label_1.grid(row=4, column=1)
        label = tk.Label(self, text = "")
        label_1 = tk.Label(self, text = "")

        entry = tk.Entry(self, relief = tk.RIDGE,
                         borderwidth=5, width=20,
                         bg="gray", font=("Helvetica", 24))
        entry.grid(row=1, column=0, columnspan=3)

        def create_label():
            word = str(entry.get())
            format_word = (word,)
            label_text = Operations.find_in_db(format_word)
            if word != "":
                if label_text != None:
                    label["text"] = label_text
                    label.grid(row=2, column=1)
                    entry.delete(0, tk.END)
                else:
                    showinfo("Unknown Word", "There is no word ' {} ' in your database.".format(word))
                    entry.delete(0, tk.END)

            else: showerror("Error", "You must fill the blank !")

        button = tk.Button(self, text="Find",
                  command = create_label)
        button.grid(row=3, column=1)

        entry_1 = tk.Entry(self, relief = tk.RIDGE,
                         borderwidth=5, width=20,
                         bg="gray", font=("Helvetica", 24))
        entry_1.grid(row=5, column=0, columnspan=3)

        def create_label_1():
            word = str(entry_1.get())
            format_word = (word,)
            label_text = Operations.find_in_db(format_word, 1)
            if word != "":
                if label_text != None:
                    label_1["text"] = label_text
                    label_1.grid(row=6, column=1)
                    entry_1.delete(0, tk.END)
                else:
                    showinfo("Unknown Word", "There is no word ' {} ' in your database.".format(word))
                    entry_1.delete(0, tk.END)

            else: showerror("Error", "You must fill the blank !")

        button_2 = tk.Button(self, text="Find",
                  command = create_label_1)
        button_2.grid(row=7, column=1)

        def chance_page():
            label.grid_forget()
            label_1.grid_forget()
            controller.show_frame(StartPage)

        button1 = tk.Button(self, text="Back to Home",
                            command= chance_page)
        button1.grid(row=8, column=1)

class Dictionary(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        word_set = Operations.get_all()
        rnd.shuffle(word_set)
        if len(word_set) > 10:
            sample_list = rnd.sample(word_set,10)
        else:
            sample_list = rnd.sample(word_set,len(word_set))

        for i in range(len(sample_list)):
            word, mean = sample_list[i]

            label = tk.Label(self, text = word, width = 16)
            label.grid(row = i, column = 1)

            label_1 = tk.Label(self, text = "--->", width = 16)
            label_1.grid(row=i, column = 2)

            label_2 = tk.Label(self, text = mean, width = 16)
            label_2.grid(row = i, column = 3)

        def chance_page():
            controller.show_frame(StartPage)

        button1 = tk.Button(self, text="Back to Home",width=16,
                            command=chance_page)
        button1.grid(row = 10 , column = 2)

class WordQuiz(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.user_score = 0
        score_label = tk.Label(self, text = str(self.user_score))
        score_label.grid(row = 0, column = 0)
        message_label = tk.Label(self, text = "")
        message_label.grid(row = 0, column = 1)
        def answer(word, entry_label):
            word_1 = entry_label.get()
            if word == word_1:
                self.user_score += 1
                score_label["text"] = str(self.user_score)
                message_label["text"] = "True"
            else:
                message_label["text"] = "False"

        word_set = Operations.get_all()
        rnd.shuffle(word_set)
        if len(word_set) < 5:
            sample_list = rnd.sample(word_set,len(word_set))
        else:
            sample_list = rnd.sample(word_set,5)
        for i in range(len(sample_list)):
            w, m = sample_list[i]
            q_label = tk.Label(self, text = w)
            q_label.grid(row = i+1, column = 0)
            q_entry = tk.Entry(self)
            q_entry.grid(row = i+1, column = 1)
            answer_button = tk.Button(self, text="Answer",
                                      command = lambda m=m, q_entry=q_entry: answer(m, q_entry))
            answer_button.grid(row = i+1, column = 2)

        button1 = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
        button1.grid(row = 7, column = 0)

        def new_quiz():
            quiz = WordQuiz(parent, controller)
            controller.frames[WordQuiz] = quiz
            quiz.grid(row=0, column=0, sticky="nsew")
            controller.show_frame(WordQuiz)

        button2 = tk.Button(self, text="New Quiz", command=new_quiz)
        button2.grid(row = 7, column = 1)

class Operations:

    def __init__(self):
        pass
    @classmethod
    def connect_database(cls):
        cls.con = sql.connect(PATH_1)
        cls.cur = cls.con.cursor()
        return cls.cur
    @classmethod
    def create_table(cls):
        cls.connect_database()
        cls.cur.execute( """CREATE TABLE Dict (Word text,
                                                Mean text)""" )
        cls.stop_database()
    @classmethod
    def stop_database(cls):
        cls.con.commit()
        cls.con.close()
    @classmethod
    def insert_in_db(cls, data):
        cls.connect_database()
        cls.cur.execute("INSERT INTO Dict VALUES (?, ?)",data)
        cls.stop_database()
    @classmethod
    def find_in_db(cls, word, mode=0):
        cls.connect_database()
        if mode == 0:
            cls.cur.execute("SELECT Mean From Dict WHERE Word = ?",word)
        elif mode == 1:
            cls.cur.execute("SELECT Word From Dict WHERE Mean = ?",word)
        mean = cls.cur.fetchone()
        cls.stop_database()
        return mean
    @classmethod
    def get_all(cls):
        cls.connect_database()
        cls.cur.execute("SELECT * FROM Dict")
        all_item = cls.cur.fetchall()
        cls.stop_database()
        return all_item

    @classmethod
    def change_meaning_in_db(cls, word, mean):
        cls.connect_database()
        cls.cur.execute("UPDATE Dict SET Mean = ? WHERE Word = ?", (mean, word))
        cls.stop_database()

    @classmethod
    def control_word_in_db(cls, word):
        cls.connect_database()
        cls.cur.execute("SELECT Word From Dict WHERE Word = '%s';" % word.strip())
        word_1 = cls.cur.fetchone()
        cls.stop_database()
        return word_1

    @classmethod
    def delete_from_db(cls, data):
        cls.connect_database()
        cls.cur.execute("DELETE FROM Dict WHERE Word = '%s';" % data.strip())
        cls.stop_database()

if __name__ == "__main__":
    app = PuzzleApp()
    app.mainloop()


# 1253. 좋다 (골드 4)
# 알고리즘 분류 : 자료 구조, 정렬, 이분 탐색, 두 포인터

import sys

if __name__ == '__main__':
    # 입력 받기
    N = int(input()) # 배열의 요소 개수
    arr = list(map(int, sys.stdin.readline().split())) # 배열의 요소들

# 배열 정렬
arr.sort()
ans = 0  # 정답 카운트 초기화

# 배열의 각 요소에 대해 반복
for i in range(N):
    # 현재 요소를 배열에서 제외한 새로운 배열 생성
    tmp = arr[:i] + arr[i + 1:]
    left, right = 0, len(tmp) - 1  # 두 요소 합을 찾기 위한 포인터 초기화

    # 두 요소 합을 찾는 과정
    while left < right:
        t = tmp[left] + tmp[right]  # 두 요소의 합 계산

        if t == arr[i]:
            ans += 1  # 합이 제외된 요소와 같으면 정답 카운트 증가
            break

        if t < arr[i]:
            left += 1  # 합이 작으면 왼쪽 포인터 증가
        else:
            right -= 1  # 합이 크면 오른쪽 포인터 감소

print(ans)  # 최종 정답 카운트 출력