import json
import logging

import requests_mock

from arcgis_proxy.utils.reproject import reproject_esrijson
from arcgis_proxy.utils.services import get_image_service_url
from arcgis_proxy.utils.geostore import get_esrijson_wm
from arcgis_proxy.utils.geostore import get_geostore

from tests.mocks import mock_geostore

with open("tests/fixtures/geojson.json") as src:
    geojson = json.load(src)

with open("tests/fixtures/esrijson.json") as src:
    esrijson = json.load(src)

with open("tests/fixtures/esrijson_wm.json") as src:
    esrijson_wm = json.load(src)

with open("tests/fixtures/geostore.json") as src:
    geostore = json.load(src)

geostore_id = "204c6ff1dae38a10953b19d452921283"
service_url = "https://gis.forest-atlas.org/server/rest/services/eth/EthiopiaRestoration/ImageServer"

@requests_mock.Mocker(kw="mocker")
def test_get_geostore(client, mocker):
    """Test to make calls to geostore"""

    logging.debug("[TEST]: Test to make call to geostore")

    with client:
        mocked = mock_geostore(mocker)
        result = get_geostore(geostore_id, "api-key-test")

    assert result == geostore
    assert (
        f"/v1/geostore/{geostore_id}?format=esri"
        in f"{mocked.last_request.path}?{mocked.last_request.query}"
    )

# @mock.patch("arcgis_proxy.utils.geostore.get_geostore", side_effect=mocked_get_geostore)
@requests_mock.Mocker(kw="mocker")
def test_get_esrijson_wm(client, mocker):
    """Test to get ESRIJSON from geostore"""

    logging.debug("[TEST]: Test get ESRIJSON in WM from geostore")

    with client:
        mock_geostore(mocker)
        ej = get_esrijson_wm(geostore_id, "api-key-test")

    logging.debug("[TEST]: esrijson_wm: {}".format(esrijson_wm))

    assert ej == esrijson_wm
    # self.assertIn(mock.call(geostore_id), mock_geostore_id.call_args_list)

def test_reproject_esrijson():
    """Test if ESRI Json gets correctly projected into Web Mercator"""

    logging.debug("[TEST]: Test reproject ESRIJSON")

    esrijson_proj = reproject_esrijson(esrijson)
    assert esrijson_proj == esrijson_wm

def test_get_image_service_url():
    """Test if service URL gets correctly generated"""

    logging.debug("[TEST]: Test service URL generation")

    url = get_image_service_url(
        server="forest-atlas", service="eth/EthiopiaRestoration"
    )
    assert url == service_url

    url = get_image_service_url(
        server="forest-atlas", service="eth/EthiopiaRestoration"
    )
    assert url == service_url


from tortuga.cli import tortugaCli
from tortuga.wsapi.softwareProfileWsApi import SoftwareProfileWsApi

class CopySoftwareProfileCli(tortugaCli.TortugaCli):
    def __init__(self):
        super().__init__()

    def parseArgs(self, usage=None):
        option_group_name = _('Copy Software Profile Options')
        self.addOptionGroup(option_group_name, '')
        self.addOptionToGroup(option_group_name,
                              '--src', required=True,
                              dest='srcSoftwareProfileName',
                              metavar='NAME',
                              help=_('Name of source software profile'))
        self.addOptionToGroup(option_group_name,
                              '--dst', required=True,
                              dest='dstSoftwareProfileName',
                              metavar='NAME',
                              help=_('Name of destination software profile'))

        super().parseArgs(usage=usage)

    def runCommand(self):
        self.parseArgs(_('Copy an existing software profile'))

        api = self.configureClient(SoftwareProfileWsApi)
        api.copySoftwareProfile(
            self.getArgs().srcSoftwareProfileName,
            self.getArgs().dstSoftwareProfileName)

def main():
    CopySoftwareProfileCli().run()


import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font
from .scrollable_listbox_and_input import ScrollableListboxAndInput
from .config_holder import ConfigHolder
from .language_holder import LanguageHolder

class FontSelector:

  def __init__ (self, family, size):
    self._family = family
    self._size = size
    self._onupdates = list()

  @property
  def family (self):
    return self._family

  @family.setter
  def family (self, value):
    self._family = value
    self.call_onupdates()

  @property
  def size (self):
    return self._size

  @size.setter
  def size (self, value):
    self._size = value
    self.call_onupdates()

  def add_onupdate (self, func):
    self._onupdates.append(func)

  def call_onupdates (self):
    for onupdate in self._onupdates:
      onupdate()

  def get_font (self):
    return [ self.family, self.size ]

"""
+---------+
| listbox |
|         |
|         |
+---------+
| input   |
+---------+
"""

class FamilySelectorWidget (ScrollableListboxAndInput):

  def __init__ (self, family, master=None, *, scrollx=False, scrolly=True):
    self.family = family
    super().__init__(master, scrollx=scrollx, scrolly=scrolly)

  def setup_widgets (self):
    super().setup_widgets()
    for family in tk.font.families():
      self.listbox.listbox.insert(tk.END, family)
    self.set_value(self.family)

"""
+---------+
| listbox |
|         |
|         |
+---------+
| input   |
+---------+
"""

class SizeSelectorWidget (ScrollableListboxAndInput):

  def __init__ (self, size, master=None, *, sizerange=(1, 50), scrollx=False, scrolly=True):
    self.size = size
    self.sizerange = sizerange
    super().__init__(master, scrollx=scrollx, scrolly=scrolly)

  def get_value (self):
    try:
      return int(super().get_value())
    except ValueError:
      return 0 #return 0 on error.

  def setup_widgets (self):
    super().setup_widgets()
    sizemin = min(self.sizerange)
    sizemax = max(self.sizerange)
    for size in range(sizemin, sizemax):
      self.listbox.listbox.insert(tk.END, str(size))
    self.set_value(self.size)

"""
+---------+
| label   |
+---------+
| input   |
+---------+
"""

class PreviewWidget (ttk.Frame):

  def __init__ (self, master=None, *, width, height):
    super().__init__(master)
    self.width = width
    self.height = height
    self.previewlabel = None
    self.previewentry = None
    self.previewvar = None
    self.setup_widgets()

  def setup_widgets (self):
    previewvar = tk.StringVar(value="abcABC123")
    previewframe = ttk.Frame(self, width=self.width, height=self.height)
    previewframe.pack(fill=tk.X, expand=True)
    previewlabel = ttk.Label(previewframe, textvariable=previewvar, anchor=tk.CENTER, background="#ffffff")
    previewlabel.place(relx=0.0, rely=0.0, relwidth=1.0, relheight=1.0)
    previewentry = ttk.Entry(self, textvariable=previewvar)
    previewentry.pack(fill=tk.X, expand=True)
    self.previewvar = previewvar
    self.previewlabel = previewlabel
    self.previewentry = previewentry

  def apply_font (self, font):
    self.previewlabel.config(font=font)

"""
+-----------------+
|        [o][_][x]|
+-----------------+
| preview         |
|                 |
+--------+--------+
| family | size   |
|        |        |
+--------+--------+
|     [ok][cancel]|
+-----------------+
"""

class FontSelectorWindow (tk.Toplevel, ConfigHolder, LanguageHolder):

  def __init__ (self, fontselector, master=None, *, config, language):
    tk.Toplevel.__init__(self, master)
    ConfigHolder.__init__(self, config=config)
    LanguageHolder.__init__(self, language=language)
    self.fontselector = fontselector
    self.preview = None
    self.familyselector = None
    self.sizeselector = None
    self.setup_widgets()

  def _ok (self):
    self.fontselector.family = self.familyselector.get_value()
    self.fontselector.size = self.sizeselector.get_value()
    self.destroy()

  def _onupdate (self):
    self.preview.apply_font((
      self.familyselector.get_value(),
      self.sizeselector.get_value(),
    ))

  def setup_widgets (self): #rough

    #preview

    previewframe = ttk.Frame(self)
    previewframe.grid(row=0, column=0, columnspan=2, sticky=tk.EW, padx=10, pady=10)
    previewlabel = ttk.Label(previewframe, text=self.translate("label_preview"))
    previewlabel.pack(anchor=tk.W)
    preview = PreviewWidget(previewframe, width=320, height=160)
    preview.pack(fill=tk.X)

    #family

    familyframe = ttk.Frame(self)
    familyframe.grid(row=1, column=0, sticky=tk.NSEW, padx=10, pady=10)
    familylabel = ttk.Label(familyframe, text=self.translate("label_family"))
    familylabel.pack(anchor=tk.W)
    familyselector = FamilySelectorWidget(self.fontselector.family, familyframe)
    familyselector.pack(fill=tk.BOTH, expand=True)
    familyselector.add_onupdate(self._onupdate)

    #size

    sizeframe = ttk.Frame(self)
    sizeframe.grid(row=1, column=1, sticky=tk.NSEW, padx=10, pady=10)
    sizelabel = ttk.Label(sizeframe, text=self.translate("label_size"))
    sizelabel.pack(anchor=tk.W)
    sizeselector = SizeSelectorWidget(self.fontselector.size, sizeframe)
    sizeselector.pack(fill=tk.BOTH, expand=True)
    sizeselector.add_onupdate(self._onupdate)

    #buttons

    buttonframe = ttk.Frame(self)
    buttonframe.grid(row=2, column=0, columnspan=2, sticky=tk.NSEW, padx=10, pady=10)
    cancelbutton = ttk.Button(buttonframe, text=self.translate("label_calcel"), command=self.destroy)
    cancelbutton.pack(side=tk.RIGHT)
    okbutton = ttk.Button(buttonframe, text=self.translate("label_ok"), command=self._ok)
    okbutton.pack(side=tk.RIGHT)

    self.grid_rowconfigure(0, weight=0)
    self.grid_rowconfigure(1, weight=1)
    self.grid_columnconfigure(0, weight=1)
    self.grid_columnconfigure(1, weight=1)

    self.preview = preview
    self.familyselector = familyselector
    self.sizeselector = sizeselector

if __name__ == "__main__": #test
  root = tk.Tk()
  fontselector = FontSelector("メイリオ", 12, config={}, language={ "label_preview": "label_preview", "label_family": "label_family", "label_size": "label_size", "label_calcel": "label_calcel", "label_ok": "label_ok" })
  fontselector.open_window(root)
  root.mainloop()
  print(fontselector.family, fontselector.size) #test


import json
import threading
import time
import src.query_generator as generator
import common.src.basic_utils as utils
from common.src.mqtt_utils import MyMQTTClass
from common.conf import GLOBAL_VARS
from pprint import pprint
import random
import pickle
import common.src.utility as geo_utils
import os
import common.src.adjustable_RSU as ag

DEBUG = 0

class Broker_Mqtt(MyMQTTClass):
    def __init__(self, client_id=None, host="localhost", port=1883, keep_alive=60, clean_session=True, mongodb_c=None):
        super().__init__(client_id, host, port, keep_alive, clean_session)
        self._mongodb_c = mongodb_c
        self._tasks = []
        self._log_flag_once = False
        self._task_start_time = None
        self._timer_task = threading.Thread(target=self.get_unsent_tasks, args = ())
        self._timer_task.start()

        if not os.path.exists(os.path.join(os.getcwd(), 'data')):
            raise OSError("Must first download data, see README.md")
        data_dir = os.path.join(os.getcwd(), 'data')

        file_path = os.path.join(data_dir, '{}-{}-rsu_arr.pkl'.format(GLOBAL_VARS.X_AXIS, GLOBAL_VARS.Y_AXIS))
        with open(file_path, 'rb') as handle:
            self._rsu_arr = pickle.load(handle)

        file_path = os.path.join(data_dir, '{}-{}-G.pkl'.format(GLOBAL_VARS.X_AXIS, GLOBAL_VARS.Y_AXIS))
        with open(file_path, 'rb') as handle:
            self._nxg = pickle.load(handle)

    def mqtt_on_message(self, mqttc, obj, msg):
        self.parse_topic(msg)

    def start_unsent_tasks_thread(self):
        if not self._timer_task.is_alive():
            self._timer_task = threading.Thread(target=self.get_unsent_tasks, args = ())
            self._timer_task.start()

    def parse_topic(self, msg):
        t_arr = msg.topic.split("/")

        if msg.topic == GLOBAL_VARS.SIMULATED_SINGLE_QUERY_TO_BROKER:
            data = json.loads(utils.decode(msg.payload))
            print("Broker receives : {}".format(data))
            tasks = generator.get_single_task(self._mongodb_c, data['x'], data['y'], data['s'], data['d'], data['t'])
            print(tasks)
            print(type(tasks))

            self.generate_mongo_tasks_entry(tasks)

            start = utils.time_print(0)
            utils.print_log("Starting sub-task allocation.")
            for task in tasks:
                self.subtask_allocation(GLOBAL_VARS.NEIGHBOR_LEVEL, task)
            for task in tasks:
                self.assign_next_rsu(task)
            elapsed = utils.time_print(0) - start
            utils.print_log("Total allocation time: {} ms".format(elapsed))

            # HACK: Add sleep so I can get the allocation time data
            # time.sleep(5)

            self._tasks = tasks
            self._log_flag_once = False

            self._task_start_time = utils.time_print(0)
            # The placement here is purely for debugging
            self._collect_tasks = threading.Thread(target=self.compile_tasks_by_id, args = ())
            self._collect_tasks.start()

            self.send(GLOBAL_VARS.START_LOGGING, utils.encode("START"))

            pass

        if msg.topic == GLOBAL_VARS.SIMULATED_QUERY_TO_BROKER:
            data = json.loads(utils.decode(msg.payload))
            print("Broker receives : {}".format(data))

            tasks = generator.get_tasks(self._mongodb_c, data['x'], data['y'], data['number_of_queries'], sorted=True)

            self.generate_mongo_tasks_entry(tasks)

            start = utils.time_print(0)
            utils.print_log("Starting sub-task allocation.")
            for task in tasks:
                self.subtask_allocation(GLOBAL_VARS.NEIGHBOR_LEVEL, task)
            for task in tasks:
                self.assign_next_rsu(task)
            elapsed = utils.time_print(0) - start
            utils.print_log("Total allocation time: {} ms".format(elapsed))

            # # HACK: Add sleep so I can get the allocation time data
            # time.sleep(5)

            self._tasks = tasks
            self._log_flag_once = False

            self._task_start_time = utils.time_print(0)
            # The placement here is purely for debugging
            self._collect_tasks = threading.Thread(target=self.compile_tasks_by_id, args = ())
            self._collect_tasks.start()

            self.send(GLOBAL_VARS.START_LOGGING, utils.encode("START"))

        if msg.topic == GLOBAL_VARS.QUERY_TO_BROKER:
                print("Broker receives : {}".format(str(msg.payload)))
                self.generate_mongo_payload(msg.payload)

        if GLOBAL_VARS.RESPONSE_TO_BROKER in msg.topic:
            rsu = t_arr[-1]
            if rsu in list(GLOBAL_VARS.RSUS.values()):
                # update mongodb entry as Responded (2)
                data = json.loads(utils.decode(msg.payload))

                route = data['route']
                travel_time = data['travel_time']
                utils.print_log("worker-{} responded with :{}".format(rsu, data['_id']))
                self._mongodb_c.update_one("tasks", data['_id'], {"state": GLOBAL_VARS.TASK_STATES["RESPONDED"],
                                                              "processed_time": utils.time_print(int),
                                                              "travel_time": travel_time,
                                                              "route": route,
                                                              "next_node": route[-1]})
                if DEBUG == 1:
                    utils.print_log("Updated: {}".format(data['_id']))

        self.start_unsent_tasks_thread()

    # Place for adding new mongodb columns.
    # Unsent = 0, Sent = 1, Responded = 2, Task_done = 3
    def generate_mongo_tasks_entry(self, tasks):
        for task in tasks:
            print(task)
            data = task.get_json()
            data['inquiry_time'] = utils.time_print(int)
            data['allocation_time'] = None
            data['processed_time'] = None
            data['state'] = GLOBAL_VARS.TASK_STATES["UNSENT"]
            data['next_node'] = None
            data['route'] = None
            data['travel_time'] = None
            data['rsu_assigned_to'] = None
            data['retry_count'] = 0
            data['next_rsu'] = None
            t_id = data['_id']

            _DB = self._mongodb_c.get_db("admin")
            found = _DB["tasks"].count_documents({"_id": t_id})
            if found == 0:
                t_id = self._mongodb_c.insert("tasks", data)

    def generate_mongo_payload(self, message):
        print("generate_mongo_payload:", len(message))
        _m = utils.decode(message)
        _d = json.loads(_m)
        data = _d['data']
        data['inquiry_time'] = utils.time_print(int)
        data['allocation_time'] = None
        data['processed_time'] = None
        data['state'] = GLOBAL_VARS.TASK_STATES["UNSENT"]
        data['next_node'] = None
        data['route'] = None
        data['travel_time'] = None
        data['rsu_assigned_to'] = None
        data['retry_count'] = 0
        data['next_rsu'] = None
        t_id = data['_id']

        _DB = self._mongodb_c.get_db("admin")
        found = _DB["tasks"].count_documents({"_id": t_id})
        if found == 0:
            t_id = self._mongodb_c.insert("tasks", data)

    def remove_one_task(self, id):
        for i, task in enumerate(self._tasks):
            if task._id == id:
                del self._tasks[i]
                print("removed one ({})".format(id))
                break

    def remove_task(self, parsed_id):
        for i, task in enumerate(self._tasks):
            if task.parsed_id == parsed_id:
                del self._tasks[i]
                print("removed msny ({})".format(parsed_id))
                break

    def assign_next_rsu(self, subtask):
        # Get next sub-task step
        data = subtask.get_json()
        _id = data['_id']
        step = data['step']
        steps = data['steps']
        if step == steps:
            return
        next_step = str(int(step) + 1).zfill(3)
        parsed_id = data['parsed_id']
        res = self._mongodb_c._db.tasks.find_one({"parsed_id": parsed_id, "step": next_step})
        # Should always have a result if it is not the last step, if none, then it really is an error in the task generation
        next_rsu = res['rsu_assigned_to']
        self._mongodb_c._db.tasks.update_one({"_id": _id}, {"$set": {"next_rsu": next_rsu}})
        # utils.print_log("Set to: {}".format(next_rsu))

    # Decide which RSU to allocate to by sending status queries
    def subtask_allocation(self, nlevel, subtask):
        data = subtask.get_json()
        gridA = data['gridA']
        gridB = data['gridB']

        if isinstance(gridA, int):
            optimal_rsu = gridB
        else:
            optimal_rsu = gridA

        if DEBUG == 1:
            print("Checking for: {}".format(optimal_rsu))

        if nlevel == 0:
            self._mongodb_c._db.tasks.update_one({"_id": data['_id']}, {'$set': {'rsu_assigned_to': optimal_rsu, 'allocation_time': utils.time_print(int)}})
            return

        if nlevel > 0:
            r = geo_utils.get_rsu_by_grid_id(self._rsu_arr, optimal_rsu)
            nn = geo_utils.get_neighbors_level(self._rsu_arr, r.get_idx(), nlevel)

            nn.insert(0, r.get_idx())
            found = False
            candidate_rsus = []

            # Arranges the neighbors by distance from the most optimal grid in question
            # DEBUG: This will cause some additional delays
            nn = geo_utils.sort_idx_by_distance(GLOBAL_VARS.X_AXIS, GLOBAL_VARS.Y_AXIS, r.get_idx(), nn)
            nn.sort(key=lambda x: x[1])
            nn = [n[0] for n in nn]

            for n in nn:
                rsu = self._rsu_arr[n]
                candidate_rsus.append(rsu)

                res, gid = rsu.add_task(self._nxg, self._rsu_arr, subtask, use_sub_grids=GLOBAL_VARS.USE_SUB_GRIDS)
                if res:
                    found = True
                    self._mongodb_c._db.tasks.update_one({"_id": data['_id']}, {'$set': {'rsu_assigned_to': gid, 'allocation_time': utils.time_print(int)}})
                    # utils.print_log("Assigned to: {}".format(gid))
                    break
                '''
                If not ok, move to the next one (keep which has lowest number)
                '''
            # Get RSU with least number of queue
            if not found:
                if DEBUG == 1:
                    print("Not found by looking, must force...")
                # NOTE: Just shuffling so there is a chance that subtasks will be assigned to different RSUs and not just in the order they come in (if they are both tied for minimum queue lengths)
                # IDEA: Check if this has an effect
                # Right now as the last resort, it appends to the RSU with least queue length
                # If i don't randomize this, then it will assign to the least distance, which is just the most optimal one (may cause delay)
                random.shuffle(candidate_rsus)
                candidate_rsus = sorted(candidate_rsus, key=lambda rsu: len(rsu.queue), reverse=False)

                if DEBUG == 1:
                    [print(r) for r in candidate_rsus]
                    if candidate_rsus[0]._sub_grids:
                        [print(r) for r in candidate_rsus[0]._sub_grids]
                        print("\n")

                _, gid = candidate_rsus[0].add_task_forced(subtask, use_sub_grids=GLOBAL_VARS.USE_SUB_GRIDS)
                # utils.print_log("Forced to: {}".format(gid))
                self._mongodb_c._db.tasks.update_one({"_id": data['_id']}, {'$set': {'rsu_assigned_to': gid, 'allocation_time': utils.time_print(int)}})

            return

    def get_unsent_tasks(self):
        mongo_tasks = list(self._mongodb_c.find("tasks", {"state": {"$lt": GLOBAL_VARS.TASK_STATES["SENT"]}}))
        mongo_tasks = sorted(mongo_tasks, key=lambda k: int(k['step']))
        time.sleep(0.2)

        while len(mongo_tasks) > 0:
            for task in mongo_tasks:
                if task['rsu_assigned_to'] is None:
                    continue

                t_id = task['_id']
                rsu = task['rsu_assigned_to']

                topic = utils.add_destination(GLOBAL_VARS.BROKER_TO_RSU, rsu)
                payload = json.dumps(task)

                self._mongodb_c.update_one("tasks", t_id, {"state": GLOBAL_VARS.TASK_STATES["SENT"]})
                self._mongodb_c._db.tasks.update({'_id': t_id}, {'$inc': {'retry_count': 1}})

                if DEBUG == 1:
                    utils.print_log("Broker sending task {} to topic: rsu-{}".format(t_id, utils.get_worker_from_topic(topic)))
                self.send(topic, utils.encode(payload))

            mongo_tasks = list(self._mongodb_c.find("tasks", {"state": {"$lt": GLOBAL_VARS.TASK_STATES["SENT"]}}))

    def compile_tasks_by_id(self):
        while True:
            if utils.time_print(int) - self._task_start_time >= GLOBAL_VARS.TIMEOUT:
                res = self._mongodb_c._db.tasks.find({"state": {"$eq": GLOBAL_VARS.TASK_STATES["SENT"]}}).sort([("_id", 1)])

                timedout = []

                for task in res:
                    parsed_id = task['parsed_id']
                    if parsed_id not in timedout:
                        timedout.append(parsed_id)
                    self._mongodb_c._db.tasks.update_many({"parsed_id": parsed_id}, {'$set': {'state': GLOBAL_VARS.TASK_STATES['TIMEOUT']}})
                    self._mongodb_c._db.queries.update_one({"_id": parsed_id}, {'$set': {'final_route': "ERROR",
                                                                                'total_travel_time': "ERROR",
                                                                                'total_processed_time': "ERROR"}})

                [utils.print_log("{} timedout.".format(t)) for t in timedout]
                self.send(GLOBAL_VARS.STOP_LOGGING, utils.encode("STOP"))
                self._mongodb_c.save_collection_to_json('queries')
                self._mongodb_c.save_collection_to_json('tasks')
                break

            count = self._mongodb_c._db.queries.count_documents({"final_route": None})
            if count == 0:
                continue

            res = self._mongodb_c._db.queries.find({"final_route": None})
            for r in res:
                parsed_id = r['_id']
                count = self._mongodb_c._db.tasks.count_documents({"parsed_id": parsed_id, "state": GLOBAL_VARS.TASK_STATES["RESPONDED"]})
                temps = self._mongodb_c._db.tasks.find_one({"parsed_id": parsed_id, "state": GLOBAL_VARS.TASK_STATES["RESPONDED"]})

                if not temps:
                    continue

                task_steps = int(temps['steps']) + 1
                if task_steps == count:
                    tasks = self._mongodb_c._db.tasks.find({"parsed_id": parsed_id, "state": GLOBAL_VARS.TASK_STATES["RESPONDED"]})
                    route = []
                    total_travel_time = 0
                    utils.print_log("Collecting {}".format(parsed_id))
                    for task in tasks:
                        route.extend(task['route'])
                        last_processing_time = task['processed_time']
                        total_travel_time = total_travel_time + task['travel_time']

                    if route and total_travel_time > 0:
                        self._mongodb_c._db.queries.update_one({'_id': parsed_id},
                                                                {'$set': {'final_route': utils.f7(route),
                                                                        'total_processed_time':last_processing_time,
                                                                        'total_travel_time': total_travel_time}})

                        self._mongodb_c._db.tasks.update_many({"parsed_id": parsed_id, "state": GLOBAL_VARS.TASK_STATES["RESPONDED"]},
                                                              {'$set': {'state': GLOBAL_VARS.TASK_STATES['COLLECTED']}})


"""
    @author: Suraj Kumar Giri
    @init-date: 19th Jan 2023
    @last-modified: 19th April 2023

    @description:
        * Module to handle all the time related operations involving in the web app.

    @functions:
        *
"""
import datetime
from time import time

def readableDateTime(dateTime: datetime.datetime = datetime.datetime.now()) -> str:
    """
        Description:
            - Function to convert datetime object to readable format.
            - Readable format is like 19 Jan 2023 12:30:00 PM

        Args:
            * dateTime (datetime.datetime, optional):
                - Datetime object to be converted to readable format.
                - Default to current datetime.

        Returns:
            * str:
                - Readable datetime string.
                - Format is like 19 Jan 2023 12:30:00 PM
    """
    return dateTime.strftime("%d %b %Y %I:%M:%S %p")

def readableStringDateTime(dateTime: str) -> str:
    """
        Description:
            - Function to convert string format of datetime to readable format.
            - Readable format is like 19 Jan 2023 12:30:00 PM

        Args:
            * dateTime (str):
                - Datetime string to be converted in to readable format.
                - Accepted format is "2023-01-09 13:55:30"

        Returns:
            * str:
                - Readable datetime string.
                - Format is like 19 Jan 2023 12:30:00 PM
    """
    # Below is the format of MySQL datetime string (But by fetching DATETIME data using mysql.connector, it will convert it into python datetime.datetime object similarly as done by this function.)
    # 2023-01-09 13:55:30

    # fetching each element from the datetime string
    dateTimeDict = {
        'year': int(dateTime[:4]),
        'month': int(dateTime[5:7]),
        'day': int(dateTime[8:10]),
        'hour': int(dateTime[11:13]),
        'minute': int(dateTime[14:16]),
        'second': int(dateTime[17:])
    }
    return readableDateTime(datetime.datetime(**dateTimeDict))

def epochToMySql(epochSeconds: float = time()) -> str:
    """
        Description:
            - Function to convert epoch seconds to MySQL datetime string.

        Args:
            * epochSeconds (float, optional):
                - Epoch seconds which needs to be converted to MySQL datetime string.
                - Defaults to time(). Means current epoch seconds.

        Returns:
            * str:
                - MySQL datetime string.
    """
    return datetime.datetime.fromtimestamp(epochSeconds).strftime("%Y-%m-%d %H:%M:%S")

if __name__ == '__main__':
    print(readableDateTime())
    print(readableStringDateTime('2023-01-09 13:55:30'))
    print(epochToMySql())


"""inital

Revision ID: 1bd064d75748
Revises:
Create Date: 2023-01-13 22:16:34.102416

"""
import sqlalchemy as sa

from alembic import op

# revision identifiers, used by Alembic.
revision = "1bd064d75748"
down_revision = None
branch_labels = None
depends_on = None

def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "user",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("username", sa.String(length=50), nullable=True),
        sa.Column("email", sa.String(length=150), nullable=True),
        sa.Column("password", sa.String(length=250), nullable=True),
        sa.Column("date_of_birth", sa.DateTime(), nullable=True),
        sa.Column("is_admin", sa.Boolean(), nullable=True),
        sa.Column("is_staff", sa.Boolean(), nullable=True),
        sa.Column("is_superuser", sa.Boolean(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_user_date_of_birth"), "user", ["date_of_birth"], unique=False
    )
    op.create_index(op.f("ix_user_email"), "user", ["email"], unique=True)
    op.create_index(op.f("ix_user_id"), "user", ["id"], unique=False)
    op.create_index(op.f("ix_user_username"), "user", ["username"], unique=True)
    # ### end Alembic commands ###

def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_user_username"), table_name="user")
    op.drop_index(op.f("ix_user_id"), table_name="user")
    op.drop_index(op.f("ix_user_email"), table_name="user")
    op.drop_index(op.f("ix_user_date_of_birth"), table_name="user")
    op.drop_table("user")
    # ### end Alembic commands ###


import json
from unittest import mock

from attr import define

from .utils import MockedRedis

@define
class MockAsyncResult:
    task_id: str
    state: str

def test_status(client):
    response = client.get("/api/v1/status")

    assert response.status_code == 200
    assert response.json() == {"status": "OK"}

def test_task_state(client):
    """test getting state of given celery task_id"""
    with mock.patch("ubi_manifest.app.api.app.AsyncResult") as task_mock:
        task_id = "some-task-id"
        task_mock.return_value = MockAsyncResult(task_id=task_id, state="PENDING")

        response = client.get(f"/api/v1/task/{task_id}")

        # 200 status code is expected
        assert response.status_code == 200
        json_data = response.json()
        # task_id and state are properly set in response
        assert json_data["task_id"] == task_id
        assert json_data["state"] == "PENDING"

def test_task_state_not_found(client):
    """test getting state of given celery task when task is not found"""
    with mock.patch("ubi_manifest.app.api.app.AsyncResult") as task_mock:
        task_id = "some-task-id"
        task_mock.return_value = None

        response = client.get(f"/api/v1/task/{task_id}")
        # 404 is expected status code
        assert response.status_code == 404
        json_data = response.json()
        # proper detail is set in the response
        assert json_data["detail"] == f"Task {task_id} not found"

def test_manifest_get(client):
    """test getting depsolved content for repository"""
    depsolver_result_item = [
        {
            "src_repo_id": "source-foo-bar-repo-1",
            "unit_type": "RpmUnit",
            "unit_attr": "filename",
            "value": "some-filename.rpm",
        },
        {
            "src_repo_id": "source-foo-bar-repo-2",
            "unit_type": "RpmUnit",
            "unit_attr": "filename",
            "value": "some-other-filename.rpm",
        },
    ]

    depsolver_result_item_json_str = json.dumps(depsolver_result_item)

    redis_data = {"ubi_repo_id": depsolver_result_item_json_str}

    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data=redis_data)
        response = client.get(f"/api/v1/manifest/ubi_repo_id")

        # expected status code in 200
        assert response.status_code == 200
        json_data = response.json()
        # repo_id is set to the one we requested
        assert json_data["repo_id"] == "ubi_repo_id"

        content = sorted(json_data["content"], key=lambda x: x["value"])
        # there are two units in the content
        assert len(content) == 2
        content_item = content[0]
        # details of unit are set properly
        assert content_item["src_repo_id"] == "source-foo-bar-repo-1"
        assert content_item["unit_type"] == "RpmUnit"
        assert content_item["unit_attr"] == "filename"
        assert content_item["value"] == "some-filename.rpm"

        content_item = content[1]
        # details of unit are set properly
        assert content_item["src_repo_id"] == "source-foo-bar-repo-2"
        assert content_item["unit_type"] == "RpmUnit"
        assert content_item["unit_attr"] == "filename"
        assert content_item["value"] == "some-other-filename.rpm"

def test_manifest_get_empty(client):
    """test getting empty manifest for repository"""
    depsolver_result_item = []
    depsolver_result_item_json_str = json.dumps(depsolver_result_item)

    redis_data = {"ubi_repo_id": depsolver_result_item_json_str}

    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data=redis_data)
        response = client.get(f"/api/v1/manifest/ubi_repo_id")

        # expected status code in 200
        assert response.status_code == 200
        json_data = response.json()
        # repo_id is set to the one we requested
        assert json_data["repo_id"] == "ubi_repo_id"

        content = sorted(json_data["content"], key=lambda x: x["value"])
        # the content is empty
        assert len(content) == 0

def test_manifest_get_not_found(client):
    """test getting depsolved content when the cotent is not available for given repo_id"""
    with mock.patch("ubi_manifest.app.api.redis.from_url") as mock_redis_from_url:
        mock_redis_from_url.return_value = MockedRedis(data={})
        response = client.get("/api/v1/manifest/ubi_repo_id")
        # expected status code is 404
        assert response.status_code == 404
        json_data = response.json()
        # response detail is properly set
        assert json_data["detail"] == "Content for ubi_repo_id not found"

def test_manifest_post(client):
    """test request for depsolving for given repo ids"""
    with mock.patch("celery.app.task.Task.apply_async") as mocked_apply_async:
        mocked_apply_async.return_value = MockAsyncResult(
            task_id="foo-bar-id", state="PENDING"
        )

        # will request depsolving for 2 repos
        # 'repo_1' is set in the default config, and it will be depsolving
        # 'repo_not_allowed' will be skipped - not present in the config
        response = client.post(
            "/api/v1/manifest", json={"repo_ids": ["repo_1", "repo_not_allowed"]}
        )

        # depsolve task is run with 2 repos in args:
        # 'repo_1' was requested via API
        # 'repo_2' is taken from repo_group that is defined in the config
        # it's required to run depsolving for whole repo_group, otherwise we
        # won't be able to find some deps that are not in the 'repo_1' but are
        # present in 'repo_2'
        # 'repo_not_allowed' is skipped completely
        # the content config url is also determined from default conf and passed as arg
        mocked_apply_async.assert_called_once_with(
            args=[["repo_1", "repo_2"], "url_to_config_repository"]
        )

        # expected status code is 200
        assert response.status_code == 201
        json_data = response.json()
        # one task is expected to be spawned therefore there is only one item
        # in the response with proper task_id and state set
        assert len(json_data) == 1
        item = json_data[0]
        assert item["task_id"] == "foo-bar-id"
        assert item["state"] == "PENDING"

def test_manifest_post_not_allowed(client):
    """test request for depsolving for given repo ids, but none of the is allowed by config"""
    with mock.patch("celery.app.task.Task.apply_async") as mocked_apply_async:
        # none of repos in request are allowed for depsolving by config
        response = client.post(
            "/api/v1/manifest",
            json={"repo_ids": ["repo_not_allowed_1", "repo_not_allowed_2"]},
        )
        # we never call apply_async on depsolve_task
        mocked_apply_async.assert_not_called()
        # expected status code is 404
        assert response.status_code == 404
        # there is enough detail info in the response
        json_data = response.json()
        assert (
            json_data["detail"]
            == "None of ['repo_not_allowed_1', 'repo_not_allowed_2'] are allowed for depsolving."
        )


class Node:
    def __init__(self, val, prev=None, next=None, child=None):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child

# Creating the nodes
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node6 = Node(6)
node7 = Node(7)
node8 = Node(8)
node9 = Node(9)
node10 = Node(10)

# Building the linked list
node1.next = node2
node2.prev = node1
node2.next = node3
node3.prev = node2
node3.next = node4
node4.prev = node3
node4.next = node5
node5.prev = node4

# Connecting child nodes
node3.child = node6
node6.next = node7
node7.prev = node6
node7.next = node8
node8.prev = node7

node8.child = node9
node9.next = node10
node10.prev = node9

class solution:
    def flatten(self, head):
        start = head
        stack = []
        while head:
            if head.child:
                if head.next:
                    stack.append(head.next)
                head.next = head.child
                head.next.prev = head
                head.child = None
            if head.next == None and len(stack) != 0:
                head.next = stack.pop()
                head.next.prev = head
            head = head.next

        return start

x = solution()
node = x.flatten(node1)

while node:
    print(node.val, end=" ")
    node = node.next


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 21 13:56:10 2018

@author: valeria
"""
import numpy as np
#import matplotlib
#matplotlib.use('Agg')
from matplotlib import pyplot as plt
#import datetime
#from scipy import stats
import sys
sys.path.append('/home/valeria/NIERSC/Scripts/IceVolume/PIOMAS_test/functions/')
import Vi_functions as V

INDIR = '/home/valeria/NIERSC/Projects/Bashmachnikov/data/PIOMAS/'
OUTDIR = '/home/valeria/NIERSC/Scripts/IceVolume/PIOMAS_test/Comparison_obs/'
months_winter = np.array([10,11,12,1,2,3,4])
months_dc = np.array([1,2,3,4])

##PIOMAS
fname_PIOMAS = INDIR+'PIOMAS_vol_export.txt'
outname_PIOMAS = OUTDIR+'txt/'+'Monthly_mean_ViFlix_std_PIOMAS_1979-2016_OctApr.txt'
Vif_PIOMAS, dates_PIOMAS = V.read_PIOMAS_Vi_flux(fname_PIOMAS)
years_PIOMAS = np.arange(1978,2017)
##winter
monthly_Vif_PIOMAS, mean_monthly_Vif_PIOMAS, std_monthly_Vif_PIOMAS = V.calculate_monthly_stats_Vif(years_PIOMAS, months_winter, Vif_PIOMAS, dates_PIOMAS, outname_PIOMAS)
###dc
#outname_PIOMAS = 'Monthly_mean_ViFlix_std_PIOMAS_1979-2016_JanApr.txt'
#monthly_Vif_PIOMAS_dc, mean_monthly_Vif_PIOMAS_dc, std_monthly_Vif_PIOMAS_dc = calculate_monthly_stats_Vif(years_PIOMAS, months_dc, Vif_PIOMAS, dates_PIOMAS, outname_PIOMAS)

##Cryosat
fname_Cryosat = INDIR+'CRYOSAT_vol_export.txt'
outname_Cr = OUTDIR+'txt/'+'Monthly_mean_ViFlix_std_Cryosat_2010-2017_OctApr.txt'
Vif_Cr, dates_Cr = V.read_Cryosat_Vi_flux(fname_Cryosat)
years_Cr = np.arange(2010,2018,1)
##winter
monthly_Vif_Cr, mean_monthly_Vif_Cr, std_monthly_Vif_Cr = V.calculate_monthly_stats_Vif(years_Cr, months_winter, Vif_Cr, dates_Cr, outname_Cr)
###dc
#outname_Cr = 'Monthly_mean_ViFlix_std_Cryosat_2010-2017_JanApr.txt'
#Vif_period_Cr_dc, dates_period_Cr_dc, mean_monthly_Vif_Cr_dc, std_monthly_Vif_Cr_dc = calculate_monthly_stats_Vif(years_Cr, months_dc, Vif_Cr, dates_Cr, outname_Cr)

#Kwok_2004
fname_k04=INDIR+'Kwok_vol_export_2004.txt'
outname_k04 =OUTDIR+'txt/'+ 'Monthly_mean_ViFlix_std_Kwok_1991-1999_OctApr.txt'
Vif_k04, dates_k04 = V.read_Kwk_Sprn_Vi_flux(fname_k04)
years_k04 = np.arange(1991,2000,1)
##winter
monthly_Vif_k04, mean_monthly_Vif_k04, std_monthly_Vif_k04 = V.calculate_monthly_stats_Vif(years_k04, months_winter, Vif_k04, dates_k04, outname_k04)

##
##import Spreen_2009 volume flux
fname_s09=INDIR+'Spreen_vol_export_2009.txt'
outname_s09 = OUTDIR+'txt/'+'Monthly_mean_ViFlix_std_Spreen_2003-2008_OctApr.txt'
Vif_s09, dates_s09 = V.read_Kwk_Sprn_Vi_flux(fname_s09)
years_s09 = np.arange(2003,2009,1)
##winter
monthly_Vif_s09, mean_monthly_Vif_s09, std_monthly_Vif_s09 = V.calculate_monthly_stats_Vif(years_s09, months_winter, Vif_s09, dates_s09, outname_s09)

#PLOTTING
plt.figure()
#PIOMAS
plt.plot(mean_monthly_Vif_PIOMAS,  c = 'royalblue', label = 'PIOMAS')
yerr=std_monthly_Vif_PIOMAS
plt.errorbar(range(len(yerr)),mean_monthly_Vif_PIOMAS,yerr,lw=0, ecolor='royalblue', elinewidth=1, capsize=5)

plt.plot(mean_monthly_Vif_Cr, c = 'darkorange', label = 'Cryosat2/SMOS')
yerr=std_monthly_Vif_Cr
plt.errorbar(range(len(yerr)),mean_monthly_Vif_Cr,yerr,lw=0, ecolor='darkorange', elinewidth=1, capsize=5)

plt.plot(mean_monthly_Vif_k04, c = 'plum',  label = 'Kwok2004')
yerr=std_monthly_Vif_k04
plt.errorbar(range(len(yerr)),mean_monthly_Vif_k04,yerr,lw=0, ecolor='plum', elinewidth=1, capsize=5)

plt.plot(mean_monthly_Vif_s09, c = 'mediumspringgreen',  label = 'Spreen2009')
yerr=std_monthly_Vif_s09
plt.errorbar(range(len(yerr)),mean_monthly_Vif_s09,yerr,lw=0, ecolor='mediumspringgreen', elinewidth=1, capsize=5)

plt.xticks(np.arange(len(months_winter)),[str(m) for m in months_winter])
plt.xlabel('Months')
plt.ylabel('km^3')
plt.title('Mean monthly sea ice volume flux')
plt.grid()
plt.tight_layout()
plt.legend()
plt.show()
plt.savefig(OUTDIR+'figs/'+'PIOMAS_Viflux_comparison_cycle.pdf')
#


#!/usr/bin/env python

import sys
from I3Tray import *
from icecube import icetray, dataclasses, dataio, phys_services, sim_services, tableio, hdfwriter

tray = I3Tray()

tray.AddModule("I3Reader",
               "reader",
               FilenameList=sys.argv[2:])

tray.AddModule("I3NullSplitter", 'nullsplit')

hdftable = hdfwriter.I3HDFTableService(sys.argv[1] + ".h5")

tray.AddModule(tableio.I3TableWriter, "writerHDF",
        tableservice = hdftable,
        SubEventStreams = ['nullsplit'],
        keys = ["I3MCTree"])

tray.AddModule("TrashCan","trash")

tray.Execute()
tray.Finish()


import random

def iter_random():
    """
    Wraps random number generator in an infinite iterable, allowing random
    floats to be retrieved with calls to next()
    """
    while 1:
        yield random.random()

def cumulative_emperical(emp):
    sum_prob = 0.0
    emp_cum_prob = []
    for val, prob in emp:
        sum_prob += prob
        emp_cum_prob.append((val, sum_prob))
    return emp_cum_prob

def emperical_rng(emp):
    while 1:
        rand_float = random.random()
        for val, prob in emp:
            if rand_float < prob:
                yield val
                break

def cumulative_emperical_rng(emp):
    return emperical_rng((cumulative_emperical(emp)))


import cbpro
import datetime
import ccxt
import logging
from pprint import pprint
import time
import datetime
import pandas as pd
from sqlalchemy import create_engine
from credentials_db import user, passw, host, port, database

user = user
passw = passw
host = host
port = port
database = database

mydb = create_engine('mysql+pymysql://' + user + ':' + passw + '@' + host + ':' + str(port) + '/' + database, echo=False)

import gdax
import datetime

epoch_now = datetime.datetime.now().timestamp()*1000

def test2():
    publicClient = gdax.PublicClient()
    actual2 = datetime.datetime.now()
    client = ccxt.gdax
    print("actual2 ", actual2)
    actual = epoch_now
    ten_dias = datetime.timedelta(minutes=14400)
    print(ten_dias)
    print("actual", actual)
    flag = True
    now = '2018-11-18 00:00:00.000000'
    date_time_now = datetime.datetime.strptime(now, '%Y-%m-%d %H:%M:%S.%f')
    print("now ", now)
    date_time_str = '2018-11-08 00:00:00.000000'
    date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')
    print("date_time_obj", date_time_obj)
    print("isoformat()", date_time_obj.isoformat())
    epoch_next_date_start = 0
    while epoch_next_date_start < actual and flag is True:
        hist = publicClient.get_product_historic_rates(
                    "BTC-EUR",
                    start=date_time_obj.isoformat(),
                    end=date_time_now.isoformat(),
                    granularity=3600)
        print(hist)
        if actual2.isoformat() <= client.iso8601(hist[-1][0]):
            print("en el if ", hist[-1][0])
            flag = False
        else:
            date_time_obj = date_time_obj + ten_dias
            print(date_time_obj)
            date_time_now = date_time_now + ten_dias
            print(date_time_now)
            print(date_time_now.isoformat())
            print(hist[-1][0])
            print(client.iso8601(hist[-1][0]))
            time.sleep(2)

def get_data_by_market_gdax(exchange, market_name):
    market_name = market_name.split(sep='/')
    market_name = '-'.join(market_name)
    publicClient = gdax.PublicClient()
    client = ccxt.gdax
    start_point_time = '2019-04-08T00:00:00'
    actual = epoch_now
    listI = []
    start_point_time_epock = client.parse8601(start_point_time)
    end_point_time = start_point_time_epock + 864000000
    try:
        next_date_start_t = client.iso8601(start_point_time_epock)
        end_point_time_ = client.iso8601(end_point_time)
        epoch_next_date_start = 0
        flag = True
        while epoch_next_date_start < actual and flag is True:
            time.sleep(1)
            hist = publicClient.get_product_historic_rates(
                market_name,
                start=next_date_start_t,
                end=end_point_time_,
                granularity=3600)
            listI = listI + hist
            next_date_start_t = end_point_time_
            end_point_time_ = client.parse8601(end_point_time_)
            end_point_time_ = end_point_time_ + 864000000
            epoch_next_date_start = end_point_time_
            if end_point_time_ >= actual:
                flag = False
            else:
                end_point_time_ = client.iso8601(end_point_time_)
        df = pd.DataFrame(listI, columns=["timestamp", "open", "high", "low", "close", "volume"])
        df.to_sql(name='{}_{}'.format(exchange, market_name), con=mydb, if_exists='replace', index=False,
                  index_label='id')
        print(listI)
    except Exception as error:

        # Create a custom logger
        logger = logging.getLogger(__name__)

        # Create handlers
        f_handler = logging.FileHandler('gdax_exchanges.log')

        # Create formatters and add it to handlers
        f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        f_handler.setFormatter(f_format)

        # Add handlers to the logger
        logger.addHandler(f_handler)
        logger.error('EXCHANGE: %s ERROR %s', exchange, error)
        logging.error('COIN: %s', market_name)

        pass

#get_data_by_market_gdax(exchange)

#test2()

def test2():
    product = "{}-{}".format("BTC", "EUR")
    publicClient = gdax.PublicClient()
    hist = publicClient.get_product_historic_rates(
                product,
                granularity=3600)
    pprint(hist)

#test2()

"""client = ccxt.bitmex
epoch_now = datetime.datetime.now().timestamp() * 1000
start_point_time = '2000-11-08T00:00:00'
actual = epoch_now
print(actual)
start_point_time_ = client.parse8601(start_point_time)
print(start_point_time_)
next_date_start = start_point_time_
next_date_start = client.iso8601(start_point_time_)
response = ccs.poloniex.public.returnChartData("BTC_LTC", start=960412893000, end=1559942493, period=1800)
print(response)"""

# coinbasepro equals gdax

"""public_client = cbpro.PublicClient()
epoch_now = datetime.datetime.now().timestamp()*1000
client = ccxt.coinbase

actual = epoch_now
actual = str(actual)
print(type(actual))
print(actual)
start_point_time = '2015-11-08T00:00:00'
start_point_time_ = client.parse8601(start_point_time)
start_point_time_ = str(start_point_time_)
print(type(start_point_time_))
print(start_point_time_)
print(public_client.get_products())

v = public_client.get_product_historic_rates('ETH-USD')
print("v", v)
# To include other parameters, see function docstring:
v1 = public_client.get_product_historic_rates('ETH-USD', start_point_time_, actual, 300)
print("v1", v1)"""


# A very simple numerical implementation of the Black-Scholes Model

# dS = \mu*s*dt + \sigma*S*dW

import numpy as np
import matplotlib.pyplot as plt

# time
T = 2

# start price
S0 = 20
dt = 0.01
N = round(T/dt)
t = np.linspace(0, T, N)

def run_samples(runs=20,mu=0.09,sigma=0.05):

    for i in range(runs):
        W = np.random.standard_normal(size=N)
        W = np.cumsum(W) * np.sqrt(dt)  # standard brownian motion
        X = (mu - 0.5 * sigma ** 2) * t + sigma * W
        S = S0 * np.exp(X)              # geometric brownian motion
        plt.plot(t, S)
        plt.title('Price development with mu = %s and sigma = %s' % (str(mu),str(sigma)))

    plt.show()


class ListNode:
    def __init__(self, val = 0, next = None):
        self.val = val
        self.next = next

class Solution:
    def isPalindrome(self, head) :
        if head is None:
            return True
        first_half_end = self.find_median(head)
        second_half_start = self.reverse(first_half_end.next)
        start = head
        end = second_half_start
        result = True
        while result and end is not None:
            if start.val != end.val:
                result = False
            start = start.next
            end = end.next
        first_half_end.next = self.reverse(second_half_start)
        return result

    def find_median(self, head):
        fast = head
        slow = head
        while fast.next is not None and fast.next.next is not None:
            fast = fast.next.next
            slow = slow.next
        return slow

    def reverse(self, head):
        prevnode = None
        while head is not None:
            nextnode = head.next
            head.next = prevnode
            prevnode =head
            head = nextnode
        return prevnode

head = Listnode


"""
References:
    https://adventofcode.com/2015/day/10
"""

from beartype import beartype

@beartype
def look_and_say(sequence: str, turns_left: int) -> int:
    from itertools import groupby

    return (
        look_and_say(
            "".join(f"{len([*group])}{key}" for key, group in groupby(sequence)),
            turns_left - 1,
        )
        if turns_left
        else len(sequence)
    )

@beartype
def part_a(data: str) -> int:
    return look_and_say(data, 40)

@beartype
def part_b(data: str) -> int:
    return look_and_say(data, 50)

def main():
    from aocd import get, get_data

    from advent_of_code import submitter

    day: int
    year: int
    day, year = get.get_day_and_year()
    data: str = get_data(day=day, year=year)

    submitter(
        day=day, year=year, data=data, part_a_function=part_a, part_b_function=part_b
    )

if __name__ == "__main__":
    main()


import pandas as pd
from sqlalchemy import create_engine
import certifi
import ssl
import time
import geopy.geocoders
from geopy.geocoders import Nominatim
ctx = ssl.create_default_context(cafile=certifi.where())
geopy.geocoders.options.default_ssl_context = ctx
pd.options.mode.chained_assignment = None  # default='warn'

engine = create_engine('sqlite:///icono_MHL.db')
df = pd.read_sql("select * from icono_MHL_filtered where (GeoNoRue is not null or GeoRue is not null)and ImageUrl is not null", engine)

locator = geopy.Nominatim(user_agent="myGeocoder")
location = locator.geocode("Champ de Mars, Paris, France")

for index, row in df.iterrows():
    Rue = row['GeoRue']
    if Rue == None:
        Rue = ""
    NoRue = row['GeoNoRue']
    if NoRue == None:
        NoRue = ""
    loc = row['GeoLocalite']
    if loc == None:
        loc = ""
    pays = row['GeoPays']
    if pays == None:
        pays = ""
    NPA = row['GeoNPA']
    if NPA == None:
        pays = ""
    location = locator.geocode(Rue + " " + NoRue + " " + loc + " " + pays)
    if location is not None:
        df.Latitude[index] = location.latitude
        df.Longitude[index] = location.longitude
        print(f'{index}/15950\n')
        # time.sleep(0.3)
    else:
        print("error")

df.to_sql('icono_MHL_all_latlong', engine)
print(df)


"""
Testing for the base module (sklearn.ensemble.base).
"""

# Authors: Gilles Louppe
# License: BSD 3 clause

from collections import OrderedDict

import numpy as np

from sklearn.datasets import load_iris
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble._base import _set_random_states
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import Perceptron
from sklearn.pipeline import Pipeline

def test_base():
    # Check BaseEnsemble methods.
    ensemble = BaggingClassifier(
        estimator=Perceptron(random_state=None), n_estimators=3
    )

    iris = load_iris()
    ensemble.fit(iris.data, iris.target)
    ensemble.estimators_ = []  # empty the list and create estimators manually

    ensemble._make_estimator()
    random_state = np.random.RandomState(3)
    ensemble._make_estimator(random_state=random_state)
    ensemble._make_estimator(random_state=random_state)
    ensemble._make_estimator(append=False)

    assert 3 == len(ensemble)
    assert 3 == len(ensemble.estimators_)

    assert isinstance(ensemble[0], Perceptron)
    assert ensemble[0].random_state is None
    assert isinstance(ensemble[1].random_state, int)
    assert isinstance(ensemble[2].random_state, int)
    assert ensemble[1].random_state != ensemble[2].random_state

    np_int_ensemble = BaggingClassifier(
        estimator=Perceptron(), n_estimators=np.int32(3)
    )
    np_int_ensemble.fit(iris.data, iris.target)

def test_set_random_states():
    # Linear Discriminant Analysis doesn't have random state: smoke test
    _set_random_states(LinearDiscriminantAnalysis(), random_state=17)

    clf1 = Perceptron(random_state=None)
    assert clf1.random_state is None
    # check random_state is None still sets
    _set_random_states(clf1, None)
    assert isinstance(clf1.random_state, int)

    # check random_state fixes results in consistent initialisation
    _set_random_states(clf1, 3)
    assert isinstance(clf1.random_state, int)
    clf2 = Perceptron(random_state=None)
    _set_random_states(clf2, 3)
    assert clf1.random_state == clf2.random_state

    # nested random_state

    def make_steps():
        return [
            ("sel", SelectFromModel(Perceptron(random_state=None))),
            ("clf", Perceptron(random_state=None)),
        ]

    est1 = Pipeline(make_steps())
    _set_random_states(est1, 3)
    assert isinstance(est1.steps[0][1].estimator.random_state, int)
    assert isinstance(est1.steps[1][1].random_state, int)
    assert (
        est1.get_params()["sel__estimator__random_state"]
        != est1.get_params()["clf__random_state"]
    )

    # ensure multiple random_state parameters are invariant to get_params()
    # iteration order

    class AlphaParamPipeline(Pipeline):
        def get_params(self, *args, **kwargs):
            params = Pipeline.get_params(self, *args, **kwargs).items()
            return OrderedDict(sorted(params))

    class RevParamPipeline(Pipeline):
        def get_params(self, *args, **kwargs):
            params = Pipeline.get_params(self, *args, **kwargs).items()
            return OrderedDict(sorted(params, reverse=True))

    for cls in [AlphaParamPipeline, RevParamPipeline]:
        est2 = cls(make_steps())
        _set_random_states(est2, 3)
        assert (
            est1.get_params()["sel__estimator__random_state"]
            == est2.get_params()["sel__estimator__random_state"]
        )
        assert (
            est1.get_params()["clf__random_state"]
            == est2.get_params()["clf__random_state"]
        )


from __future__ import division
from twisted.protocols import amp

MMOSS_PROTOCOL = 12171

REQUEST_FULLUPDATE = "r_fu"
REQUEST_STATSUPDATE = "r_su"
EVENT_QUIT       = "e_qu"

class ClientPing(amp.Command):
    """Client originated ping message for gauging latency.

    Message attributes:
    clienttime - timestamp at client when ping generated.
    Response attributes:
    clienttime - timestamp at client when ping generated.
    servertime - timestamp at server when ping response generated.
    """
    arguments = [('clienttime', amp.Float())]
    response = [('clienttime', amp.Float()),
                ('servertime', amp.Float())]

class ClientControlEvent(amp.Command):
    """Client user control event.

    Message attributes:
    timestamp - Timestamp of control event.
    thrust - Forward/reverse thrust force.
    ccwthrust - Counter-clockwise thrust impulse.
    shootv - Velocity of a fired bullet.
    shoote - Energy of a fired bullet.
    """
    arguments = [('timestamp', amp.Float()),
                 ('thrust', amp.Float()),
                 ('ccwthrust',amp.Float()),
                 ('shootv', amp.Float()),
                 ('shoote', amp.Float())]

class ClientJoinRequest(amp.Command):
    """Client join/respawn request.

    Message attributes:
    shipname - User/player name.
    radius - Radius of the ship in pixels.
    wmax - Weapon relative maximum level (0-100).
    fmax - Fuel relative maximum level (0-100).
    smax - Shield relative maximum level (0-100).
    image - Bitmap of the ship icon (pygame format).
    imagex - Width of image.
    imagey - Height of image.
    thrustimg - Bitmap of the ship thrusting image.
    bulletimg - Bitmap of the ship's bullet image.
    """
    arguments = [('shipname',amp.String()),
                    ('radius',amp.Integer()),
                    ('wmax',amp.Integer()),
                    ('fmax',amp.Integer()),
                    ('smax',amp.Integer()),
                    ('image',amp.String()),
                    ('imagex',amp.Integer()),
                    ('imagey',amp.Integer()),
                    ('thrustimg',amp.String()),
                    ('bulletimg',amp.String())]
    response = [('shipid',amp.Integer()),('time',amp.Float()),
        ('gamewidth',amp.Integer()),('gameheight',amp.Integer())]

class ClientGenericRequest(amp.Command):
    """Generic client request.

    Message attributes:
    request - String code for a request.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('request',amp.String())]
    response = [('result', amp.Integer())]

class ClientGenericEvent(amp.Command):
    """Generic client event.

    Message attributes:
    event - String code for an event.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('event',amp.String())]
    response = [('result',amp.Integer())]

class ServerObjectStateEvent(amp.Command):
    """Server object state change event.

    Message attributes:
    objectid - Numeric ID of object.
    objecttype - Text representation of object type.
    objectname - Name of object.
    eventtime - Timestamp of object event.
    x - X coordinate of object position.
    y - Y coordinate of object position.
    vx - X component of object velocity.
    vy - Y component of object velocity.
    a - Axial acceleration of object.
    r - Rotational position of object in radians (0 points up).
    rr - Rotational rate of object in radians/second.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('objectid', amp.Integer()),
                 ('objecttype', amp.String()),
                 ('objectname', amp.String()),
                 ('eventtime', amp.Float()),
                 ('x', amp.Float()),
                 ('y', amp.Float()),
                 ('vx', amp.Float()),
                 ('vy', amp.Float()),
                 ('a', amp.Float()),
                 ('r', amp.Float()),
                 ('rr', amp.Float())]
    response = [('result', amp.Integer())]

class ServerObjectJoinEvent(amp.Command):
    """Server object join/spawn event.

    Message attributes:
    objectid - Numeric ID of object.
    objecttype - Text representation of object type.
    objectname - Name of object.
    radius - Radius of the ship in pixels.
    image - Bitmap of the ship icon (pygame format).
    imagex - Width of image.
    imagey - Height of image.
    thrustimg - Bitmap of the ship thrusting image.
    bulletimg - Bitmap of the ship's bullet image.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('objectid', amp.Integer()),
                 ('objecttype', amp.String()),
                 ('objectname', amp.String()),
                 ('radius', amp.Integer()),
                 ('image', amp.String()),
                 ('imagex', amp.Integer()),
                 ('imagey', amp.Integer()),
                 ('thrustimg', amp.String()),
                 ('bulletimg', amp.String())]
    response = [('result', amp.Integer())]

class ServerPrivateObjectStateEvent(amp.Command):
    """Server private object state event.

    Message attributes:
    objectid - Numeric ID of the object.
    wlevel - Weapon health level.
    flevel - Fuel health level.
    slevel - Shield health level.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('objectid',amp.Integer()),
                 ('wlevel',amp.Float()),
                 ('flevel',amp.Float()),
                 ('slevel',amp.Float())]
    response = [('result', amp.Integer())]

class ServerObjectDropEvent(amp.Command):
    """Server object drop event. An object has died/exploded/quit, etc.

    Message attributes:
    objectid - Numeric ID of the object.
    eventtime - Timestamp of drop.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('objectid', amp.Integer()),
                 ('eventtime', amp.Float())]
    response = [('result', amp.Integer())]

class ServerPlayerStatsEvent(amp.Command):
    """Server player stats event.

    Message attributes:
    playername - Name of player - empty string when done.
    playtime - Cumulative seconds of play time.
    killcount - Total number of kills since connected.
    killedcount - Total number of deaths since connected.
    Response attributes:
    result - 1 for success.
    """
    arguments = [('playername', amp.String()),
                 ('playtime', amp.Float()),
                 ('killcount', amp.Integer()),
                 ('killedcount',amp.Integer())
                ]
    response = [('result', amp.Integer())]


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

# Einlesen der Recommendation Übersicht
df = pd.read_csv('/Users/davidritter/Documents/userwerk/CDP_Recommendation/reco_overview.csv', sep=',')
print(list(df))

# Filtern nach Recommendation und tatsächlicher Bestellung
reco = df[df.event =='store']
reco_order = df[df.event =='order']

# Zähle Anzahl der Recommendation und Bestellungen
number_of_reco = reco.shape[0]
number_of_reco_order = reco_order.shape[0]

# Zähle Distinct die Anzahl der unterschiedlichen E-mails für die Recommmendation und die Bestellung
number_of_unique_reco = reco['hashedEmail'].unique().shape[0]
number_of_unique_reco_order = reco_order['hashedEmail'].unique().shape[0]

# Zähle das Häufigste Produkt in der Recommendation an 1. Stelle
reco1 = pd.DataFrame(reco, columns = ['p0'])
reco1 = reco1.rename(columns={'p0': 'Reco1'})
reco1 = reco1.value_counts().rename_axis('products_reco1').reset_index(name='counts')
print(reco1)

# Zähle das Häufigste Produkt in der Recommendation an 2. Stelle
reco2 = pd.DataFrame(reco, columns = ['p1'])
reco2 = reco2.rename(columns={'p1': 'Reco2'})
reco2 = reco2.value_counts().rename_axis('products_reco2').reset_index(name='counts')
print(reco2)

# Zähle das Häufigste Produkt in der Recommendation an 3. Stelle
reco3 = pd.DataFrame(reco, columns = ['p2'])
reco3 = reco3.rename(columns={'p2': 'Reco3'})
reco3 = reco3.value_counts().rename_axis('products_reco3').reset_index(name='counts')
print(reco3)

# Zähle das Häufigste Produkt in der Recommendation an 4. Stelle
reco4 = pd.DataFrame(reco, columns = ['p3'])
reco4 = reco4.rename(columns={'p3': 'Reco4'})
reco4 = reco4.value_counts().rename_axis('products_reco4').reset_index(name='counts')
print(reco4)

# Zähle das Häufigste Produkt in der Recommendation an 5. Stelle
reco5 = pd.DataFrame(reco, columns = ['p4'])
reco5 = reco5.rename(columns={'p4': 'Reco5'})
reco5 = reco5.value_counts().rename_axis('products_reco5').reset_index(name='counts')
print(reco5)

# Zähle das Häufigste Produkt in der Recommendation an 6. Stelle
reco6 = pd.DataFrame(reco, columns = ['p5'])
reco6 = reco6.rename(columns={'p5': 'Reco6'})
reco6 = reco6.value_counts().rename_axis('products_reco6').reset_index(name='counts')
print(reco6)

# Zähle das Häufigste Produkt in der Recommendation an 7. Stelle
reco7 = pd.DataFrame(reco, columns = ['p6'])
reco7 = reco7.rename(columns={'p6': 'Reco7'})
reco7 = reco7.value_counts().rename_axis('products_reco7').reset_index(name='counts')
print(reco7)

# Zähle das Häufigste Produkt in der Recommendation an 8. Stelle
reco8 = pd.DataFrame(reco, columns = ['p7'])
reco8 = reco8.rename(columns={'p7': 'Reco8'})
reco8 = reco8.value_counts().rename_axis('products_reco8').reset_index(name='counts')
print(reco8)

# Zähle das Häufigste Produkt in der Recommendation an 9. Stelle
reco9 = pd.DataFrame(reco, columns = ['p8'])
reco9 = reco9.rename(columns={'p8': 'Reco9'})
reco9 = reco9.value_counts().rename_axis('products_reco9').reset_index(name='counts')
print(reco9)

# Zähle das Häufigste Produkt in der Recommendation an 10. Stelle
reco10 = pd.DataFrame(reco, columns = ['p9'])
reco10 = reco10.rename(columns={'p9': 'Reco10'})
reco10 = reco10.value_counts().rename_axis('products_reco10').reset_index(name='counts')
print(reco10)

# Zähle das Häufigste Produkt in der Recommendation an 11. Stelle
reco11 = pd.DataFrame(reco, columns = ['p10'])
reco11 = reco11.rename(columns={'p10': 'Reco11'})
reco11 = reco11.value_counts().rename_axis('products_reco11').reset_index(name='counts')
print(reco11)

# Zähle das Häufigste Produkt in der Recommendation an 12. Stelle
reco12 = pd.DataFrame(reco, columns = ['p11'])
reco12 = reco12.rename(columns={'p11': 'Reco12'})
reco12 = reco12.value_counts().rename_axis('products_reco12').reset_index(name='counts')
print(reco12)

# Zähle das Häufigste Produkt in der Recommendation an 13. Stelle
reco13 = pd.DataFrame(reco, columns = ['p12'])
reco13 = reco13.rename(columns={'p12': 'Reco13'})
reco13 = reco13.value_counts().rename_axis('products_reco13').reset_index(name='counts')
print(reco13)

# Zähle das Häufigste Produkt in der Recommendation an 14. Stelle
reco14 = pd.DataFrame(reco, columns = ['p13'])
reco14 = reco14.rename(columns={'p13': 'Reco14'})
reco14 = reco14.value_counts().rename_axis('products_reco14').reset_index(name='counts')
print(reco14)

# Zähle das Häufigste Produkt in der Recommendation an 15. Stelle
reco15 = pd.DataFrame(reco, columns = ['p14'])
reco15 = reco15.rename(columns={'p14': 'Reco15'})
reco15 = reco15.value_counts().rename_axis('products_reco15').reset_index(name='counts')
print(reco15)

# Erstellen eines DataFrames mit allen absoluten Häufigkeiten der Produkte
products = pd.concat([reco1['products_reco1'], reco2['products_reco2'], reco3['products_reco3'], reco4['products_reco4'], reco5['products_reco5'], reco6['products_reco6'], reco7['products_reco7'], reco8['products_reco8'], reco9['products_reco9'], reco10['products_reco10'], reco11['products_reco11'], reco12['products_reco12'], reco13['products_reco13'], reco14['products_reco14'], reco15['products_reco15']], axis=0)
freq = pd.DataFrame({'products':list(products)})
freq = freq.drop_duplicates()
freq = freq.reset_index()
freq = freq.drop(['index'], axis=1)
freq = freq.join(reco1, lsuffix='products', rsuffix='products_reco1')
freq = freq.drop(['products_reco1'], axis=1)
freq = freq.rename(columns={'counts': 'Reco1'})
freq = freq.set_index('products').join(reco2.set_index('products_reco2'))
freq = freq.rename(columns={'counts': 'Reco2'})
freq = freq.join(reco3.set_index('products_reco3'))
freq = freq.rename(columns={'counts': 'Reco3'})
freq = freq.join(reco4.set_index('products_reco4'))
freq = freq.rename(columns={'counts': 'Reco4'})
freq = freq.join(reco5.set_index('products_reco5'))
freq = freq.rename(columns={'counts': 'Reco5'})
freq = freq.join(reco6.set_index('products_reco6'))
freq = freq.rename(columns={'counts': 'Reco6'})
freq = freq.join(reco7.set_index('products_reco7'))
freq = freq.rename(columns={'counts': 'Reco7'})
freq = freq.join(reco8.set_index('products_reco8'))
freq = freq.rename(columns={'counts': 'Reco8'})
freq = freq.join(reco9.set_index('products_reco9'))
freq = freq.rename(columns={'counts': 'Reco9'})
freq = freq.join(reco10.set_index('products_reco10'))
freq = freq.rename(columns={'counts': 'Reco10'})
freq = freq.join(reco11.set_index('products_reco11'))
freq = freq.rename(columns={'counts': 'Reco11'})
freq = freq.join(reco12.set_index('products_reco12'))
freq = freq.rename(columns={'counts': 'Reco12'})
freq = freq.join(reco13.set_index('products_reco13'))
freq = freq.rename(columns={'counts': 'Reco13'})
freq = freq.join(reco14.set_index('products_reco14'))
freq = freq.rename(columns={'counts': 'Reco14'})
freq = freq.join(reco15.set_index('products_reco15'))
freq = freq.rename(columns={'counts': 'Reco15'})
freq = freq.fillna(0)
freq = freq.astype(int)
freq['top'] = freq['Reco1']
freq['top2'] = freq['Reco1'] + freq['Reco2']
freq['top3'] = freq['Reco1'] + freq['Reco2'] + freq['Reco3']
freq['top4'] = freq['Reco1'] + freq['Reco2'] + freq['Reco3'] + freq['Reco4']
freq['top5'] = freq['Reco1'] + freq['Reco2'] + freq['Reco3'] + freq['Reco4'] + freq['Reco5']
freq['top10'] = freq['Reco1'] + freq['Reco2'] + freq['Reco3'] + freq['Reco4'] + freq['Reco5'] + freq['Reco6'] + freq['Reco7'] + freq['Reco8'] + freq['Reco9'] + freq['Reco10']
freq['total'] = freq['Reco1'] + freq['Reco2'] + freq['Reco3'] + freq['Reco4'] + freq['Reco5'] + freq['Reco6'] + freq['Reco7'] + freq['Reco8'] + freq['Reco9'] + freq['Reco10'] + freq['Reco11'] + freq['Reco12'] + freq['Reco13'] + freq['Reco14'] + freq['Reco15']
freq = freq.sort_values(by=['total'], ascending=False)
print(freq)

# Produkte die Immer Empfohlen werden
always_reco = freq.dropna()
print(always_reco)

print(freq)
print(len(reco))

rel_freq = (freq/len(reco)) * 100
print(rel_freq)

freq.to_csv('/Users/davidritter/Documents/userwerk/CDP_Recommendation/reco_freq.csv')
rel_freq.to_csv('/Users/davidritter/Documents/userwerk/CDP_Recommendation/reco_rel_freq.csv')

# Zähle das Häufigsten bestellten Produkt in der Recommendation an 1. Stelle
ordere_product = pd.DataFrame(reco_order, columns = ['orderedProduct'])
ordere_product = ordere_product.value_counts().rename_axis('products_reco1').reset_index(name='counts')

ordere_product= ordere_product.reset_index()
ordere_product = ordere_product.drop(['index'], axis=1)
ordere_product= ordere_product.rename(columns={'products_reco1': 'orderedProduct'})
print(ordere_product)
print(len(reco_order))

rel_freq_ordere_product = ordere_product
rel_freq_ordere_product['counts'] = (rel_freq_ordere_product['counts']/len(reco_order)) * 100
print(rel_freq_ordere_product)

ordere_product.to_csv('/Users/davidritter/Documents/userwerk/CDP_Recommendation/ordere_product.csv')
rel_freq_ordere_product.to_csv('/Users/davidritter/Documents/userwerk/CDP_Recommendation/rel_freq_ordere_product.csv')


import climate
from climate.pyom import PyOM
from climate.pyom.core import numerics, external, idemix
from climate.setup.acc2 import ACC2
import numpy as np
import sys
np.set_printoptions(threshold=np.nan)

yt_start = -39.0
yt_end   = 43
yu_start = -40.0
yu_end   = 42

baroTimer = climate.Timer("barotropics")
if len(sys.argv) == 2:
    b = ACC2(fortran=sys.argv[1])
    b.fortran.my_mpi_init(0)
    b.set_parameter()
    b.set_legacy_parameter()
    b.fortran.pe_decomposition()
    b.fortran.allocate_main_module()
    b.fortran.allocate_isoneutral_module()
    b.fortran.allocate_tke_module()
    b.fortran.allocate_eke_module()
    b.fortran.allocate_idemix_module()
    b.set_grid()
    b.fortran.calc_grid()
    b.set_coriolis()
    b.fortran.calc_beta()
    b.set_topography()
    b.fortran.calc_topo()
    b.set_initial_conditions()
    b.fortran.calc_initial_conditions()
    b.fortran.streamfunction_init()
    with baroTimer:
        for i in xrange(1000):
            b.fortran.solve_streamfunction()
else:
    a = ACC2()
    """
     allocate everything
    """
    a.set_parameter()
    a._allocate()

    """
      Grid
    """
    a.set_grid()
    numerics.calc_grid(a)

    """
     Coriolis
    """
    a.set_coriolis()
    numerics.calc_beta(a)

    """
     topography
    """
    a.set_topography()

    numerics.calc_topo(a)
    idemix.calc_spectral_topo(a)

    a.set_initial_conditions()
    numerics.calc_initial_conditions(a)

    a.set_forcing()

    external.streamfunction_init(a)
    with baroTimer:
        for i in xrange(1000):
            external.solve_streamfunction(a)
baroTimer.printTime()


# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, x):
#	self.val = x
#	self.left = None
#	self.right = None

class Solution:
	def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
		count = 0
		i = 0
		stack = [(root, 0)]

		op_list = list()
		temp_list = list()
		prev_lev = 0
		while stack:
			node, level = stack.pop(0)
			# print(stack)
			if node:
				stack.append((node.left, level+1))
				stack.append((node.right, level+1))
				# print(level)
				if prev_lev != level:
					prev_lev = level
					if count % 2!=0:
						temp_list.reverse();
					op_list.append(temp_list)
					temp_list= list()
					temp_list.append(node.val)
					count = count + 1
				else:
					temp_list.append(node.val)

		if temp_list:
			if (count) % 2!=0:
				temp_list.reverse();
			op_list.append(temp_list)

		return(op_list)


from django.contrib.auth.decorators import login_required
from django.views.generic import FormView, ListView
from aircraft.models import NewPlaneMaster,AircraftModel
from logbook.models import FlightTime
from user.views import getuserid
from dal import autocomplete
from aircraft.forms import AirplaneEntry
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.views.generic.base import TemplateView
from django.views.generic import FormView, DetailView
from django.views.generic.list import ListView
from aircraft.models import AircraftModel, Manufacture, NewPlaneMaster
from airport.views import airporthome
from logbook.models import FlightTime
from user.models import Users
from django.contrib.auth.models import User
from django_currentuser.middleware import (
    get_current_user)
from user.views import getuserid
from airline.views import flightaware
from django.core.paginator import Paginator
from django.db.models import Count,Sum,Avg
from django.db.models.functions import Round
from django.db.models import Q
from django.http import HttpResponse

@login_required(login_url='/')

def aircrafthome(request):
    print('hello')

class CategoryDisplayAll(TemplateView):
    template_name = 'aircraft/aircraftbase.html'
    def get(self, request, *args, **kwargs):
        pagetitle = "Category Report"
        qs = []
        userid = getuserid()
        manufacture = Manufacture.objects.all().values()
        #this is used to get the category totals, you can also select the manufacture totals dropdown
        #gets all the airplanes
        uniquetype = FlightTime.objects.filter(userid=userid).values('aircrafttype').distinct()
        for airtype in uniquetype:
            info = {'aircraftsummary': FlightTime.objects.filter(userid=userid,aircrafttype=airtype['aircrafttype']).aggregate(
                airtotal = Sum('total'),
                avgflight = Avg('total'),
                numflight = Count('total'),
                avgmiles = Round(Avg('distance')),
                totalmiles = Sum('distance'),
                avgpax = Round(Avg('passengercount')),
                totalpax = Sum('passengercount'),
                night = Sum('night'),
                landings = Sum('landings'),
            )}
            lastflown = FlightTime.objects.filter(userid=userid,aircrafttype=airtype['aircrafttype']).exclude(scheduledflight=1).latest('flightdate')

            record = {'aircraftype':airtype['aircrafttype'],'info':{'aircraftsummary':{'airtotal':info['aircraftsummary']['airtotal'],'avgflight':round((info['aircraftsummary']['avgflight']),2),'numflight':info['aircraftsummary']['numflight'],'avgmiles':int(round((info['aircraftsummary']['avgmiles']),0)),'totalmiles':info['aircraftsummary']['totalmiles'],'avgpax':int(round((info['aircraftsummary']['avgpax']),0)),'totalpax':info['aircraftsummary']['totalpax'],'night':info['aircraftsummary']['night'],'landings':info['aircraftsummary']['landings']}},'lastflown':lastflown}

            if record['info']['aircraftsummary']['airtotal'] > 0:
                qs.append(record)

        return self.render_to_response({"manufacture":manufacture,"qs":qs, "title":pagetitle})
class CategoryDisplay(TemplateView):
    template_name = 'aircraft/categorydisplay.html'
    def get(self, request, *args, **kwargs):
        pagetitle = "Category Report"
        qs = []
        userid = getuserid()
        manufacture = Manufacture.objects.all().values()
        #this is used to get the category totals, you can also select the manufacture totals dropdown

        id = request.GET.get('category')
        uniquetype = AircraftModel.objects.filter(mfr=id)
        for airtype in uniquetype:
            checkingfornone = FlightTime.objects.filter(userid=userid,aircrafttype=airtype).aggregate(Sum('total'))

            if checkingfornone['total__sum'] != None:
                info = {'aircraftsummary': FlightTime.objects.filter(userid=userid,aircrafttype=airtype).aggregate(
                    airtotal = Sum('total'),
                    avgflight = Avg('total'),
                    numflight = Count('total'),
                    avgmiles = Avg('distance'),
                    totalmiles = Sum('distance'),
                    avgpax = Avg('passengercount'),
                    totalpax = Sum('passengercount'),
                    night = Sum('night'),
                    landings = Sum('landings'),
                )}
                lastflown = FlightTime.objects.filter(userid=userid,aircrafttype=airtype).exclude(scheduledflight=1).latest('flightdate')

                #making it so that i can round the results the way I want
                #them before appending them to the list to send them to the
                #template in the context
                record = {'aircraftype':airtype,'info':{'aircraftsummary':{'airtotal':info['aircraftsummary']['airtotal'],'avgflight':round((info['aircraftsummary']['avgflight']),2),'numflight':info['aircraftsummary']['numflight'],'avgmiles':int(round((info['aircraftsummary']['avgmiles']),0)),'totalmiles':info['aircraftsummary']['totalmiles'],'avgpax':int(round((info['aircraftsummary']['avgpax']),0)),'totalpax':info['aircraftsummary']['totalpax'],'night':info['aircraftsummary']['night'],'landings':info['aircraftsummary']['landings']}},'lastflown':lastflown}
                if record['info']['aircraftsummary']['airtotal'] != None:
                    qs.append(record)
        tairtotal = 0; tavgflight = 0; tnumflight = 0; tavgmiles = 0
        ttotalmiles = 0; tavgpax = 0; ttotalpax = 0; count = 0; tnight = 0; tlandings = 0;
        #adding the totals for the categories
        for itemtotal in qs:
            tairtotal = tairtotal + (itemtotal['info']['aircraftsummary']['airtotal'])
            tavgflight = tavgflight + (itemtotal['info']['aircraftsummary']['avgflight'])
            tnumflight = tnumflight + (itemtotal['info']['aircraftsummary']['numflight'])
            tavgmiles = tavgmiles + (itemtotal['info']['aircraftsummary']['avgmiles'])
            ttotalmiles = ttotalmiles + (itemtotal['info']['aircraftsummary']['totalmiles'])
            tavgpax = tavgpax + (itemtotal['info']['aircraftsummary']['avgpax'])
            ttotalpax = ttotalpax + (itemtotal['info']['aircraftsummary']['totalpax'])
            tnight = tnight + (itemtotal['info']['aircraftsummary']['night'])
            tlandings = tlandings + (itemtotal['info']['aircraftsummary']['landings'])
            count += 1

        record = {'aircraftype':'Total','info':{'aircraftsummary':{'airtotal':tairtotal,'avgflight':round((tavgflight/count),2),'numflight':tnumflight,'avgmiles':int((tavgmiles/count)),'totalmiles':ttotalmiles,'avgpax':int(tavgpax/count),'totalpax':ttotalpax,'night':tnight,'landings':tlandings}}}
        qs.append(record)
        return self.render_to_response({"manufacture":manufacture,"qs":qs, "title":pagetitle})

class TailBase(TemplateView):
    template_name = 'aircraft/tailbase.html'
    def get(self, request, *args, **kwargs):
        pagetitle = "Tail Number Lookup"
        return self.render_to_response({"title":pagetitle})
class TailLookupDisplay(TemplateView):
    template_name = 'aircraft/taillookup.html'

    def get(self, request, *args, **kwargs):
        userid=getuserid()
        pagetitle = "Tail Number Lookup"
        secondrequest = request.GET.get('lookup[id]')

        info = FlightTime.objects.filter(userid=userid,aircraftId=secondrequest).aggregate(
                    airtotal = Sum('total'),
                    miletotal = Sum('distance'),
                    paxtotal = Sum('passengercount'),
                    flighttotal = Count('total'),
                    avgflight = Avg('total'),
                    avgdistance = Avg('distance'),
                    avgpax = Avg('passengercount')
            )
        flights = FlightTime.objects.filter(userid=userid,aircraftId=secondrequest).exclude(scheduledflight=True).order_by('-flightdate')

        return self.render_to_response({"title":pagetitle,"years":info,"depart":flights})
class TailNumberLookup(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = []
        userid = getuserid()
        disticttails = FlightTime.objects.filter(userid=userid).values('aircraftId').distinct().order_by('aircraftId')

        for aircraft in disticttails:
            data = {'id':aircraft['aircraftId'],'text':aircraft['aircraftId']}
            qs.append(data)

        # return  JsonResponse(correctdata, safe=False)
        # print(correctdata)
        # return self.render_to_response({"result":correctdata})
        qs = NewPlaneMaster.objects.all().order_by('nnumber')
        if self.q:
            qs = qs.filter(nnumber__istartswith=self.q)
        return qs

class NewIDLookup(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        qs = AircraftModel.objects.all().order_by('type')
        if self.q:
            qs = qs.filter(type__istartswith=self.q)
        return qs
class AircraftEntry(FormView):

    template_name = 'aircraft/searchtype.html'
    form_class = AirplaneEntry
    success_url = 'entry'

    def form_valid(self,form):
        form.save()
        return super().form_valid(form)


# Python3 program to Find elements of a
# list by indices present in another list

def findElements(lst1, lst2):
    return [lst1[i] for i in lst2]

# Driver code
lst1 = [10, 20, 30, 40, 50]
lst2 = [0, 2, 4]
print(findElements(lst1, lst2))

# Python3 program to Find elements of a
# list by indices present in another list

def findElements1(lst1, lst2):
    return list(map(lst1.__getitem__, lst2))

# Driver code
lst1 = [10, 20, 30, 40, 50]
lst2 = [0, 2, 4]
print(findElements1(lst1, lst2))

def findElements2(lst1, lst2):
    # Create a dictionary that maps indices in lst2 to their corresponding elements in lst1
    index_map = {index: element for index, element in enumerate(lst1)}

    # Use a list comprehension to extract the values from the dictionary
    return [index_map[index] for index in lst2]

lst1 = [10, 20, 30, 40, 50]
lst2 = [0, 2, 4]
print(findElements2(lst1, lst2))

#---------------------
nums = [1,2,3,4,5,6,7,8,9,10]

my_list = []
for letter in "abcd":
  for num in nums:
    my_list.append((letter, num))

print(my_list)

my_list = [(letter, num) for letter in "abcd" for num in range(4)]
print(my_list)

temps = [29.3, 20, -100, 60.23, 88, -9999, 122, "no data"]

new_temps = [temp/10 for temp in temps if not(isinstance(temp, str)) and temp > 0]

print(new_temps)

new_temps = [temp/10 if not(isinstance(temp, str)) and temp > 0 else 0 for temp in temps]

print(new_temps)

pair = ['2.3', '2.9', '14.6']

people = [{
  "first_name": "Василий",
  "last_name": "Марков",
  "birthday": "9/25/1984"
}, {
  "first_name": "Регина",
  "last_name": "Павленко",
  "birthday": "8/21/1995"
}]

birthdays = [
  person[term]
  for person in people
  for term in person
  if term == "birthday"
]

print(birthdays)

fruits = ["apples", "bananas", "strawberries"]
fruits = [fruit.upper() for fruit in fruits]

print(fruits)

my_string = "HelloMyNameIsAnton"
my_string = "".join([i if i.islower()  else " " + i.lower() if i in ["N", "I"] else " " + i for i in my_string])[1:]
print(my_string)

numbers = [1,2,3,4,5,6]
letters = ["a","b","c","d","e","f"]
g = {x: y for x, y in zip(numbers, letters)}
print(g)
#---------------------------

def grut(values):
    return sum([float(value) for value in values])

print(grut(pair))

def area(a, b):
    return a+b

print(area('4', '6'))

def find_sum(**kwargs):
    return sum(kwargs.values())

print(find_sum(x=1, y=2, z=6))


# -*- coding: utf-8 -*-

import ampligraph
import openbiolink
from ampligraph import evaluation
from ampligraph.evaluation import evaluate_performance
from openbiolink.evaluation.dataLoader import DataLoader
from ampligraph.latent_features import ComplEx
import tensorflow as tf
import numpy as np
from ampligraph.latent_features import save_model, restore_model
import argparse

def train_model(save_dir, output_dir, epochs):
    # Name of the Dataset, possible values HQ_DIR, HQ_UNDIR, ALL_DIR, ALL_UNDIR. Default: HQ_DIR
    dl = DataLoader("HQ_DIR")

    cmp = []

    for el in dl.mappings['nodes']['label2id']:
      if 'compound' in el.lower():
        cmp.append(el)

    rels = set(dl.data['train_positive'][1])

    print(dl.mappings['relations']['label2id'])

    train_positive = dl.data['train_positive'].to_numpy()
    train_negative = dl.data['train_negative'].to_numpy()

    test_positive = dl.data['test_positive'].to_numpy()
    test_negative = dl.data['test_negative'].to_numpy()

    validation_positive = dl.data['valid_positive'].to_numpy()
    vakidation_negative = dl.data['valid_negative'].to_numpy()

    model = ComplEx(batches_count=250,
                    seed=0,
                    epochs=epochs,
                    k=200,
                    eta=30,
                    embedding_model_params = {'negative_corruption_entities': train_negative},
                    optimizer='adam',
                    optimizer_params={'lr':0.001},
                    loss='multiclass_nll',
                    regularizer='LP',
                    regularizer_params={'p': 3, 'lambda': 0.001},
                    verbose=True)

    tf.logging.set_verbosity(tf.logging.ERROR)
    print("---------------Training the model...---------------")
    model.fit(train_positive, early_stopping=False)

    save_model(model, save_dir)

    X_positive = np.concatenate((train_positive, test_positive, validation_positive), axis=0)

    print("---------------Evaluate the model...---------------")
    ranks = evaluate_performance(test_positive,
                                 model=model,
                                 filter_triples=X_positive,   # Corruption strategy filter defined above
                                 verbose=True)

    # save ranks
    print("---------------Saving the evaluation results...---------------")
    np.save(output_dir, np.asarray(ranks))

if __name__ == '__main__':

    # Construct the argument parser
    ap = argparse.ArgumentParser()

    # Add the arguments to the parser
    ap.add_argument("-epochs", "--epochs", required=True,
                    help="Where to save the evaluation results.")

    ap.add_argument("-save-dir", "--save-dir", required=True,
                    help="Directory to save the trained model.")

    ap.add_argument("-output", "--output-dir", required=True,
                     help="Where to save the evaluation results.")

    args = ap.parse_args()
    print(args)
    save_dir = args.save_dir
    output_dir = args.output_dir
    epochs = args.epochs
    train_model(save_dir, output_dir, epochs)


from flask import Flask, render_template, url_for, redirect
from flask import request, flash, get_flashed_messages
from datetime import date
from urllib.parse import urlparse
from bs4 import BeautifulSoup
from dotenv import load_dotenv
import psycopg2
import psycopg2.extras
import os
import validators
import requests

load_dotenv()

app = Flask(__name__)

app.secret_key = os.getenv('SECRET_KEY')
DATABASE_URL = os.getenv('DATABASE_URL')

def make_conn():
    return psycopg2.connect(DATABASE_URL)

def normalize_url(url):
    parsed_url = urlparse(url)
    return f'{parsed_url.scheme}://{parsed_url.hostname}'

def get_page_data(html):
    soup = BeautifulSoup(html, 'html.parser')
    h1 = title = desc = ''

    if soup.find('h1'):
        h1 = soup.h1.text

    if soup.find('title'):
        title = soup.title.string

    if soup.find('meta'):
        desc = soup.meta.attrs.get('content', '')

    return h1, title, desc

@app.get('/')
def get_index():
    messages = get_flashed_messages(with_categories=True)
    return render_template('index.html', messages=messages, url='')

@app.post('/urls')
def post_urls():
    data = request.form.to_dict()
    if not validators.url(data['url']):
        flash('Некорректный URL', 'error')
        messages = get_flashed_messages(with_categories=True)
        return render_template('index.html', messages=messages,
                               url=data['url']), 422
    conn = make_conn()
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    url = normalize_url(data['url'])

    cur.execute("SELECT id FROM urls WHERE name=%s", (url,))
    rec = cur.fetchone()

    if rec:
        conn.close()

        flash('Страница уже существует', 'info')
        return redirect(url_for('get_url', id=rec['id']))

    cur.execute("INSERT INTO urls (name, created_at) VALUES (%s, %s)"
                "RETURNING id", (url, date.today()))
    conn.commit()
    rec = cur.fetchone()

    conn.close()

    flash('Страница успешно добавлена', 'success')
    return redirect(url_for('get_url', id=rec['id']))

@app.get('/urls')
def get_urls():
    conn = make_conn()
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    cur.execute("SELECT urls.id, urls.name, url_checks.created_at, "
                "url_checks.status_code FROM urls LEFT JOIN "
                "(SELECT * FROM url_checks WHERE id IN "
                "(SELECT MAX(id) as id FROM url_checks GROUP BY url_id)) "
                "AS url_checks ON urls.id = url_checks.url_id "
                "ORDER BY urls.id DESC")
    data = cur.fetchall()

    conn.close()
    return render_template('urls.html', data=data)

@app.route('/urls/<int:id>')
def get_url(id):
    messages = get_flashed_messages(with_categories=True)
    conn = make_conn()
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    cur.execute("SELECT * FROM urls WHERE id=%s", (id,))
    data = cur.fetchone()

    if not data:
        conn.close()
        return render_template('notfound.html'), 404

    cur.execute("SELECT * FROM url_checks WHERE url_id=%s ORDER BY id DESC",
                (id,))
    checks = cur.fetchall()

    conn.close()
    return render_template('url.html', messages=messages, data=data,
                           checks=checks)

@app.post('/urls/<int:id>/checks')
def post_check(id):
    conn = make_conn()
    cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    cur.execute("SELECT name FROM urls WHERE id=%s", (id,))
    rec = cur.fetchone()

    try:
        resp = requests.get(rec['name'])
        resp.raise_for_status()
    except requests.exceptions.RequestException:
        conn.close()

        flash('Произошла ошибка при проверке', 'error')
        return redirect(url_for('get_url', id=id))

    h1, title, desc = get_page_data(resp.text)
    cur.execute("INSERT INTO url_checks "
                "(url_id, status_code, h1, title, description, created_at) "
                "VALUES (%s, %s, %s, %s, %s, %s)",
                (id, resp.status_code, h1, title, desc, date.today()))
    conn.commit()
    conn.close()

    flash('Страница успешно проверена', 'success')
    return redirect(url_for('get_url', id=id))


import requests
import urllib
import pandas as pd
import sys
import json

from bs4 import BeautifulSoup

# Function to extract Product Title
def get_title(soup):

    try:
        # Outer Tag Object
        title = soup.find("span", attrs={"id": 'productTitle'})

        # Inner NavigatableString Object
        title_value = title.string

        # Title as a string value
        title_string = title_value.strip()

        # # Printing types of values for efficient understanding
        # print(type(title))
        # print(type(title_value))
        # print(type(title_string))
        # print()

    except AttributeError:
        title_string = ""

    return title_string

    # Function to extract Product Title

def get_image(soup, alt_title):

    image_string = ''

    try:
        # Outer Tag Object
        images = soup.find("img", attrs={"alt": alt_title})
        image_string = images.attrs['data-old-hires']

    except AttributeError:
        image_string = ""

    return image_string

# Function to extract Product Price
def get_price(soup):

    try:
        price = soup.find(
            "span", attrs={'id': 'priceblock_ourprice'}).string.strip()

    except AttributeError:
        price = ""

    return price

    # Function to extract Product Price

def get_original_price(soup):

    try:
        original_price = soup.find(
            "span", attrs={'class': 'priceBlockStrikePriceString'}).string.strip()

    except AttributeError:
        original_price = ""

    return original_price

# Function to extract Product Rating
def get_rating(soup):

    try:
        rating = soup.find(
            "i", attrs={'class': 'a-icon a-icon-star a-star-4-5'}).string.strip()

    except AttributeError:

        try:
            rating = soup.find(
                "span", attrs={'class': 'a-icon-alt'}).string.strip()
        except:
            rating = ""

    return rating

# Function to extract Number of User Reviews

def get_review_count(soup):
    try:
        review_count = soup.find(
            "span", attrs={'id': 'acrCustomerReviewText'}).string.strip()

    except AttributeError:
        review_count = ""

    return review_count

# Function to extract Availability Status
def get_availability(soup):
    try:
        available = soup.find("div", attrs={'id': 'availability'})
        available = available.find("span").string.strip()

    except AttributeError:
        available = "Not Available"

    return available

def amazon_scrape(keyword, HEADERS):

    # URL = "https://www.amazon.com/s?k=playstation+4&ref=nb_sb_noss_2"
    URL = 'https://www.amazon.com/s?' + urllib.parse.urlencode({'k': keyword})

    proxies = {
        'http': 'http://10.10.10.10:8000',
        'https': 'http://10.10.10.10:8000'
    }

    # HTTP Request
    webpage = requests.get(URL, headers=HEADERS)

    # Soup Object containing all data
    soup = BeautifulSoup(webpage.content, "lxml")

    # Fetch links as List of Tag Objects
    links = soup.find_all("a", attrs={'class': 'a-link-normal s-no-outline'})

    # Store the links
    links_list = []

    data_list = []

    # Loop for extracting links from Tag Objects
    for link in links:
        links_list.append(link.get('href'))

    # Loop for extracting product details from each link
    for link in links_list:

        new_webpage = requests.get(
            "https://www.amazon.com" + link, headers=HEADERS)

        new_soup = BeautifulSoup(new_webpage.content, "lxml")
        url = 'https://www.amazon.com' + link

        title = get_title(new_soup)
        # all_images = get_image(new_soup, title)
        rating = get_rating(new_soup)
        price = get_price(new_soup)
        original_price = get_original_price(new_soup)

        if (price != ""):
            data = {}
            data['title'] = title
            data['price'] = float(price[1:])
            data['rating'] = rating
            data['link'] = url

            if (original_price != ""):
                data['original_price'] = float(original_price[1:])
            else:
                data['original_price'] = ""

            data_list.append(data)

            # print("Product Title =", title)
            # # print("Product Image =", get_image(new_soup, title))
            # print("Product Price = $", price)
            # print("Product Price [Original]= $", get_original_price(new_soup))
            # print("Product Rating =", get_rating(new_soup))
            # print("Number of Product Reviews =", get_review_count(new_soup))
            # print("Availability =", get_availability(new_soup))
            # print("Link =", url)
            # print()
            # print()

    return data_list

if __name__ == '__main__':

    # Headers for request
    HEADERS = ({'User-Agent':
                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
                'Accept-Language': 'en-US'})

    keyword = str(sys.argv[1])
    # keyword = 'Playstation 4 Console'

    results = amazon_scrape(keyword, HEADERS)
    list_to_json_array = json.dumps(results)

    print(list_to_json_array)
    # print(results)