import pandas as pd

userCarbPercent, userProteinPercent, userFatPercent = 0,0,0
mealUserMacros = {}

dfBreakfast = pd.read_csv("Eat_Skinny/Skinny_Breakfast_Recipes.csv")
dfBreakfast_2 = pd.read_csv("Skinny_Taste/Skinny_Taste_Breakfast_Recipes.csv")
dfBreakfast = dfBreakfast.append(dfBreakfast_2, ignore_index = True)

dfLunch = pd.read_csv("Eat_Skinny/Skinny_Lunch_Recipes.csv")
dfLunch_2 = pd.read_csv("Skinny_Taste/Skinny_Taste_Lunch_Recipes.csv")
dfLunch = dfLunch.append(dfLunch_2, ignore_index = True)

dfDinner = pd.read_csv("Eat_Skinny/Skinny_Dinner_Recipes.csv")
dfDinner_2 = pd.read_csv("Skinny_Taste/Skinny_Taste_Dinner_Recipes.csv")
dfDinner = dfDinner.append(dfDinner_2, ignore_index = True)

print("\n Type in your top 5 favorite foods you would eat NO MATTER WHAT HAPPENED - omake sure to seperate with commas")
print("Try to be as generic as possible yet specific. REMEMBER COMMAS!: ")
Foods = (input("Answer: ").lower()).replace(" ", "")
favoriteFoods = Foods.split(",")

userCal = int(input("How many Calories do you want in your meal Plan?: "))
while(userCarbPercent + userProteinPercent + userFatPercent) != 100:
  if ((userCarbPercent + userProteinPercent + userFatPercent) != 100):
    print("\n Input Macronutrient Percentage Values in order of Carbs, Protein, and Fats - only numbers seperated with commas")
    print("EXAMPLE: 30,30,40")
    print("If you get this message again then your percentages don't add up to 100")
    macroPercentage = input("Input Macronutrient Percentage: ")

  try:
    userCarbPercent, userProteinPercent, userFatPercent = map(int, macroPercentage.split(","))
  except:
    print("\n You didn't type in the values correctly. Remeber no %, just numbers, seperated with commas. TRY AGAIN")

userCarbGrams = (userCal * (userCarbPercent / 100))// 4
userProteinGrams = (userCal * (userProteinPercent / 100))// 4
userFatGrams = (userCal * (userFatPercent / 100))// 9

print("\nYour meal plan will have near " + str(userCarbGrams) + " grams of Carbs, " + str(userProteinGrams) + " grams of protein, and " + str(userFatGrams) + " grams of Fat")

numberUserMeals = int(input("How many meals would you want in a day, just put in a number: "))

for i in range(0,numberUserMeals):
  userCarb = 0
  userProtein = 0
  userFat = 0
  while (userCarb == 0 and userProtein == 0 and userFat == 0):
    print("\nWhat type of meal do you want for Meal #" + str(i+1))
    mealType = (input("Choose 'Breakfast', 'Lunch', or 'Dinner'. Type it EXACTLY!: ")).lower()
    print("\nInput your macros in GRAMS just in number form in the the order of carbs, protein, and fats. Make sure to seperate each number with commas.")
    tempMarcos = input("What are your preffered macros for Meal #" + str(i+1) + ": ")
    try:
      userCarb, userProtein, userFat = map(int, tempMarcos.split(","))
    except:
      print("\n You didn't type in the values correctly. Remeber no 'grams', just numbers, seperated with commas. TRY AGAIN")
  totalCal = ((userCarb + userProtein) * 4) + (userFat * 9)
  mealUserMacros["Meal #" + str(i+1)] = [userCarb, userProtein, userFat, mealType, totalCal]

#Abstraction
def Range(target, number, lowPercentage, highPercentage):
  lowBound = (target * lowPercentage)
  highBound = (target * highPercentage)

  if (number > lowBound and number < highBound):
    return (True)
  else:
    return (False)

def sortFavorites():
  global dfBreakfast_01
  global dfLunch_01
  global dfDinner_01

  dfBreakfast_01 = dfBreakfast.copy()
  dfLunch_01 = dfLunch.copy()
  dfDinner_01 = dfDinner.copy()

  dfBreakfast_01["Score"] = 0
  dfLunch_01["Score"] = 0
  dfDinner_01["Score"] = 0

  for index, row in dfBreakfast_01.iterrows():
    for food in favoriteFoods:
      tempIngred = food in (dfBreakfast_01.Ingredients[index])
      tempTitle = food in (dfBreakfast_01.Name[index])
      if(tempIngred or tempTitle):
         dfBreakfast_01.loc[index, "Score"] = dfBreakfast_01.loc[index, "Score"] + 1

  for index, row in dfLunch_01.iterrows():
    for food in favoriteFoods:
      tempIngred = food in (dfLunch_01.Ingredients[index])
      tempTitle = food in (dfLunch_01.Name[index])
      if (tempIngred or tempTitle):
        dfLunch_01.loc[index, "Score"] = dfLunch_01.loc[index, "Score"] + 1

  for index, row in dfDinner_01.iterrows():
    for food in favoriteFoods:
      tempIngred = food in (dfDinner_01.Ingredients[index])
      tempTitle = food in (dfDinner_01.Name[index])
      if (tempIngred or tempTitle):
        dfDinner_01.loc[index, "Score"] = dfDinner_01.loc[index, "Score"] + 1

  dfBreakfast_01 = dfBreakfast_01.sort_values(by = "Score", ascending = False)
  dfBreakfast_01 = dfBreakfast_01.reset_index(drop = True)

  dfLunch_01 = dfLunch_01.sort_values(by = "Score", ascending = False)
  dfLunch_01 = dfLunch_01.reset_index(drop = True)

  dfDinner_01.sort_values(by = "Score", ascending = False)
  dfDinner_01 = dfDinner_01.reset_index(drop = True)

#Child Algorithm #1
def checkMacros(meal, carbs, protein, fat, calories, lowPercentage, highPercentage, servings):
  test = mealUserMacros.get(meal)
  carbsGrams = test[0]
  proteinGrams = test[1]
  fatsGrams = test[2]
  actualCal = test[4]

  carbs = servings * carbs
  protein = servings * protein
  fat = servings * fat
  calories = servings * calories

  if (Range(carbsGrams, carbs, lowPercentage, highPercentage) and Range(proteinGrams, protein, lowPercentage, highPercentage) and Range(fatsGrams, fat, lowPercentage, highPercentage) and Range(actualCal, calories, lowPercentage, highPercentage)):
    return (True)
  else:
    return (False)

#Child Algorithm #2
def getMealMacros(rowIndex, typeMeal):
  if (typeMeal == "breakfast"):
    carbs = dfBreakfast_01.loc[rowIndex, "Carbs Grams"]
    protein = dfBreakfast_01.loc[rowIndex, "Protein Grams"]
    fat = dfBreakfast_01.loc[rowIndex, "Fat Grams"]
    calories = dfBreakfast_01.loc[rowIndex, "Calories"]
    url = dfBreakfast_01.loc[rowIndex, "Url"]
    name = dfBreakfast_01.loc[rowIndex, "Name"]

  elif (typeMeal == "lunch"):
    carbs = dfLunch_01.loc[rowIndex, "Carbs Grams"]
    protein = dfLunch_01.loc[rowIndex, "Protein Grams"]
    fat = dfLunch_01.loc[rowIndex, "Fat Grams"]
    calories = dfLunch_01.loc[rowIndex, "Calories"]
    url = dfLunch_01.loc[rowIndex, "Url"]
    name = dfLunch_01.loc[rowIndex, "Name"]

  elif (typeMeal == "dinner"):
    carbs = dfDinner_01.loc[rowIndex, "Carbs Grams"]
    protein = dfDinner_01.loc[rowIndex, "Protein Grams"]
    fat = dfDinner_01.loc[rowIndex, "Fat Grams"]
    calories = dfDinner_01.loc[rowIndex, "Calories"]
    url = dfDinner_01.loc[rowIndex, "Url"]
    name = dfDinner_01.loc[rowIndex, "Name"]

  temp = [carbs, protein, fat, calories, url, name]
  return (temp)

#MAIN Algorithm
def generateMealPlan(mealTypes):
  global mealPlan
  global servings
  global lowPercentageList
  global highPercentageList

  lowPercentageList = []
  highPercentageList = []
  mealPlan = {}

  for index, meal in enumerate(mealUserMacros):
    lowPercentage = 0.9
    highPercentage = 1.1
    typeMeal = mealTypes[index]

    lookMeal = True
    rowIndex = 0
    if (typeMeal == "breakfast"):
      lenDf = len(dfBreakfast_01.index)
    if (typeMeal == "lunch"):
      lenDf = len(dfLunch_01.index)
    if (typeMeal == "dinner"):
      lenDf = len(dfDinner_01.index)

    while(lookMeal):
      servings = 0.5
      macros = getMealMacros(rowIndex, typeMeal)
      carbs = macros[0]
      protein = macros[1]
      fat = macros[2]
      calories = macros[3]
      url = macros[4]
      name = macros[5]

      for i in range(0,8):
        if (checkMacros(meal, carbs, protein, fat, calories, lowPercentage, highPercentage,servings)):
          lookMeal = False
          mealPlan[meal] = [url, name, typeMeal, servings]

          lowPercentageList.append((1 - lowPercentage) * 100)
          highPercentageList.append((highPercentage - 1) * 100)
        servings = servings + 0.5

      rowIndex = rowIndex + 1

      if (rowIndex == lenDf):
        rowIndex = 0
        lowPercentage = lowPercentage - (0.02)
        highPercentage = highPercentage + (0.02)
  print("\n" + str(mealPlan))

mealTypes = []
for meal in mealUserMacros:
  temp = mealUserMacros.get(meal)
  mealTypes.append(temp[3])

sortFavorites()
generateMealPlan(mealTypes)

print(lowPercentageList)
print(highPercentageList)

print("\nWant to change your meal types and number of meals?")
ans = input("Put 'Yes' for yes and 'No' for no:")

if (ans == "Yes"):
  print("\nPut Lunch, Dinner, or Breakfast in the order of the meals, but for the program to work the number of choices must equal the amount of meals you're having in a day")
  mealTypes = (input("Put either 'breakfast', 'lunch', or 'dinner' seprated by only commas:")).split(",")

  generateMealPlan(mealTypes)
else:
  print("\nCheck out the recipes in your meal plan with the urls")


import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from tqdm import tqdm
from transformers import AutoConfig, AutoTokenizer
from modeling import BertForSentimentClassification, AlbertForSentimentClassification, DistilBertForSentimentClassification
from dataset import SSTDataset
from arguments import args

def get_accuracy_from_logits(logits, labels):
	#Get a tensor of shape [B, 1, 1] with probabilities that the sentiment is positive
	probs = torch.sigmoid(logits.unsqueeze(-1))
	#Convert probabilities to predictions, 1 being positive and 0 being negative
	soft_probs = (probs > 0.5).long()
	#Check which predictions are the same as the ground truth and calculate the accuracy
	acc = (soft_probs.squeeze() == labels).float().mean()
	return acc

def evaluate(model, criterion, dataloader, device):
	model.eval()
	mean_acc, mean_loss, count = 0, 0, 0
	with torch.no_grad():
		for input_ids, attention_mask, labels in tqdm(dataloader, desc="Evaluating"):
			input_ids, attention_mask, labels = input_ids.to(device), attention_mask.to(device), labels.to(device)
			logits = model(input_ids, attention_mask)
			mean_loss += criterion(logits.squeeze(-1), labels.float()).item()
			mean_acc += get_accuracy_from_logits(logits, labels)
			count += 1
	return mean_acc / count, mean_loss / count

if __name__ == "__main__":

	if args.model_name_or_path is None:
		args.model_name_or_path = 'barissayil/bert-sentiment-analysis-sst'

	#Configuration for the desired transformer model
	config = AutoConfig.from_pretrained(args.model_name_or_path)

	#Tokenizer for the desired transformer model
	tokenizer = AutoTokenizer.from_pretrained(args.model_name_or_path)

	#Create the model with the desired transformer model
	if config.model_type == 'bert':
		model = BertForSentimentClassification.from_pretrained(args.model_name_or_path)
	elif config.model_type == 'albert':
		model = AlbertForSentimentClassification.from_pretrained(args.model_name_or_path)
	elif config.model_type == 'distilbert':
		model = DistilBertForSentimentClassification.from_pretrained(args.model_name_or_path)
	else:
		raise ValueError('This transformer model is not supported yet.')

	device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
	model = model.to(device)

	#Takes as the input the logits of the positive class and computes the binary cross-entropy
	criterion = nn.BCEWithLogitsLoss()

	val_set = SSTDataset(filename='data/dev.tsv', maxlen=args.maxlen_val, tokenizer=tokenizer)
	val_loader = DataLoader(dataset=val_set, batch_size=args.batch_size, num_workers=args.num_threads)

	val_acc, val_loss = evaluate(model=model, criterion=criterion, dataloader=val_loader, device=device)
	print("Validation Accuracy : {}, Validation Loss : {}".format(val_acc, val_loss))


"""mainProject URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include, url
from django.contrib import admin,auth
from django.conf.urls.static import static
from django.conf import settings
from accounts.views import login_view,register_view,logout_view,profileedit
#from comments.views import commentView
from comments.views import comment_delete
urlpatterns = [

    url(r'^admin/', admin.site.urls),
      url(r'^', include('bored.urls', namespace="bored")),
      url(r'^', include('bored.api.urls', namespace="bored-api")),
       url(r'^comments', include('comments.api.urls', namespace="comments-api")),
 url(r'^ckeditor/', include('ckeditor_uploader.urls')),
  url(r'^accounts/', include('allauth.urls')),
url(r'^profile/profile-edit/', profileedit,name='profile_edit'),
 url(r'^(?P<id>\d+)/deletecomment/(?P<id1>\d+)',comment_delete,name='comments'),
 url(r'^accounts/login/', login_view,name='login'),
 url(r'^register/', register_view,name='register'),
  url(r'^accounts/logout/', logout_view, name='logout'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
  urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)


import json
import shutil
import logging
from jsonmerge import merge
from airflow.models import BaseOperator
from cwltool.process import relocateOutputs
from cwltool.stdfsaccess import StdFsAccess

class JobCleanup(BaseOperator):

    def __init__(self, *args, **kwargs):
        super(JobCleanup, self).__init__(task_id=self.__class__.__name__, *args, **kwargs)

    def execute(self, context):
        collected_outputs = {}
        for task_outputs in self.xcom_pull(context=context, task_ids=[task.task_id for task in self.upstream_list]):
            collected_outputs = merge(collected_outputs, task_outputs["outputs"])
        logging.debug('Collected outputs: \n{}'.format(json.dumps(collected_outputs, indent=4)))
        tmp_folder = collected_outputs["tmp_folder"]
        output_folder = collected_outputs["output_folder"]
        relocated_outputs = relocateOutputs(outputObj={output_id: collected_outputs[output_src]
                                                       for output_src, output_id in self.dag.get_output_list().items()
                                                       if output_src in collected_outputs},
                                            destination_path=output_folder,
                                            source_directories=[output_folder],
                                            action="copy",
                                            fs_access=StdFsAccess(""))

        relocated_outputs = {key.split("/")[-1]: val for key, val in relocated_outputs.items()}
        shutil.rmtree(tmp_folder, ignore_errors=False)
        logging.debug('Delete temporary output directory: \n{}'.format(tmp_folder))
        logging.info("WORKFLOW RESULTS\n" + json.dumps(relocated_outputs, indent=4))


import os
import argparse
import subprocess

def iterate_over_directory(input_dir,
                           results_file,
                           timeout):
    # get all the files in the directory
    files = os.listdir(input_dir)
    for f in files:
        name, extension = os.path.splitext(f)
        # we only care about the graph files
        if extension != ".graph":
            continue
        # open the graph file
        print("Processing file {}".format(f))
        subprocess.call("python3 toboggan.py {}/{} --skip_truth "
                        "--experiment_info --timeout {} >>"
                        " {}".format(input_dir, f, timeout, results_file),
                        shell=True)

def main(args):
    timeout = -1
    if args.timeout:
        timeout = args.timeout
    iterate_over_directory(args.input_dir, args.results_file_name, timeout)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("input_dir", help="directory containing .graph and"
                        " .truth files", type=str)
    parser.add_argument("results_file_name", help="name of file to store notes"
                        " of instances on which toboggan times out", type=str)
    parser.add_argument("timeout", help="time to run before skipping instance",
                        type=int)

    args = parser.parse_args()
    main(args)


from collections import OrderedDict
from xigt.codecs import xigtxml

# etree is either from lxml.etree or xml.etree.ElementTree
etree = xigtxml.etree

### Decoding ###

def matrix_decode_meta(elem):
    metatype = elem.get('type').lower()
    if metatype in ('judgment', 'vetted', 'phenomena'):
        metaattrs = xigtxml.get_attributes(elem, ignore=('type',))
        content = None
        if metatype == 'phenomena':
            content = [p.text for p in elem.iter('phenomenon')]
        return xigtxml.Meta(type=metatype,
                            attributes=metaattrs,
                            content=content)
    else:
        return xigtxml.default_decode_meta(elem)

### Encoding ###

def encode_meta(meta):
    metatype = meta.type.lower()
    if metatype in ('judgment', 'vetted', 'phenomena'):
        attributes = dict(type=meta.type, **meta.attributes)
        e = etree.Element('meta', attrib=attributes)
        if metatype == 'phenomena':
            for phenomenon in meta.content:
                p = etree.Element('phenomenon')
                p.text = phenomenon
                e.append(p)
        return e
    else:
        return xigtxml.default_encode_meta(meta)

### Function maps ###

xigtxml.decode_meta = matrix_decode_meta
xigtxml.encode_meta = matrix_encode_meta

if __name__ == '__main__':
    import sys
    f = sys.argv[1]
    xc = xigtxml.load(open(f,'r'))
    print(xigtxml.dumps(xc, pretty_print=True))
    xigtxml.dump(open('abkhaz-out.xigt','w'), xc, pretty_print=True)


import argparse
import string

import pytest

from support import timing

def reacted_length(s: str) -> int:
    s = s.strip()
    ret = [s[0]]
    for c in s[1:]:
        if ret and c == ret[-1].swapcase():
            ret.pop()
        else:
            ret.append(c)
    return len(ret)

def compute(s: str) -> int:
    return min(
        reacted_length(s.replace(c, '').replace(c.upper(), ''))
        for c in string.ascii_lowercase
    )

@pytest.mark.parametrize(
    ('input_s', 'expected'),
    (
        ('dabAcCaCBAcCcaDA', 4),
        ('dabAcCaCBAcCcaDA\n', 4),
    ),
)
def test(input_s: str, expected: int) -> None:
    assert compute(input_s) == expected

def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('data_file')
    args = parser.parse_args()

    with open(args.data_file) as f, timing():
        print(compute(f.read()))

    return 0

if __name__ == '__main__':
    exit(main())


#! /usr/bin/env python3

import math

def solution(arr):
    i = 0
    while i < len(arr):
        upper_i = i
        for j in range(i, -1, -1):
            if arr[j] > arr[upper_i]:
                temp = arr[j]
                arr[j] = arr[upper_i]
                arr[upper_i] = temp
                upper_i = j

        current_count = i + 1
        if current_count % 2 == 0:
            left = math.floor(i/2)
            right = math.ceil(i/2)
            print((arr[left] + arr[right]) / 2)
        else:
            index = math.ceil(i/2) if i >= 2 else i
            print(arr[index])

        i += 1

    return arr

if __name__ == "__main__":
    print(solution([2, 1, 5, 7, 2, 0, 5]))


# This package will contain the spiders of your Scrapy project
#
# Please refer to the documentation for information on how to create and manage
# your spiders.
import scrapy
from TestDemo.items import TestdemoItem
class TestDemo(scrapy.Spider):

    name = "douban"
    allowed_domains = ['movie.douban.com']
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0'}
    # start_urls = ["https://movie.douban.com/top250"]

    def start_requests(self):
        url = 'https://movie.douban.com/top250'
        yield scrapy.Request(url, headers=self.headers)

    def parse(self, response):
        items = TestdemoItem()
        movies = response.xpath("//ol[@class='grid_view']/li")
        for movie in movies:
            items["movie_rank"] = movie.xpath(".//div[@class='pic']/em/text()").extract()[0]
            items["movie_name"]=movie.xpath(".//div[@class='hd']/a/span[1]/text()").extract()[0]
            items["movie_score"] = movie.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]
            items["movie_comment"] = movie.xpath(".//div[@class='star']/span/text()").re('\d+人评价')[0]
            print(items["movie_rank"] + ":" + items["movie_name"] + " " + \
                  items["movie_score"] + " " + items["movie_comment"])
            yield items

        next_url = response.xpath("//span[@class='next']/a/@href").extract()
        if next_url:
            next_url = "https://movie.douban.com/top250" + next_url[0]
            yield scrapy.Request(next_url, callback=self.parse,headers=self.headers)


# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License  (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Copyright (c) Open-MMLab. All rights reserved.
from .config import Config, ConfigDict
from .misc import (check_prerequisites, concat_list, is_list_of, is_seq_of,
                   is_str, is_tuple_of, iter_cast, list_cast,
                   requires_executable, requires_package, slice_list,
                   tuple_cast)
from .path import (FileNotFoundError, check_file_exist, fopen, is_filepath,
                   mkdir_or_exist, scandir, symlink)
from .progressbar import (ProgressBar, track_iter_progress,
                          track_parallel_progress, track_progress)
from .timer import Timer, TimerError, check_time

__all__ = [
    'ConfigDict', 'Config', 'is_str', 'iter_cast', 'list_cast', 'tuple_cast',
    'is_seq_of', 'is_list_of', 'is_tuple_of', 'slice_list', 'concat_list',
    'check_prerequisites', 'requires_package', 'requires_executable',
    'is_filepath', 'fopen', 'check_file_exist', 'mkdir_or_exist', 'symlink',
    'scandir', 'FileNotFoundError', 'ProgressBar', 'track_progress',
    'track_iter_progress', 'track_parallel_progress', 'Timer', 'TimerError',
    'check_time'
]


from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import ListView
from django.urls import reverse
from django.http import HttpResponseRedirect, Http404
from django.forms import inlineformset_factory, forms
from .models import Gun, Bullet, TestResult, Velocity
from .forms import GunForm, BulletForm, ResultForm, VelocityForm

class HomeView(ListView):
    model = Gun
    template_name = "home.html"

class GunsView(ListView):
    model = Gun
    template_name = "guns.html"

@login_required
def gunview(request, gun_id):
    """Show a single gun and all its info."""
    guns = Gun.objects.filter(owner=request.user, id=gun_id).prefetch_related('bullets__results__velocity')
    # Make sure the gun belongs to the current user.
    for gun in guns:
        if gun.owner != request.user:
            raise Http404

    context = {'guns': guns}
    return render(request, 'gun.html', context)

@login_required
def AddGun(request):
    """Add a new gun."""
    if request.method != 'POST':
        # No data submitted; create a blank form.
        form = GunForm()
    else:
        # POST data submitted; process data.
        form = GunForm(request.POST)
        if form.is_valid():
            new_gun = form.save(commit=False)
            new_gun.owner = request.user
            form.save()
            return HttpResponseRedirect(reverse('guns'))
    context = {'form': form}
    return render(request, 'add_gun.html', context)

@login_required
def addbullet(request, gun_id):
    """Add a new bullet."""
    gun = Gun.objects.get(id=gun_id)
    if request.method != 'POST':
        # No data submitted; create a blank form.
        form = BulletForm()
    else:
        # POST data submitted; process data.
        form = BulletForm(data=request.POST)
        if form.is_valid():
            new_bullet = form.save(commit=False)
            new_bullet.gun = gun
            new_bullet.save()
            return HttpResponseRedirect(reverse('gun', args=[gun_id]))
    context = {'form': form}
    return render(request, 'add_bullet.html', context)

@login_required
def add_data(request, bullet_id):
    """Add a new result."""
    ResultFormSet = inlineformset_factory(Bullet, TestResult, fields=('charge', 'moa'), can_delete=False, extra=5)
    bullet = Bullet.objects.get(id=bullet_id)
    if request.method != 'POST':
        # No data submitted; create a blank form.
        formset = ResultFormSet()
    else:
        # POST data submitted; process data.
        formset = ResultFormSet(request.POST, instance=bullet)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse('gun', args=[bullet.gun.pk]))
    context = {'formset': formset}
    return render(request, 'add_data.html', context)

@login_required
def edit_data(request, result_id):
    """Edit an existing result."""
    result = TestResult.objects.get(id=result_id)
    gun = result.bullet.gun
    if request.method != 'POST':
        # Initial request; pre-fill form with the current entry.
        form = ResultForm(instance=result)
    else:
        # POST data submitted; process data.
        form = ResultForm(instance=result, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('gun', args=[gun.id]))
    context = {'result': result, 'gun': gun, 'form': form}
    return render(request, 'edit_data.html', context)

@login_required
def delete_data(request, result_id):
    """delete an existing result."""
    result = TestResult.objects.get(id=result_id)
    result.delete()
    gun = result.bullet.gun
    return HttpResponseRedirect(reverse('gun', args=[gun.id]))

@login_required
def add_velocity(request, result_id):
    """Add new velocity."""
    VelocityFormSet = inlineformset_factory(TestResult, Velocity, fields=('shotnumber', 'velocity'), can_delete=False)
    result = TestResult.objects.get(id=result_id)
    if request.method != 'POST':
        # No data submitted; create a blank form.
        formset = VelocityFormSet(instance=result)
    else:
        # POST data submitted; process data.
        formset = VelocityFormSet(request.POST, instance=result)
        if formset.is_valid():
            formset.save()
            return HttpResponseRedirect(reverse('edit_data', args=[result.pk]))
    context = {'formset': formset}
    return render(request, 'add_velocity.html', context)

@login_required
def edit_bullet(request, bullet_id):
    """Edit an existing result."""
    bullet = Bullet.objects.get(id=bullet_id)
    gun = bullet.gun
    if request.method != 'POST':
        # Initial request; pre-fill form with the current entry.
        form = BulletForm(instance=bullet)
    else:
        # POST data submitted; process data.
        form = BulletForm(instance=bullet, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('gun', args=[gun.id]))
    context = {'bullet': bullet, 'gun': gun, 'form': form}
    return render(request, 'edit_bullet.html', context)

@login_required
def delete_bullet(request, bullet_id):
    """delete an existing result."""
    bullet = Bullet.objects.get(id=bullet_id)
    bullet.delete()
    gun = bullet.gun
    return HttpResponseRedirect(reverse('gun', args=[gun.id]))

@login_required
def view_graph(request, bullet_id):
    """Show a single bullet graph."""
    bullet = Bullet.objects.filter(id=bullet_id).prefetch_related('results__velocity')
    velocitylist = []
    chargelist = []
    moalist = []
    for b in bullet:
        for result in b.results.all():
            chargelist.append(result.charge)
            moalist.append(result.moa)
            total_avg = 0
            for velocity in result.velocity.all():
                total_avg += velocity.velocity
            total_avg /= 3
            velocitylist.append(total_avg)

    context = {'bullet': bullet, 'velocitylist': velocitylist, 'chargelist':chargelist, 'moalist':moalist}
    return render(request, 'graph.html', context)


class Solution(object):
    def isPowerOfThree(self, n):
        """

        :type n: List[int]
        :rtype: bool
        """

        if n == 1:
            return True
        elif (n / 3) != (n // 3) or n < 1:
            return False
        else:
            return self.isPowerOfThree(n / 3)

def main():
    solution = Solution()
    ret = solution.isPowerOfThree(27)
    print(ret)

if __name__ == '__main__':
    main()


import unittest
from abc import ABCMeta

from testhelpers.generator import TestUsingType, create_tests, get_classes_to_test, \
    TEST_LATEST_ONLY_ENVIRONMENT_VARIABLE_SET_VALUE, TestUsingObject, create_tests_using_objects, \
    create_tests_using_types, TypeUsedInTest, ObjectTypeUsedInTest

class _ExampleTestThatUsesTypes(TestUsingType[TypeUsedInTest], metaclass=ABCMeta):
    """
    Example test that uses types.
    """

class _ExampleTestThatUsesObjects(TestUsingObject[ObjectTypeUsedInTest], metaclass=ABCMeta):
    """
    Example test that uses objects.
    """

class TestCreateTestsUsingTypes(unittest.TestCase):
    """
    Tests for `create_tests_using_types`.
    """
    def test_can_create_tests(self):
        test_types = {type, int, str, float}
        tests = create_tests_using_types(_ExampleTestThatUsesTypes, test_types)
        for name, test in tests.items():
            self.assertTrue(issubclass(test, TestUsingType))
            test_types.remove(test.get_type_to_test())
        self.assertEqual(0, len(test_types))

    def test_can_create_test_with_custom_naming(self):
        custom_namer = lambda *args: "MyTestName"
        tests = create_tests_using_types(_ExampleTestThatUsesTypes, {object}, custom_namer)
        self.assertEqual(1, len(tests))
        self.assertEqual(custom_namer(), list(tests.keys())[0])

class TestCreateTestsUsingObjects(unittest.TestCase):
    """
    Tests for `create_tests_using_objects`.
    """
    def test_can_create_tests(self):
        test_objects = {object(), int(1), str("2"), float(3.0)}
        tests = create_tests_using_objects(_ExampleTestThatUsesObjects, test_objects)
        for name, test in tests.items():
            self.assertTrue(issubclass(test, TestUsingObject))
            test_objects.remove(test.get_object_to_test())
        self.assertEqual(0, len(test_objects))

    def test_can_create_test_with_custom_naming(self):
        custom_namer = lambda *args: "MyTestName"
        tests = create_tests_using_objects(_ExampleTestThatUsesObjects, {object()}, custom_namer)
        self.assertEqual(1, len(tests))
        self.assertEqual(custom_namer(), list(tests.keys())[0])

class TestCreateTests(unittest.TestCase):
    """
    Tests for `create_tests`.
    """
    def test_can_create_tests_using_types(self):
        tests = create_tests(_ExampleTestThatUsesTypes, {object()})
        self.assertTrue(issubclass(list(tests.values())[0], TestUsingType))

    def test_can_create_tests_using_objects(self):
        tests = create_tests(_ExampleTestThatUsesObjects, {object()}, lambda *args: "Name")
        self.assertTrue(issubclass(list(tests.values())[0], TestUsingObject))

class TestGetClassesToTest(unittest.TestCase):
    """
    Tests for `get_classes_to_test`.
    """
    _ALL_CLASSES = {int, str, float}
    _LATEST_CLASS = str

    def test_all_returned_if_environment_variable_not_set(self):
        assert TEST_LATEST_ONLY_ENVIRONMENT_VARIABLE_SET_VALUE != ""
        to_test = get_classes_to_test(
            TestGetClassesToTest._ALL_CLASSES, TestGetClassesToTest._LATEST_CLASS,
            _environment_variable_reader=lambda str: "")
        self.assertEqual(TestGetClassesToTest._ALL_CLASSES, to_test)

    def test_all_returned_if_environment_variable_set(self):
        to_test = get_classes_to_test(
            TestGetClassesToTest._ALL_CLASSES, TestGetClassesToTest._LATEST_CLASS,
            _environment_variable_reader=lambda str: TEST_LATEST_ONLY_ENVIRONMENT_VARIABLE_SET_VALUE)
        self.assertEqual({TestGetClassesToTest._LATEST_CLASS}, to_test)

    def test_valid_return_given_current_environment_variable_setting(self):
        to_test = get_classes_to_test(TestGetClassesToTest._ALL_CLASSES, TestGetClassesToTest._LATEST_CLASS)
        if len(to_test) == 1:
            self.assertEqual({TestGetClassesToTest._LATEST_CLASS}, to_test)
        else:
            self.assertEqual(TestGetClassesToTest._ALL_CLASSES, to_test)

if __name__ == "__main__":
    unittest.main()


import filecmp
import json
import logging
import os
import random
import re
import tempfile
from collections import namedtuple
from itertools import combinations
from pathlib import Path
from typing import Callable, Optional, Set

import boto3
from tqdm import tqdm

from .util import Oracle, Results, instances, load_json

bucket = 'gnosis-dev-dfusion'
page_size = 1000

def get_instance_list(
    client,
    prefix: str
):
    """Return set of filename is S3 bucket."""
    l = set()
    page = client.list_objects_v2(
        Bucket=bucket, Prefix=prefix, MaxKeys=page_size
    )
    l |= {r['Key'] for r in page['Contents'] if r['Key'][-4:] == 'json'}

    while page['IsTruncated']:
        page = client.list_objects_v2(
            Bucket=bucket,
            Prefix=prefix,
            MaxKeys=page_size,
            ContinuationToken=page['NextContinuationToken']
        )
        l |= {r['Key'] for r in page['Contents'] if r['Key'][-4:] == 'json'}
    return l

def get_instance_date(instance_path: str):
    return re.search(r'\/([0-9\-]+)', instance_path).group(1)

def get_instance_batch(instance_path: str):
    return re.search(r'instance_([0-9]+)', instance_path).group(1)

def filter_instances_by_date(instance_paths, from_date):
    instance_paths = {
        instance_path
        for instance_path in instance_paths
        if get_instance_date(instance_path) >= from_date
    }
    return instance_paths

def filter_instances_by_batch(instance_paths, batches):
    instance_paths = {
        instance_path
        for instance_path in instance_paths
        if get_instance_batch(instance_path) in batches
    }
    return instance_paths

def get_instance_name(instance_path: str):
    return Path(instance_path).name

def get_result_name(result_path: str):
    return Path(result_path).parent.name

def download_instance(
    client,
    path: str,
    output_dir: Path,
    name_extractor: Callable[[str], str]
):
    instance_name = name_extractor(path)
    local_path = str(output_dir / instance_name)
    client.download_file(Bucket=bucket, Key=path, Filename=local_path)

def download_instances(
    client,
    instance_paths: Set[str],
    output_dir: Path,
    name_extractor: Callable[[str], str]
):
    for instance_path in tqdm(instance_paths):
        download_instance(client, instance_path, output_dir, name_extractor)

def select_batches(
    batches: Set[str],
    n: int,
    selection_criteria: str
):
    if selection_criteria == 'most_recent':
        batches = sorted(list(batches), key=int, reverse=True)
        batches = set(batches[:n])
    elif selection_criteria == 'random':
        batches = set(random.sample(batches, n))
    else:
        assert False
    return batches

def select_feasible_batches(
    max_nr_instances: int,
    max_fraction_infeasible: float,
    selection_criteria: str,
    result_paths: Path
):
    # select all feasible instances
    feasible = set()
    for name, path in instances(result_paths):
        try:
            instance = load_json(path)
        except json.JSONDecodeError:
            continue  # ignore empty files and other unparsable garbage
        if len(instance['orders']) > 0:
            feasible.add(name)

    feasible = {get_instance_batch(instance) for instance in feasible}

    # select subset of feasible instances
    nr_feasible = min(len(feasible), int(max_nr_instances * (1 - max_fraction_infeasible)))

    return select_batches(feasible, nr_feasible, selection_criteria)

def filter_unique(instances_path: Path):
    to_remove = set()
    for (name1, path1), (name2, path2) \
            in tqdm(combinations(instances(instances_path), 2)):
        if path1 in to_remove or path2 in to_remove:
            continue
        if filecmp.cmp(path1, path2):
            to_remove.add(path2)

    for path in to_remove:
        os.remove(path)

def get_batch_ids_from_file(filename):
    with open(filename, 'r') as f:
        return f.read().splitlines()

def filter_paths(paths, args):
    if args.from_date is not None:
        paths = filter_instances_by_date(paths, args.from_date)
    if args.with_batch_ids_from_file is not None:
        paths = filter_instances_by_batch(
            paths,
            get_batch_ids_from_file(args.with_batch_ids_from_file)
        )
    if args.with_batch_ids is not None:
        paths = filter_instances_by_batch(
            paths,
            args.with_batch_ids
        )
    return paths

def main(args):
    if args.max_fraction_infeasible != 1 and (
        args.with_batch_ids is not None
        or args.with_batch_ids_from_file is not None
    ):
        print("WARNING: '--max_fraction_infeasible' ignored when '--with_batch_ids' is given.")
        args.max_fraction_infeasible = 1

    instances_prefix = f'data/{args.network}/{args.solver}/instances/'
    results_prefix = f'data/{args.network}/{args.solver}/results/'

    client = boto3.client('s3')

    print("Downloading solution list.")
    result_paths = get_instance_list(client, prefix=results_prefix)
    result_paths = filter_paths(result_paths, args)

    batches = {get_instance_batch(result_path) for result_path in result_paths}

    result_dir = tempfile.TemporaryDirectory()

    print("Downloading solutions.")
    download_instances(client, result_paths, Path(result_dir.name), get_result_name)

    print("Selecting feasible instances.")
    feasible_batches = select_feasible_batches(
        args.max_nr_instances,
        args.max_fraction_infeasible,
        args.selection_criteria,
        Path(result_dir.name)
    )

    print("Downloading problem list.")
    instance_paths = get_instance_list(client, prefix=instances_prefix)
    instance_paths = filter_paths(instance_paths, args)

    print("Downloading feasible problems.")
    feasible_instance_paths = filter_instances_by_batch(instance_paths, feasible_batches)
    download_instances(
        client, feasible_instance_paths, Path(args.instances_path), get_instance_name
    )

    print("Selecting infeasible instances.")
    infeasible_batches = batches - feasible_batches
    if args.max_fraction_infeasible != 1:
        nr_infeasible = int(
            (len(feasible_batches) * args.max_fraction_infeasible)
            / (1 - args.max_fraction_infeasible)
        )
    else:
        nr_infeasible = len(infeasible_batches)

    infeasible_batches = select_batches(
        infeasible_batches,
        nr_infeasible,
        args.selection_criteria
    )

    print("Downloading infeasible problems.")
    infeasible_instance_paths = filter_instances_by_batch(
        instance_paths, infeasible_batches
    )
    download_instances(
        client, infeasible_instance_paths, Path(args.instances_path), get_instance_name
    )

    print("Removing duplicate problems.")
    filter_unique(Path(args.instances_path))

def setup_arg_parser(subparsers):
    parser = subparsers.add_parser('download', help="Downloads instances from S3 bucket.")

    parser.add_argument(
        'instances_path',
        type=Path,
        help='Directory where to copy instances to.'
    )
    parser.add_argument(
        '--from_date',
        type=str,
        help='Get instances newer than the given date (inclusive).'
    )
    parser.add_argument(
        '--max_nr_instances',
        type=int,
        default=100,
        help='Maximum number of instances to download.'
    )
    parser.add_argument(
        '--max_fraction_infeasible',
        type=float,
        default=1 / 3,
        help='Instances should have at most given fraction of infeasible instances.'
    )
    parser.add_argument(
        '--selection_criteria',
        type=str,
        choices=['most_recent', 'random'],
        default='random',
        help='How to select instances.'
    )
    parser.add_argument(
        '--with_batch_ids',
        type=str,
        nargs='+',
        help='Get instances with given batch ids (separated by spaces).'
    )
    parser.add_argument(
        '--with_batch_ids_from_file',
        type=str,
        help='Get instances with batch ids given in specified file (one per line).'
    )
    parser.add_argument(
        '--network',
        type=str,
        choices=['mainnet', 'mainnet-prod', 'rinkeby'],
        default='mainnet',
        help='Network where to pull instances from.'
    )
    parser.add_argument(
        '--solver',
        type=str,
        choices=['standard-solver', 'fallback-solver', 'open-solver'],
        default='standard-solver',
        help='Solver where to pull solution instances from.'
    )
    parser.set_defaults(exec_subcommand=main)


import os
import numpy as np
import pandas as pd
from tqdm import tqdm
import multiprocessing
from multiprocessing import  Pool
from utils_preprocess_title import preprocess_title

TRAIN_CSV_DIR = './data/train.csv'
CATEGORIES_OUTPUT_DIR = './output/categories.npy'
TITLES_OUTPUT_DIR = './output/titles_normal.npy'
LABELS_OUTPUT_DIR = './output/labels.npy'

data = pd.read_csv(TRAIN_CSV_DIR)

unreliable = data[data['label_quality'] == 'unreliable']
reliable = data[data['label_quality'] == 'reliable']

merged = pd.concat([
  unreliable,
  reliable,
])

merged = merged.drop('label_quality', axis=1)
categories = merged.category.unique()
categories = np.sort(categories)

np.save(CATEGORIES_OUTPUT_DIR, categories)

categories_list = list(categories)
dictOfCategories = { word : i for i, word in enumerate(categories_list) }

tokens_list_stemmed = []
tokens_list = []
categories = []

def normalize(row):
  row.title = preprocess_title(row.title, row.language)
  row.category = dictOfCategories.get(row.category)
  return row

def normalize_chunk(data):
  tqdm.pandas()
  return data.progress_apply(normalize, axis=1)

def norm(dataframe):
  WORKERS = multiprocessing.cpu_count()
  with Pool(WORKERS) as p:
    df_split = np.array_split(dataframe, WORKERS)
    df = pd.concat(p.map(normalize_chunk, df_split))
    return df

tokens = filtered = norm(merged)
tokens = tokens[tokens.title.str.len() != 0]

tokens_list = np.squeeze(tokens.iloc[:, 0:1].values)
categories = np.squeeze(tokens.iloc[:, 2:3].values)

np.save(TITLES_OUTPUT_DIR, tokens_list)
np.save(LABELS_OUTPUT_DIR, categories)


class Precondition():
    def __init__(self, pre, fun):
        self.pre = pre
        self.fun = fun

    def compile(self):
        return '''
void pre_{id}({0}) {{
    // {pre!r}
}}
'''.format(self.fun.params(), id = self.fun.id, pre=self.pre)


from meta_policy_search.baselines.linear_baseline import LinearFeatureBaseline, MetaNNBaseline, LinearTimeBaseline
from meta_policy_search.envs.mujoco_envs.humanoid_rand_direc import HumanoidRandDirecEnv
from meta_policy_search.envs.mujoco_envs.humanoid_rand_direc_2d import HumanoidRandDirec2DEnv
from meta_policy_search.envs.mujoco_envs.ant_rand_direc import AntRandDirecEnv
from meta_policy_search.envs.mujoco_envs.ant_rand_direc_2d import AntRandDirec2DEnv
from meta_policy_search.envs.mujoco_envs.ant_rand_goal import AntRandGoalEnv
from meta_policy_search.envs.mujoco_envs.half_cheetah_rand_direc import HalfCheetahRandDirecEnv
from meta_policy_search.envs.mujoco_envs.half_cheetah_rand_vel import HalfCheetahRandVelEnv
from meta_policy_search.envs.mujoco_envs.humanoid_rand_direc import HumanoidRandDirecEnv
from meta_policy_search.envs.mujoco_envs.humanoid_rand_direc_2d import HumanoidRandDirec2DEnv
from meta_policy_search.envs.mujoco_envs.walker2d_rand_direc import Walker2DRandDirecEnv
from meta_policy_search.envs.mujoco_envs.walker2d_rand_vel import Walker2DRandVelEnv
from meta_policy_search.envs.mujoco_envs.swimmer_rand_vel import SwimmerRandVelEnv
from meta_policy_search.envs.normalized_env import normalize
from meta_policy_search.meta_algos.tmaml import TMAML
from meta_policy_search.meta_trainer import Trainer
from meta_policy_search.samplers.meta_sampler import MetaSampler
from meta_policy_search.samplers.tmaml_sample_processor import TMAMLMetaSampleProcessor
from meta_policy_search.policies.meta_gaussian_mlp_policy import MetaGaussianMLPPolicy
from meta_policy_search.utils import logger
from meta_policy_search.utils.utils import set_seed, ClassEncoder

import numpy as np
import os
import json
import argparse
import time
import os

def main(config):
    set_seed(config['seed'])

    reward_baseline = LinearTimeBaseline() # the usual baseline
    return_baseline = LinearFeatureBaseline() # the additional baseline for DICE

    env = globals()[config['env']]() # instantiate env
    env = normalize(env) # apply normalize wrapper to env

    meta_baseline = MetaNNBaseline(input_size=env.observation_space.shape[0]) # the meta baseline

    policy = MetaGaussianMLPPolicy(
            name="meta-policy",
            obs_dim=np.prod(env.observation_space.shape),
            action_dim=np.prod(env.action_space.shape),
            meta_batch_size=config['meta_batch_size'],
            hidden_sizes=config['hidden_sizes'],
    )

    sampler = MetaSampler(
        env=env,
        policy=policy,
        rollouts_per_meta_task=config['rollouts_per_meta_task'],
        meta_batch_size=config['meta_batch_size'],
        max_path_length=config['max_path_length'],
        parallel=config['parallel'],
    )

    sample_processor = TMAMLMetaSampleProcessor(
        baseline=reward_baseline,
        max_path_length=config['max_path_length'],
        discount=config['discount'],
        normalize_adv=config['normalize_adv'],
        positive_adv=config['positive_adv'],
        return_baseline=return_baseline,
        metabaseline=meta_baseline,
    )

    algo = TMAML(
        policy=policy,
        max_path_length=config['max_path_length'],
        meta_batch_size=config['meta_batch_size'],
        num_inner_grad_steps=config['num_inner_grad_steps'],
        inner_lr=config['inner_lr'],
        learning_rate=config['learning_rate']
    )

    trainer = Trainer(
        algo=algo,
        policy=policy,
        env=env,
        sampler=sampler,
        sample_processor=sample_processor,
        n_itr=config['n_itr'],
        num_inner_grad_steps=config['num_inner_grad_steps'],
    )

    trainer.train()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Taming MAML')
    parser.add_argument('--dump_path', type=str, default=os.path.join(os.path.realpath(os.path.dirname(__file__)), 'logs'))
    parser.add_argument('--seed', type=int, help='random seed', default=0)
    parser.add_argument('--env', type=str,
                        help='env name', default='HalfCheetahRandDirecEnv')
    parser.add_argument('--inner_type', type=str, help='type of inner loss function', default='log_likelihood')
    parser.add_argument('--n_iter', type=int,
                        help='number of iterations', default=5001)

    args = parser.parse_args()

    os.makedirs(args.dump_path, exist_ok=True)

    config = {
        'seed': 1,

        'baseline': 'LinearFeatureBaseline',

        'env': 'HalfCheetahRandDirecEnv',

        # sampler config
        'rollouts_per_meta_task': 20,
        'max_path_length': 100,
        'parallel': True,

        # sample processor config
        'discount': 0.99,
        'gae_lambda': 1,
        'normalize_adv': True,
        'positive_adv': False,

        # policy config
        'hidden_sizes': (64, 64),
        'learn_std': True,  # whether to learn the standard deviation of the gaussian policy

        'inner_lr': 0.1,  # adaptation step size
        'learning_rate': 1e-3,  # meta-policy gradient step size
        'step_size': 0.01,  # size of the TRPO trust-region
        'n_itr': 5001,  # number of overall training iterations
        'meta_batch_size': 40,  # number of sampled meta-tasks per iterations
        'num_inner_grad_steps': 1,  # number of inner / adaptation gradient steps
        'inner_type': 'log_likelihood',  # type of inner loss function used

    }

    config.update(vars(args))

    # configure logger
    logger.configure(dir=args.dump_path, format_strs=['stdout', 'log', 'csv', 'tensorboard'],
                     snapshot_mode='last_gap')

    # dump run configuration before starting training
    json.dump(config, open(args.dump_path +
                           '/params.json', 'w'), cls=ClassEncoder)

    # start the actual algorithm
    main(config)


import torchvision

from torchvision import transforms

def get_dataset(dataset_name, datadir):
    if dataset_name == "mnist":
        dataset = torchvision.datasets.MNIST(datadir, train=True,
                               download=True,
                               transform=torchvision.transforms.Compose([
                                   torchvision.transforms.ToTensor(),
                                   torchvision.transforms.Normalize(
                                       (0.5,), (0.5,))
                               ]))

    if dataset_name == "cifar10":
        transform_function = transforms.Compose([
            transforms.RandomCrop(32, padding=4),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize((0.4914, 0.4822, 0.4465),
                                 (0.2023, 0.1994, 0.2010)),
        ])

        dataset = torchvision.datasets.CIFAR10(
            root=datadir,
            train=True,
            download=True,
            transform=transform_function)

    if dataset_name == "cifar100":
        transform_function = transforms.Compose([
            transforms.RandomCrop(32, padding=4),
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize((0.4914, 0.4822, 0.4465),
                                 (0.2023, 0.1994, 0.2010)),
        ])

        dataset = torchvision.datasets.CIFAR100(
            root=datadir,
            train=True,
            download=True,
            transform=transform_function)

    return dataset


import datetime
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import sys
import json
import re
from collections import defaultdict

_USERAGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'

def nested_dict(n, type):
    if n == 1:
        return defaultdict(type)
    else:
        return defaultdict(lambda: nested_dict(n-1, type))

class TFSScraper:
    def __init__(self, **kwargs):
        self._s = requests.Session()
        self._s.headers.update({'User-agent': _USERAGENT}) 		# set user agent to something less conspicuous

        retries = Retry(total=5, backoff_factor=2, status_forcelist=[ 502, 503, 504 ]) # 5 retries, [3,6,12,24,48] seconds, basic connectivity and DNS failure and http 502-504
        self._s.mount('http://', HTTPAdapter(max_retries=retries))        # does retries object stay alive outside init? does it need to be?
        self._s.mount('https://', HTTPAdapter(max_retries=retries))        # does retries object stay alive outside init? does it need to be?
        self._task = kwargs["task"] if 'task' in kwargs else None
        self._priceTables = {}  # dict { 'url1': { ['100']['100'] = 34.50, ...}, 'url2': ...}
        self._discounts = {}    # dict { 'url1': { 'manDiscount = 50, tfsDiscount = 19'}, 'url2': ... }
        self._dimensions = {}   # dict { 'url1': { 'minWidth' = 41, ... }, 'url2': ...}

    def setLogging(self, baseLog, actionLog):
        if baseLog:
            self.baseLog = baseLog
        if actionLog:
            self.actionLog = actionLog

    def _actionLog(self, msg):
        if self.actionLog:
            self.actionLog(msg)

    def _isNL(self, prodUrl):
        return (prodUrl.lower().find('247raamdecoratie.nl') >= 0)

    def _isFR(self, prodUrl):
        return (prodUrl.lower().find('stores247.fr') >= 0)

    def _baseLog(self, msg):
        if self.baseLog:
            self.baseLog(msg)

    def _isJson(self, s):
        try:
            json_object = json.loads(s)
        except ValueError:
            return False
        return True

    def _isNumber(self, s):
        try:
            complex(s) # for int, long, float and complex
        except ValueError:
            return False

        return True

    def _isInt(self, i):
        try:
            int (i)
            return True
        except ValueError:
            return False

    def _isValidProdUrl(self, url):
        if not (type(url) == str): return False
        if not ((url.lower().find("www.247raamdecoratie.nl") >= 0) or (url.lower().find("www.stores247.fr") >= 0)): return False
        if not ((url.lower().find("http://") >= 0) or (url.lower().find("https://") >= 0)): return False
        return True

    def _isTaskAborted(self):
        if self._task:
            if self._task.is_aborted():
                self._baseLog("is_aborted() is true! Task should be aborted.")
                return True
        return False

    '''
    *******************************************
    Worker functions
    *******************************************
    '''

    def _fetchDiscounts(self, prodUrl):
        r = self._s.get(prodUrl)
        src = r.text

        self._discounts[prodUrl] = {}

        m = re.search(r'(?i)var\s+man_discount\s+=\s+([0-9]+);', src)
        if m:
            manDiscount = m.group(1)
            if self._isInt(manDiscount):
                self._discounts[prodUrl]['manDiscount'] = int(manDiscount)
            else: return False
        else: return False

        m = re.search(r'(?i)var\s+tfs_discount\s+=\s+([0-9]+);', src)
        if m:
            tfsDiscount = m.group(1)
            if self._isInt(tfsDiscount):
                self._discounts[prodUrl]['tfsDiscount'] = int(tfsDiscount)
            else: return False
        else: return False

        return True

    def _fetchPriceTable(self, prodUrl):
        try:
            r = self._s.get(prodUrl) # get the product page
            src = r.text

            lengthSize = 0
            widthSize = 0

            m = re.search(r'\svar width_size\s+=\s+([0-9]+);', src)
            if m:
                widthSize = m.group(1)
                #print ("Width of table: " + widthSize)

            m = re.search(r'\svar length_size\s+=\s+([0-9]+);', src)
            if m:
                lengthSize = m.group(1)
                #print ("Length of table: "+ lengthSize)

            priceSheet = [i for i in range(int(lengthSize))]	# first dimension is WIDTH
            for i in range(0,int(lengthSize)):
                priceSheet[i] = [j for j in range(int(widthSize))]	# second dimension is HEIGHT

            pattern = re.compile(r'\spriceSheet\[([0-9]*)\]\[([0-9]*)\] = "([0-9.]+)";\n')
            for (row, col, price) in re.findall(pattern, src):
                #print("Found -- priceSheet[" + str(row) + "][" + str(col) + "] = " + str(price))
                priceSheet[int(row)][int(col)] = price

            newTbl = nested_dict(2, float)
            for i in range(1, int(widthSize)):
                for j in range(1, int(lengthSize)):
                    w = priceSheet[0][i]
                    h = priceSheet[j][0]
                    p = float(priceSheet[j][i])
                    #print("w{}xh{}=p{}   priceSheet[{}][{}]".format(w,h,p,j,i))
                    newTbl[float(w)][float(h)] = p

            self._priceTables[prodUrl] = newTbl
            return True

        except Exception as e:
            self._baseLog("Exception in _fetchPriceTable: "+ str(e))
            self._baseLog('Error on line {}'.format(sys.exc_info()[-1].tb_lineno))
            return None

    '''
    *******************************************************
    Public functions
    *******************************************************
    '''

    '''
    fetchPrice()

    Retrieve the price of a product at given sizes by extracting the price from the product page

    Expects:
    prodUrl: URL of the product page
    width: requested width
    height: requested height

    Returns:
    price if a price was found (float, excl. VAT, net of any fixed discounts)
    or False or 0 if no price was found

    '''

    def fetchPrice(self, prodUrl, width, height):

        try:
            if not ( (prodUrl.lower().find("http://") >= 0) or (prodUrl.lower().find("https://") >= 0)):
                prodUrl = 'https://' + prodUrl  # default to HTTPS if no protocol was given

            if not self._isValidProdUrl(prodUrl):
                self._baseLog("Error: invalid product URL")
                return False

            # ensure we have retrieved discounts, product dimensions, and the price table
            if not (prodUrl in self._discounts): self._fetchDiscounts(prodUrl)
            if not (prodUrl in self._dimensions): self.getProductDimensions(prodUrl)
            if not (prodUrl in self._priceTables): self._fetchPriceTable(prodUrl)

            if not (prodUrl in self._discounts):
                self._baseLog("Error: Couldn't find discount values in page source.")
                return False
            if not (prodUrl in self._dimensions):
                self._baseLog("Error: Couldn't find min/max dimensions in page source.")
                return False
            if not (prodUrl in self._priceTables):
                self._baseLog("Error: Couldn't find price information in page source.")
                return False
            #ptab = self._priceTables[prodUrl]
            #for w in ptab:
            #    for h in ptab[w]:
            #        print ("w{}xh{}=p{}".format(w,h,ptab[w][h]))

            widths = []
            heights = []
            for w in self._priceTables[prodUrl]: widths.append(float(w))
            for h in self._priceTables[prodUrl][widths[0]]: heights.append(float(h))
            widths.sort()
            heights.sort()
            # print("Widths = {}".format(widths))
            # print("Heights = {}".format(heights))

            widthKey = 0
            heightKey = 0

            for h in heights:
                #print("Comparing requested {} to table height value {}".format(height/10, h))
                if height/10 <= h:
                    heightKey = h
                    break
            for w in widths:
                #print("Comparing requested {} to table width value {}".format(width/10, w))
                if width/10 <= w:
                    widthKey = w
                    break

            if widthKey == '' or heightKey == '':
                self._baseLog("Error: Couldn't determine nearest size to look up in 247's internal price table")
                return False

            #print("heightKey is {}".format(heightKey))
            #print("widthKey is {}".format(widthKey))
            #if width==300 or width==1000:
                # print("***TABLE***")
                # print(self._priceTables[prodUrl][widthKey])
                # print("***********")
                # print("price from table: {}".format(self._priceTables[prodUrl][widthKey][heightKey]))

            basePrice = self._priceTables[prodUrl][widthKey][heightKey]
            manDiscount = self._discounts[prodUrl]['manDiscount']
            tfsDiscount = self._discounts[prodUrl]['tfsDiscount']
            #print("manDiscount = {}, tfsDiscount = {}".format(manDiscount, tfsDiscount))

            realPrice = basePrice*(1-(manDiscount + tfsDiscount)/100)

            vat = 0
            if self._isNL: vat = 21
            if self._isFR: vat = 20

            realPriceExVAT = realPrice/(1+(vat/100))
            realPriceExVATRnd = float(format(realPriceExVAT, '.2f'))
            #self._baseLog("basePrice: {}, realPrice: {}, realPriceExVAT: {}".format(basePrice, realPrice, realPriceExVATRnd))
            return realPriceExVATRnd

        except Exception as e:
            self._baseLog("Exception in fetchPrice: "+ str(e))
            self._baseLog('Error on line {}'.format(sys.exc_info()[-1].tb_lineno))
            return None

    '''
    generateProductNameFromUrl()

    Extracts product name from URL

    Expects: URL, e.g. https://www.stores247.fr/voile-cristalline-neige-store-enrouleur
    Returns: product name, e.g. 'voile-cristalline-neige-store-enrouleur'
    '''
    def generateProductNameFromUrl(self, url):

        if type(url) != str: return False
        if url.endswith("/"): url = url[:-1]    # trim trailing slash
        if url.endswith("/"): return False      # but make sure we're not left with a a string with only a slash
        k = url.rfind('/')
        return url[k+1:]

    '''
    isUrlSupported()

    Checks if scraper supports a URL

    Arguments:
    url: the url you would like to scrape

    Returns:
    true or false
    '''
    def isUrlSupported(self, url):
        '''
        supportedUrls = [
            '/p/venitien-aluminium-lames-25mm',
            '/p/venitien-aluminium-lames-50mm',
            '/p/store-plisse-classique-occultant',
            '/p/venitien-bois-lames-25mm',
        ]
        for x in supportedUrls:
            if x in url:
                return True
        return False
        '''
        return True
        ###### TODO: IMPLEMENT FOR 247. OR ARE ALL URLS SUPPORTED?

    '''
    getProductDimensions()

    Scrapes the minimum and maximum width/height for a given product

    Expects: product URL

    Returns a dict with the following values {
    minWidth: minimum width for the product,
    maxWidth: maximum width for the product,
    minHeight: minimum height for the product,
    maxHeight: maximum height for the product
    }, or False if failed
    '''
    def getProductDimensions(self, prodUrl):

        try:
            if not ( (prodUrl.lower().find("http://") >= 0) or (prodUrl.lower().find("https://") >= 0)):
                prodUrl = 'https://' + prodUrl  # default to HTTPS if no protocol was given

            if not self._isValidProdUrl(prodUrl):
                self._baseLog("Error: Invalid product URL")
                return False

            r = self._s.get(prodUrl) # get the product page
            src = r.text

            # use RegEx to find product dimensions
            m = re.search(r'(?i)colmin = ([1-9][0-9\.]+);',src)
            minWidth = m.group(1) if m else 0
            m = re.search(r'(?i)colmax = ([1-9][0-9\.]+);',src)
            maxWidth = m.group(1) if m else 0
            m = re.search(r'(?i)rowmin = ([1-9][0-9\.]+);',src)
            minHeight = m.group(1) if m else 0
            m = re.search(r'(?i)rowmax = ([1-9][0-9\.]+);',src)
            maxHeight = m.group(1) if m else 0
            if not self._isNumber(minWidth): return False
            if not self._isNumber(maxWidth): return False
            if not self._isNumber(minHeight): return False
            if not self._isNumber(maxHeight): return False
            minWidth = float(minWidth)
            maxWidth = float(maxWidth)
            minHeight = float(minHeight)
            maxHeight = float(maxHeight)
            if self._isInt(minWidth): minWidth = int(minWidth)
            if self._isInt(maxWidth): maxWidth = int(maxWidth)
            if self._isInt(minHeight): minHeight = int(minHeight)
            if self._isInt(maxHeight): maxHeight = int(maxHeight)
            ############# TODO: Now 291.3 gets converted to an INTEGER.....
            ## Need to build something that checks if there is a floating point number, and if so, store it as float, otherwise convert to int.

            if ((minHeight * maxHeight * minWidth * maxWidth) == 0):
                self._baseLog("Error: couldn't find product dimensions. minW={}, maxW={}, minH={}, maxH={}".format(minWidth, maxWidth, minHeight, maxHeight))
                return False

            dimensions = {
                'minWidth': minWidth,
                'maxWidth': maxWidth,
                'minHeight': minHeight,
                'maxHeight': maxHeight
            }

            self._dimensions[prodUrl] = dimensions

            dimensions["minWidth"] = dimensions["minWidth"] * 10
            dimensions["maxWidth"] = dimensions["maxWidth"] * 10
            dimensions["minHeight"] = dimensions["minHeight"] * 10
            dimensions["maxHeight"] = dimensions["maxHeight"] * 10

            return dimensions

        except Exception as e:
            self._baseLog("Exception in getProductDimensions: "+ str(e))
            self._baseLog('Error on line {}'.format(sys.exc_info()[-1].tb_lineno))
            return None


import os

from exaparser.utils import read
from .. import BaseUnit

class BaseExecutionUnit(BaseUnit):
    """
    Base execution unit parser class.

    Args:
        config (dict): unit config.
        work_dir (str): full path to working directory.
    """

    def __init__(self, config, work_dir):
        super(BaseExecutionUnit, self).__init__(config, work_dir)
        self.work_dir = os.path.join(self.work_dir, self.config.get("workDir", ""))

    @property
    def stdout_file(self):
        return os.path.join(self.work_dir, self.config.get("stdoutFile", ".".join((self.name, "out"))))

    @property
    def application(self):
        """
        Returns the application used in the unit.
        Override upon inheritance.

        Returns:
             dict
        """
        raise NotImplementedError

    @property
    def version(self):
        """
        Returns the application version used in the unit.

        Returns:
             str
        """
        raise NotImplementedError

    @property
    def executable(self):
        """
        Returns the executable used in the unit.
        Override upon inheritance.

        Returns:
             dict
        """
        raise NotImplementedError

    @property
    def input(self):
        """
        Returns a list of input files used in the unit.

        Note: Make sure to set "isManuallyChanged" to True.

        Returns:
             list[dict]
        """
        input_ = []
        for config in self.config.get("input", []):
            path_ = os.path.join(self.work_dir, config["name"])
            input_.append(
                {
                    "name": config["name"],
                    "isManuallyChanged": True,
                    "rendered": read(path_) if os.path.exists(path_) else "",
                }
            )
        return input_

    @property
    def postProcessors(self):
        """
        Returns a list of postProcessors used in the unit.
        Override upon inheritance as necessary.

        Returns:
             list[dict]
        """
        return self.config.get("postProcessors", [])

    @property
    def preProcessors(self):
        """
        Returns a list of preProcessors used in the unit.
        Override upon inheritance as necessary.

        Returns:
             list[dict]
        """
        return self.config.get("preProcessors", [])

    def to_json(self):
        """
        Returns the unit in JSON format.

        Returns:
             dict
        """
        config = super(BaseExecutionUnit, self).to_json()
        config.update(
            {
                "application": self.application,
                "executable": self.executable,
                "input": self.input,
                "monitors": self.monitors,
                "name": self.name,
                "postProcessors": self.postProcessors,
                "preProcessors": self.preProcessors,
                "results": self.results,
                "type": "execution",
                "status": self.status,
                "statusTrack": self.status_track,
            }
        )
        return config

    @property
    def status(self):
        """
        Returns unit status.

        Note: This is a placeholder for future to extract unit status based on unit outputs.

        Returns:
             str
        """
        return "finished"

    @property
    def status_track(self):
        """
        Returns unit status track.

        Returns:
             list[dict]
        """
        return [{"trackedAt": int(os.path.getmtime(self.work_dir)), "status": self.status}]

    @property
    def results(self):
        """
        Returns a list of property names extracted from the unit.

        Returns:
             list[dict]
        """
        return self.config.get("results", [])

    @property
    def monitors(self):
        """
        Returns a list of monitors used in the unit.

        Returns:
             list[dict]
        """
        return self.config.get("monitors", [])


"""
# mkb_sammlung_europa.py
This DAG updates the following datasets:

- [100148](https://data.bs.ch/explore/dataset/100148)

"""
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime, timedelta
from airflow.operators.docker_operator import DockerOperator

default_args = {
    'owner'                 : 'hester.pieters',
    'description'           : 'Run the mkb_sammlung_europa.py docker container',
    'depend_on_past'        : False,
    'start_date'            : datetime(2022, 1, 27),
    'email'                 : ["jonas.bieri@bs.ch", "jonas.eckenfels@bs.ch", "orhan.saeedi@bs.ch", "nicolas.maire@bs.ch"],
    'email_on_failure'      : True,
    'email_on_retry'        : False,
    'retries'               : 0,
    'retry_delay'           : timedelta(minutes=15)
}

with DAG('mkb_sammlung_europa', default_args=default_args, schedule_interval=None, catchup=False) as dag:
    dag.doc_md = __doc__
    upload = DockerOperator(
        task_id='upload',
        image='mkb_sammlung_europa:latest',
        api_version='auto',
        auto_remove=True,
        command='/bin/bash /code/data-processing/mkb_sammlung_europa/etl.sh ',
        container_name='mkb_sammlung_europa--upload',
        docker_url="unix://var/run/docker.sock",
        network_mode="bridge",
        tty=True,
        volumes=['/data/dev/workspace/data-processing:/code/data-processing', '/mnt/OGD-DataExch/PD-Kultur-MKB:/code/data-processing/mkb_sammlung_europa/data']
    )


from typing import List

class Solution:
    def restoreString(self, s: str, indices: List[int]) -> str:
        ans = [""] * len(s)

        for i in range(len(s)):
            ans[indices[i]] = s[i]
        return "".join(ans)

assert Solution().restoreString("codeleet", [4, 5, 6, 7, 0, 2, 1, 3])


import random
from statistics import median

def fill(ax,nx, x,y):       # fill the list a with n random integers in the range x --- y inclusive BUT NO duplicates permitted THIS code NEEDS to be fixed
    j = 0
    while (j < nx):  # populate the array using the while loop
        a = random.randint(x, y)  # Return a random integer .
        if a not in ax:
          ax.append(a)
          j = j + 1
    return ax
def display(ax):
    print("2. Display the list as follows: ", ax)  # DONE

def sort_list_asc(ax):
    sorted_list = sorted(ax, reverse=True)
    return sorted_list

def min_integer(ax):
    # return the smallest value in the list
    smallest = min(ax)
    return smallest

def max_integer(ax):
    # return the largest value in the list
    mx = max(ax)  # place holder only
    return mx

def div3(ax):
    count_three = 0
    for i in ax:
        if i % 3 == 0:
            count_three = count_three + 1
    return count_three
    # v = -5
    # return v

def multi5(ax):
    count_five = 0
    for i in ax:
        if i % 5 == 0:
            count_five = count_five + 1
    return count_five
    # m = 11
    # return m

def avg_of_list(ax):
    # return the average of the integers in the list
    #must call the sum() function here and divide by the size of the array
    size_of_array = sum(ax)
    average_list = size_of_array/len(ax)
    return average_list

def maximum(ax):
    # return the largest value in the list
    mx = ax[0]  # place holder only
    return mx

def minimum(ax):
    # return the smallest value in the list
    mn = ax[-1]
    return mn

def median_number(ax):
    med = median(ax)
    return med

def digit1(ax):
    list_ones = [11,21,31]
    count_end_one = 0
    for i in ax:
        if i in list_ones:
            count_end_one = count_end_one + 1
    return count_end_one

# ==========================================
# NOW we call the functions
#Suggested template i.e all calculations should be in the functions; simply call the functions
array = []
n = 21  # array size
x = 10
y = 40
array = fill(array,n, x, y)
display(array)
mx = max_integer(array)
mn = min_integer(array)
d = div3(array)
m = multi5(array)
med = median_number(array)
n1 = digit1(array)
array = sort_list_asc(array)
ave = avg_of_list(array)
print("3. The sorted list in descending order is ", array)
print( "4. The maximum integer in the list  is  : ", mx )
print( "5. The minimum integer in the list  is :", mn)
print( "6. The number of integers that are evenly divisible by 3 (no remainder)is : ", d)
print( "7. The number of integers in the list that are multiples of 5 (10, 15, 20,25, etc ) is : ", m)
print( "8. The median of the list is : ", med)
print( "9. the number of integers that end with a 1 is : ", n1)
print("10. The average of the integers is ", round(ave), ".( Please note the number is rounded.)")


import importlib
class Device:
    def __init__(self, package_name):
        self.package_name = package_name
        self.dynamic_import()

    def dynamic_import(self):
        common_module = importlib.import_module('device_common')
        name_module_map = {name:common_module for name in common_module.__all__}
        if self.package_name != "device_common":
            special_module = importlib.import_module(self.package_name)
            name_module_map.update({name:special_module for name in special_module.__all__})
        for attr_name, module in name_module_map.items():
            class_module = importlib.import_module(name_module_map[attr_name].__name__+"."+attr_name)
            camel = "".join(map(str.capitalize, attr_name.split("_")))
            the_obj = getattr(class_module,camel)()
            setattr(self, attr_name, the_obj)

if __name__ == '__main__':
    from minitest import *

    with test(Device):
        d6000 = Device("device_6000")
        d6000.firewall.some().must_equal("device_common.firewall.Firewall")
        d6000.system.some().must_equal("device_6000.system.System")

        d7000 = Device("device_7000")
        d7000.firewall.some().must_equal("device_7000.firewall.Firewall")
        d7000.load_balance.some().must_equal("device_7000.load_balance.LoadBalance")
        d7000.system.some().must_equal("device_7000.system.System")
        d7000.system.common().must_equal("common")
        d7000.system.special().must_equal("special")


# 표준 라이브러리
from sys import path as pth
from os import path, remove
from io import StringIO
import csv
import codecs

# 서드 파티 라이브러리
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
import pandas as pd
import requests

# 로컬
pth.append(path.dirname(path.abspath(path.dirname(__file__))))
from database import crud
from dependency import get_db
import model.prophet as pr
import model.tf as tf
import routers.codes as codes

router = APIRouter()

class TfInput(BaseModel):
    user_data_set_id: int

class TfPreprocess(BaseModel):
    input_raw_data: dict
    set_rate: float

class TfTraining(BaseModel):
    input_processed_data: dict
    user_id: str

class TfCustomTraining(BaseModel):
    input_processed_data: dict
    input_layer: list
    user_id: str

class TfEvaluate(BaseModel):
    input_processed_data: dict
    training_model_id: int

class TfPredict(BaseModel):
    user_data_set_id: int
    input_processed_data: dict
    training_model_id: int
    user_id: str
    period: int

class ProphetInput(BaseModel):
    user_data_set_id: int
    periods: int
    cps: float

@router.post("/ml/prophet/stock/", tags=["prophet"], description=" 데이터 입력")
def analysis_prophet(
    prophet_input: ProphetInput,
    db: Session = Depends(get_db),
):
    user_data_set_id = prophet_input.user_data_set_id
    periods = prophet_input.periods
    cps = prophet_input.cps

    analysis_value = "Close"
    data = crud.get_user_data_set(user_data_set_id=user_data_set_id, db=db)

    # csv
    if data.user_data_set_start == None:  # 7
        original_df, analysis_value = csv_data_call(data)
        df = pd.read_csv(StringIO(original_df.to_csv()), index_col="Date")
        df = df.drop(["Unnamed: 0"], axis=1)
    # 기간별
    else:
        original_df, analysis_value = db_data_call(data, db=db)
        df = pd.read_csv(StringIO(original_df.to_csv()), index_col="Date")  # 기본 인덱스는 날짜기준.
        df.sort_values(by=["Date"], axis=0, inplace=True)  # date 기준 내림차순 정렬
        df = df.drop(["Unnamed: 0"], axis=1)

    # 호출
    result = pr.prophet_stock(df, analysis_value, periods, cps, original_df)

    # 1.모델 임시 생성 (1번 prphet_test로 임의 생성)
    # 2.사용자-데이터 분석에 결과 저장
    predict_data = crud.insert_user_data_predict(
        user_data_set_id=data.user_data_set_id,
        training_model_id=1,
        user_id=data.user_id,
        db=db,
    )

    # 3. 분석 결과 저장
    data = {"user_data_predict_id": predict_data.user_data_predict_id}
    upload = {"file": result.encode("utf-8")}
    try:
        requests.post(
            "{base_url}/csv/upload/userpredictdata",
            files=upload,
            data=data,
        )
    except:
        raise HTTPException(status_code=400, detail="호출 X")

    s = codes.prophet_code(analysis_value, periods, cps)

    return {"code": s, "user_data_predict_id": predict_data.user_data_predict_id}

@router.post("/ml/tensorflow/input", tags=["tensorflow"], description="Data Input")
def data_input(tf_input: TfInput, db: Session = Depends(get_db)):
    data = crud.get_user_data_set(user_data_set_id=tf_input.user_data_set_id, db=db)
    analysis_value = "Close"

    # csv
    if data.user_data_set_start == None:
        original_df, analysis_value = csv_data_call(data)
        df = pd.read_csv(StringIO(original_df.to_csv()))
        df = df.drop(["Unnamed: 0"], axis=1)
    # 기간별
    else:
        original_df, analysis_value = db_data_call(data, db=db)
        df = pd.read_csv(StringIO(original_df.to_csv()))
        df.sort_values(by=["Date"], axis=0, inplace=True)
        df = df.drop(["Unnamed: 0"], axis=1)

    raw_data = []
    for i in range(len(df)):
        raw_data.append({"Date": df["Date"][i], "analysis_value": df[analysis_value][i]})

    return {"raw_data": raw_data, "code": codes.tf_data_input_code(analysis_value)}

@router.post("/ml/tensorflow/preprocess", tags=["tensorflow"], description="Data Preprocess")
def data_preprocess(tf_preprocess: TfPreprocess):
    processed_data = tf.data_preprocess(tf_preprocess.input_raw_data, tf_preprocess.set_rate)
    processed_data["code"] = codes.tf_data_preprocess_code(tf_preprocess.set_rate)
    return processed_data

@router.post("/ml/tensorflow/cnn/training", tags=["tensorflow"], description="CNN Model Training")
def cnn_model_training(tf_training: TfTraining, db: Session = Depends(get_db)):
    trained_data = tf.cnn_model_training(tf_training.input_processed_data, tf_training.user_id, db)
    trained_data["code"] = codes.tf_cnn_model_training_code()
    return trained_data

@router.post("/ml/tensorflow/lstm/training", tags=["tensorflow"], description="LSTM Model Training")
def lstm_model_training(tf_training: TfTraining, db: Session = Depends(get_db)):
    trained_data = tf.lstm_model_training(tf_training.input_processed_data, tf_training.user_id, db)
    trained_data["code"] = codes.tf_lstm_model_training_code()
    return trained_data

@router.post(
    "/ml/tensorflow/custom/training",
    tags=["tensorflow"],
    description="Custom Model Training",
)
def custom_model_training(tf_custom_training: TfCustomTraining, db: Session = Depends(get_db)):
    trained_data = tf.custom_model_training(
        tf_custom_training.input_processed_data,
        tf_custom_training.input_layer,
        tf_custom_training.user_id,
        db,
    )
    trained_data["code"] = codes.tf_custom_model_training_code(tf_custom_training.input_layer)
    return trained_data

@router.post("/ml/tensorflow/evaluate", tags=["tensorflow"], description="Model Evaluate")
def model_evaluate(tf_evaluate: TfEvaluate):
    evaluated_data = tf.model_evaluate(
        tf_evaluate.input_processed_data, tf_evaluate.training_model_id
    )
    evaluated_data["code"] = codes.tf_model_evaluate_code()
    return evaluated_data

@router.post("/ml/tensorflow/predict", tags=["tensorflow"], description="Model Predict")
def model_predict(tf_predict: TfPredict, db: Session = Depends(get_db)):
    predicted_data = tf.predict_future(
        tf_predict.user_data_set_id,
        tf_predict.input_processed_data,
        tf_predict.training_model_id,
        tf_predict.user_id,
        tf_predict.period,
        db,
    )
    predicted_data["code"] = codes.tf_model_predict_code(tf_predict.period)
    return predicted_data

# 파일 받아오기
def csv_data_call(data):
    try:
        files = requests.get(
            f"{base_url}/csv/download/userdataset/bytes/{data.user_data_set_id}",
        ).json()

    except:
        raise HTTPException(status_code=400, detail="호출 X")
    data = StringIO(files["file"])
    df = pd.read_csv(data, delimiter=",")

    s = set(["Date", "Close"])
    analysis_value = "Close"

    if s.issubset(set(df.columns)):
        df = df[["Date", "Close"]]
    else:
        analysis_value = "Temp"
        df = df[["Date", "Temp"]]

    return df, analysis_value

# 기간과 코드 정보 가져오기
def db_data_call(data, db: Session):
    stock_list = crud.get_data_list_by_id_date(
        db=db,
        start_date=data.user_data_set_start,
        end_date=data.user_data_set_end,
        code=data.data_list_id,
    )

    analysis_value = "Close"

    if stock_list[0].data_list_id < 7:
        df = pd.DataFrame(columns=["Date", "Close"])  # date -> ds 변경
        for sk in stock_list:
            df = df.append(
                {"Date": sk.data_set_date, "Close": str(sk.data_set_value)},
                ignore_index=True,
            )
            analysis_value = "Close"
    else:
        df = pd.DataFrame(columns=["Date", "Temp"])  # date -> ds 변경
        for sk in stock_list:
            df = df.append(
                {"Date": sk.data_set_date, "Temp": str(sk.data_set_value)},
                ignore_index=True,
            )
            analysis_value = "Temp"

    return df, analysis_value


class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        holder_0 = []
        holder_1 = []
        for symbol in s:
            if symbol in ('(', '{', '['):
                holder_0.append(symbol)
                while (holder_0 and holder_1):
                    if (holder_0[-1] == '[' and holder_1[-1] == ']') or \
                            (holder_0[-1] == '{' and holder_1[-1] == '}') or \
                            (holder_0[-1] == '(' and holder_1[-1] == ')'):
                        holder_0.pop()
                        holder_1.pop()
                    else:
                        return False
            if symbol in ('}', ']', ')'):
                holder_1.append(symbol)
                while (holder_0 and holder_1):
                    if (holder_0[-1] == '[' and holder_1[-1] == ']') or \
                            (holder_0[-1] == '{' and holder_1[-1] == '}') or \
                            (holder_0[-1] == '(' and holder_1[-1] == ')'):
                        holder_0.pop()
                        holder_1.pop()
                    else:
                        return False
        return holder_0 == [] and holder_1 == []

# Damn, why did i use such dump method?
# check my current implementation, i truely learnt sth right?

class Solution(object):
    def isValid(self, s):
        if s == '':
            return False

        stack = []
        for char in s:
            if char in ['(', '{', '[']:
                stack.append(char)
            else:
                if stack:
                    last = stack.pop()
                    if (last == '[' and char != ']') or (last == '(' and char != ')') or (last == '{' and char != '}'):
                        return False
                else:
                    return False
        return len(stack)==0


"""
INTRO GATES / ADD TWO DIGITS

You are given a two-digit integer n. Return the sum of its digits.

Example

    For n = 29, the output should be
    addTwoDigits(n) = 11.

Input/Output

    [input] integer n

        A positive two-digit integer.

        Constraints:
        10 ≤ n ≤ 99.

    [output] integer

        The sum of the first and second digits of the input number.
"""

def addTwoDigits(n):
    sum = 0
    for digit in str(n):
        sum += int(digit)

    return sum


from sys import path
from os.path import dirname

abs_path = dirname(dirname(__file__))
path.insert(0, abs_path+r'/Computing_files')
from ODE_solvers import LG4_imp, RK4_exp, EC1_exp
from ODE_solvers_static_sun import RK4_exp_step_static_sun
from Gravitational_force import der_r, der_v_SI
path.__delitem__(0)

from numpy import arange, empty, array, sqrt, arctan, cos, sin
from scipy.constants import G, pi
from matplotlib import pyplot as plt

def get_angle(x, y):
    if x<0:
        deg = arctan(y/x)+pi
    elif y<0:
        deg = arctan(y/x)+2*pi
    else:
        deg = arctan(y/x)
    return deg

def RK4_exp_static_earth_transfer(n_objects, t_0, t_end, r_0, v_0, m, h, der_r, der_v, r_transfer, t_first_transfer):
    t = arange(t_0, t_end + h / 2, h)
    v_x = empty((n_objects, t.shape[0]))
    v_y = empty((n_objects, t.shape[0]))
    x = empty((n_objects, t.shape[0]))
    y = empty((n_objects, t.shape[0]))
    for i in range(n_objects):
        v_x[i, 0] = v_0[i, 0]
        v_y[i, 0] = v_0[i, 1]
        x[i, 0] = r_0[i, 0]
        y[i, 0] = r_0[i, 1]
    i = 1
    while (t[i] < t_first_transfer):
        v_x[:, i], v_y[:, i], x[:, i], y[:, i] = RK4_exp_step_static_sun(n_objects, v_x[:, i - 1], v_y[:, i - 1],
                                                                         x[:, i - 1], y[:, i - 1], m, h, der_r, der_v)
        i += 1
    for i_r in range(r_transfer.shape[0]):
        r_initial = sqrt(x[0, i-1]**2+y[0, i-1]**2)

        delta_v = sqrt(G*m[-1]/r_initial)*(sqrt(2*r_transfer[i_r]/(r_initial + r_transfer[i_r]))-1)

        angle = get_angle(x[0, i-1], y[0, i-1])
        v_x [0, i-1] += delta_v*sin(angle)
        v_y [0, i-1] += delta_v*cos(angle)
        angle += pi
        print (angle)
        angle_round = 0

        new_angle = get_angle(x[0, i-1], y[0, i-1])
        while (new_angle<angle):
            print (new_angle)
            v_x[:, i], v_y[:, i], x[:, i], y[:, i] = RK4_exp_step_static_sun(n_objects, v_x[:, i - 1], v_y[:, i - 1],
                                                                                x[:, i - 1], y[:, i - 1], m, h, der_r, der_v)
            new_angle = get_angle(x[0, i], y[0, i])+angle_round*2*pi
            if (new_angle<(angle-pi)):
                print ("TEST")
                angle_round += 1
                new_angle += 2*pi
            print (new_angle)
            i += 1
            if (i==t.shape[0]):
                break
        print (i)
        delta_v = sqrt(G*m[-1]/r_transfer[i_r]) * (1-sqrt(2*r_initial/(r_initial+r_transfer[i_r])))
        print (delta_v)
        angle = get_angle(v_x[0, i - 1], v_y[0, i - 1])
        v_x[0, i - 1] = v_x[0, i - 1] + delta_v * cos(angle)
        v_y[0, i - 1] = v_y[0, i - 1] + delta_v * sin(angle)
    while (i < t.shape[0]):
        v_x[:, i], v_y[:, i], x[:, i], y[:, i] = RK4_exp_step_static_sun(n_objects, v_x[:, i - 1], v_y[:, i - 1],
                                                                         x[:, i - 1], y[:, i - 1], m, h, der_r, der_v)
        i += 1

    return t, x, y, v_x, v_y

if __name__=="__main__":
    t_0, t_end = 0, 150000
    h = 1

    m =array([720, 5.972*(10**24)])
    r = array([[322e3, 0]])
    v = array([[0, sqrt(G*m[-1]/r[0, 0])]])
    r_transfer = array([10000e3, 40000e3, 35680e3])

    t, x, y, v_x, v_y = RK4_exp_static_earth_transfer(1, t_0, t_end, r, v, m, h, der_r, der_v_SI, r_transfer, 0.1)
    plt.figure('Test')
    plt.plot(x[0], y[0])
    plt.show()


"""
题目:
从上到下按层打印二叉树，同一层结点从左至右输出，每一层输出一行
"""
class TreeLinkNode:
	def __init__(self,x):
		self.val=x
		self.left=None
		self.right=None

class Solution:
    def Print(self,pRoot):
        if not pRoot:
            print('None')
        nodestack=[pRoot]
        result=[]
        while nodestack:
            nextstack=[]
            res=[]
            for i in nodestack:
                res.append(i.val)
                if i.left:
                    nextstack.append(i.left)
                if i.right:
                    nextstack.append(i.right)
            nodestack=nextstack
            result.append(res)
        for i,v in enumerate(result):
            for i in range(0,len(v)):
                print(v[i],end="")
            print('\n')

T=TreeLinkNode(1)
T.left=TreeLinkNode(2)
T.right=TreeLinkNode(3)
T.left.left=TreeLinkNode(4)
T.left.right=TreeLinkNode(5)
T.right.left=TreeLinkNode(6)
T.right.right=TreeLinkNode(7)
S=Solution()
S.Print(T)


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

from globals import *
from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC
import pyinotify
import time, os

def wait_for_file_creation(filename, userId, songId, songUrl, msgrId, type, lang):
    global CURRENT_LOOP_RESULT
    global CURRENT_USER_ID
    global CURRENT_SONG_ID
    global CURRENT_SONG_URL
    global CURRENT_MSGR_ID
    global CURRENT_TYPE_ID
    global CURRENT_LANG_ID

    CURRENT_USER_ID = userId
    CURRENT_SONG_ID = songId
    CURRENT_SONG_URL = songUrl
    CURRENT_MSGR_ID = msgrId
    CURRENT_TYPE_ID = type
    CURRENT_LANG_ID = lang
    CURRENT_LOOP_RESULT = 0

    wm = pyinotify.WatchManager()
    eh = MyEventHandler()
    wm.add_watch(filename, pyinotify.ALL_EVENTS, rec=True)
    notifier = pyinotify.Notifier(wm, eh)
    if(DEBUG==1):
        print(str(userId) + " waits for " + filename + "...")
    while (CURRENT_LOOP_RESULT!=1):
        try:
            notifier.process_events()
            if notifier.check_events():
                notifier.read_events()
        except:
            e = sys.exc_info()
            if(DEBUG==1):
                print(str(e))
            break
    if(DEBUG==1):
        print("Stopping watcher for: "+filename)
    notifier.stop()

class MyEventHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        global CURRENT_LOOP_RESULT
        global CURRENT_USER_ID
        global CURRENT_SONG_ID
        global CURRENT_SONG_URL
        global CURRENT_MSGR_ID
        global CURRENT_LANG_ID

        CURRENT_LOOP_RESULT = 1
        if(DEBUG==1):
            print("Got it! Checking...")
        checkFileAndReturn(CURRENT_USER_ID, CURRENT_SONG_ID, CURRENT_SONG_URL, CURRENT_MSGR_ID, "audio", CURRENT_LANG_ID)

def checkFileAndReturn(userId, songId, songUrl, msgrId, filetype, lang):
    if(filetype == "audio"):
        file = "./mp3/"+songId+".mp3"
    elif(filetype == "video"):
        file = "./mp3/"+songId+".mp4"

    imgfile = "./mp3/"+songId+".jpg"

    #add id3 tags
    if(filetype == "audio"):
        if(DEBUG==1):
            print("Writing IDv3 tag...")
        audio = EasyID3(file)
        audio['title'] = songId.replace('_',' ')
        audio['artist'] = "DJ Tuner"
        audio['album'] = "Tunes2u.com"
        audio.save()

        #add id3 image
        try:
            a = MP3(file, ID3=ID3)
            with open(imgfile, 'br') as f:
                contents = f.read()
            a.tags.add(APIC(encoding=3, mime=u'image/jpg', type=3, desc=u'Albumcover', data=contents))
            a.save()
        except:
            if(DEBUG==1):
                print("IMG for ID3 not found...")

    if(filetype=="audio"):
        if(DEBUG==1):
            print("Returning audio file...")

        if(msgrId=="telegram"):
            data={'chat_id': userId, 'text': 'https://tunes2u.com/'+songId+'.mp3'}
            sendTelegramRaw(userId,data)
        elif(msgrId=="facebook"):
            if("de" in lang):
                data={'recipient':{'id': userId}, 'message':{'attachment':{'type':'template','payload':{'template_type':'generic','elements':[{'title':songId.replace('_',' '),'image_url':'https://tunes2u.com/'+songId+'.jpg','default_action':{'type':'web_url','url':songUrl,'messenger_extensions':'true','webview_height_ratio':'compact'},'buttons':[{'type':'web_url','url':'https://tunes2u.com/tune4u.php?file='+songId+'.mp3','title':'Download MP3'},{'type':'postback','title':'Video suchen...','payload':'video '+songId.replace('_',' ')},{'type':'element_share'}]}]}}}}
            else:
                data={'recipient':{'id': userId}, 'message':{'attachment':{'type':'template','payload':{'template_type':'generic','elements':[{'title':songId.replace('_',' '),'image_url':'https://tunes2u.com/'+songId+'.jpg','default_action':{'type':'web_url','url':songUrl,'messenger_extensions':'true','webview_height_ratio':'compact'},'buttons':[{'type':'web_url','url':'https://tunes2u.com/tune4u.php?file='+songId+'.mp3','title':'Download MP3'},{'type':'postback','title':'Search video...','payload':'video '+songId.replace('_',' ')},{'type':'element_share'}]}]}}}}

            sendFacebookRaw(userId,data)

    if(filetype=="video"):
        if(DEBUG==1):
            print("Returning video file...")

        if(msgrId=="telegram"):
            data={'chat_id': userId, 'text': 'https://tunes2u.com/'+songId+'.mp4'}
            sendTelegramRaw(userId,data)
        elif(msgrId=="facebook"):
            if("de" in lang):
                data={'recipient':{'id': userId}, 'message':{'attachment':{'type':'template','payload':{'template_type':'generic','elements':[{'title':songId.replace('_',' '),'image_url':'https://tunes2u.com/'+songId+'.jpg','default_action':{'type':'web_url','url':songUrl,'messenger_extensions':'true','webview_height_ratio':'compact'},'buttons':[{'type':'web_url','url':'https://tunes2u.com/tune4u.php?file='+songId+'.mp4','title':'Download MP4'},{'type':'postback','title':'MP3 suchen...','payload':songId.replace('_',' ')},{'type':'element_share'}]}]}}}}
            else:
                data={'recipient':{'id': userId}, 'message':{'attachment':{'type':'template','payload':{'template_type':'generic','elements':[{'title':songId.replace('_',' '),'image_url':'https://tunes2u.com/'+songId+'.jpg','default_action':{'type':'web_url','url':songUrl,'messenger_extensions':'true','webview_height_ratio':'compact'},'buttons':[{'type':'web_url','url':'https://tunes2u.com/tune4u.php?file='+songId+'.mp4','title':'Download MP4'},{'type':'postback','title':'Search MP3...','payload':songId.replace('_',' ')},{'type':'element_share'}]}]}}}}

            sendFacebookRaw(userId,data)

    #check total searches and send tips or ads depending on it
    tip = check_total_searches(userId, lang)

    if(tip != "notip"):
        if(msgrId=="telegram"):
            sendTelegramMessage(userId,tip)
        elif(msgrId=="facebook"):
            sendFacebookMessage(userId,tip)
    else:
        if(DEBUG==1):
            print("No tip to be returned...")

    #check if old files should be removed
    clear_cache()

def check_total_searches(userid, lang):
    totalSearches = get_user_searches_count(userid)

    try:
        if("de" in lang):
            return TIP_LINKS_DE[totalSearches]
        else:
            return TIP_LINKS_EN[totalSearches]
    except:
        return "notip"

def clear_cache():
    #search and clear mp3's older than 5mins
    now = time.time()
    cutoff = now - (300)
    files = os.listdir("mp3/")
    for xfile in files:
        if "1.png" not in xfile and "tune4u.php" not in xfile and "index.php" not in xfile and "getfile.php" not in xfile:
            if os.path.isfile( "mp3/" + xfile ):
                t = os.stat( "mp3/" + xfile )
                c = t.st_ctime
                if c < cutoff:
                    os.remove("mp3/" + xfile)


import scrapy
from scrapy.http import FormRequest

from locations.geo import point_locations
from locations.structured_data_spider import StructuredDataSpider

class PetsAtHomeGBSpider(StructuredDataSpider):
    name = "petsathome_gb"
    item_attributes = {"brand": "Pets at Home", "brand_wikidata": "Q7179258"}
    wanted_types = ["PetStore"]
    download_delay = 0.2

    def start_requests(self):
        for lat, lon in point_locations("eu_centroids_20km_radius_country.csv", "UK"):
            yield FormRequest(
                url="https://community.petsathome.com/models/utils.cfc",
                formdata={
                    "method": "functionhandler",
                    "returnFormat": "json",
                    "event": "webproperty.storelocator",
                    "lat": str(lat),
                    "lng": str(lon),
                    "radius": "50",
                    "companyID": "any",
                    "active": "true",
                },
                headers={"X-Requested-With": "XMLHttpRequest"},
            )

    def parse(self, response):
        for node in response.json()["data"]:
            if "groom-room" not in node["slug"]:
                website_url = "https://community.petsathome.com" + node["slug"]
                yield scrapy.Request(website_url, callback=self.parse_sd)


import copy
n, m= map(int, input().split())
r, c, d= map(int, input().split())

ve=[0,1,2,3]
vec=[(-1,0),(0,1),(1,0),(0,-1)]
_map=[]
_maptest=[]
ans=0
anst=0
for _ in range(n):
    li=[]
    li=list(map(int, input().split()))
    _map.append(list(li))
for i in _map:
    ans+=i.count(1)
_maptest=copy.deepcopy(_map)
_map[r][c]=1
while True:
    if _map[r-1][c]+_map[r][c+1]+_map[r+1][c]+_map[r][c-1]>3:
        rt=r+vec[d-2][0]
        ct=c+vec[d-2][1]
        if _maptest[rt][ct]!=0:
            break
        else:
            r+=vec[d-2][0]
            c+=vec[d-2][1]
    else:
        rt=r+vec[d-1][0]
        ct=c+vec[d-1][1]
        if _map[rt][ct]==0:
            d=ve[d-1]
            r+=vec[d][0]
            c+=vec[d][1]
            _map[r][c]=1
        else:
            d=ve[d-1]
for i in _map:
    anst+=i.count(1)

print(anst-ans)