import urllib
import sys
from bs4 import BeautifulSoup
from urllib import request, error
from file_manager import FileWriter

class SohuCrawler:
    def __init__(self):
        self.index_list = []
        self.page = None
        self.type = ''
        self.file_writer = None
        self.total = 0

    def init_index_list(self, index):
        counter = 1
        while counter < 1500:
            print("initializing list " + str(counter) + '...')
            url = SohuCrawler.get_list_url(index, counter)
            if self.init_page(url):
                soup = BeautifulSoup(self.page, "html.parser")
                # init the type
                if self.type == '' and soup.find(class_="cTtl"):
                    self.type = soup.find(class_="cTtl").string
                # init the index_list
                for content in soup.find_all('a', class_="h4 h4New"):
                    self.index_list.append(content.get("href"))
            counter += 1

    def crawler(self):
        for tmp in self.index_list:
            tmp_url = "http://m.sohu.com" + tmp
            if self.init_page(tmp_url):
                soup = BeautifulSoup(self.page, "html.parser")
                # init file writer
                self.file_writer = FileWriter('sohu/' + self.type + '/', str(self.total) + '.txt')
                try:
                    # get title
                    if soup.find('h1', class_='h1') and soup.find('h1', class_='h1').string:
                        title = soup.find('h1', class_='h1').string
                        self.file_writer.file_obj.write(title + '\n')
                    # get content
                    contents = soup.find_all('p', class_='para')
                    for content in contents:
                        if content.string:
                            self.file_writer.file_obj.write(content.string + '\n')
                finally:
                    self.file_writer.close()
            self.total += 1
            print("current:" + str(self.total))

    def init_page(self, url):
        try:
            url_request = urllib.request.Request(url)
            response = urllib.request.urlopen(url_request)
            self.page = response.read().decode(sys.getfilesystemencoding())
            return True
        except error.URLError:
            self.page = None
            print("url error\n")
            return False
        except ConnectionResetError:
            print("ConnectionResetError\n")
            return False
        except UnicodeDecodeError:
            print('UnicodeDecodeError')
            return False

    @staticmethod
    def get_list_url(index, num):
        return "http://m.sohu.com/cr/" + str(index) + "/?page=" + str(num)

    def clear(self):
        self.file_writer = None
        self.index_list.clear()
        self.page = None
        self.type = ''
        self.total = 0

    def start(self):
        index = 18
        while index < 22:
            self.init_index_list(index)
            self.crawler()
            print("finish crawling:" + self.type)
            self.clear()
            index += 1

crawler = SohuCrawler()
crawler.start()


import sys

num = int(input())

for i in range(num):
    lst = list(map(int, sys.stdin.readline().split()))
    del lst[0]
    avg = sum(lst)/len(lst)
    highscore = list(filter(lambda x: x > avg, lst))
    print('{:.3f}%'.format((round(len(highscore)/len(lst)*100, 3))))


import unittest

from vampires import Warrior, Knight, Army, Battle, Defender, Vampire

class VampiresTesting(unittest.TestCase):

    def test_create_vampire(self):
        result = Vampire

        self.assertEqual(type(Vampire()), result)

    def test_vampire_health(self):
        result = 40

        v = Vampire()
        self.assertEqual(v.health, result)

    def test_vampire_vs_defender(self):
        result = False

        b = Battle()
        a1 = Army()
        a1.addUnits(Vampire, 1)
        a2 = Army()
        a2.addUnits(Defender, 1)

        self.assertEqual(b.fight(a1, a2), result)

    def test_1war_4def_vs_3vamp_2war(self):
        result = True

        b = Battle()
        a1 = Army()
        a2 = Army()

        # a1.addUnits(Warrior, 1)
        # a2.addUnits(Vampire, 1)

        a1.addUnits(Warrior, 1)
        a1.addUnits(Defender, 4)

        a2.addUnits(Vampire, 3)
        a2.addUnits(Warrior, 2)

        self.assertEqual(b.fight(a1, a2), result)

b = Battle()
a1 = Army()
a2 = Army()

a1.addUnits(Warrior, 1)

a2.addUnits(Vampire, 1)

print(b.fight(a1, a2))


from django.urls import path
from dispo_controller import views

urlpatterns = [
    #path('create_credit_proforma', views.create_credit_proforma),
    path('create_credit', views.create_credit),
    path('create_contract', views.create_contract),
    path('create_claim', views.create_claim),
    path('test', views.make_test),
    path('helpers/create_supplier_amount_ref', views.create_supplier_amount_ref),
    path('make_order', views.make_order)
]


from request import request_url
from openpyxl import Workbook
from openpyxl.styles import Font, Color, Alignment, Border, Side
from openpyxl.utils import get_column_letter

dictionary = request_url('https://restcountries.com/v3/all')# Return values from API
#init xlxs document, reference: https://openpyxl.readthedocs.io/en/stable/tutorial.html
wb = Workbook()
ws = wb.active
thin = Side(border_style="thin", color="D9D9E3")#border color
ws.title = "Countries List"
ws.merge_cells('A1:D1')
#Create title of table
ws['A1'] = 'Countries List'
ws['A1'].font = Font(color="4F4F4F", bold = True, size = 16)#font edit, color, bold and size.
ws['A1'].alignment = Alignment(horizontal="center", vertical="center")
ws['A1'].border = Border(top=thin, left=thin, right=thin, bottom=thin)#crate border
ws['E1'].border = Border(left = thin)
#Create title of columns

ws['A2'] = 'Name'
ws['A2'].font = Font(color="808080", bold = True, size = 12)
ws['A2'].border = Border(top=thin, left=thin, right=thin, bottom=thin)

ws['B2'] = 'Capital'
ws['B2'].font = Font(color="808080", bold = True, size = 12)
ws['B2'].border = Border(top=thin, left=thin, right=thin, bottom=thin)

ws['C2'] = 'Area'
ws['C2'].font = Font(color="808080", bold = True, size = 12)
ws['C2'].border = Border(top=thin, left=thin, right=thin, bottom=thin)

ws['D2'] = 'Currencies'
ws['D2'].font = Font(color="808080", bold = True, size = 12)
ws['D2'].border = Border(top=thin, left=thin, right=thin, bottom=thin)
ws['D2'].alignment = Alignment(vertical="top")

ws.column_dimensions['A'].width = 36.89
ws.column_dimensions['B'].width = 21.96
ws.column_dimensions['C'].width = 9.48
ws.column_dimensions['D'].width = 14.37

# Get datas from dictionary
i = 3 #iterable var
for row in dictionary:
  x = 'A' + str(i) #Cell iterable selection from column A
  ws[x] = row['Name'] #Find information by key name
  ws[x].border = Border(top=thin, left=thin, right=thin, bottom=thin)
  x = 'B' + str(i) #Cell iterable selection from column B
  ws[x] = row['Capital'] #Find information by key name
  ws[x].border = Border(top=thin, left=thin, right=thin, bottom=thin)
  x = 'C' + str(i)
  ws[x] = row['Area']
  ws[x].border = Border(top=thin, left=thin, right=thin, bottom=thin)
  x = 'D' + str(i)
  ws[x] = row['Currencies']
  ws[x].border = Border(top=thin, left=thin, right=thin, bottom=thin)
  i = i + 1
#Save xlsx archive format
wb.save("country_table.xlsx")


import cv2
import numpy as np
"""
We will be joining the images into horizontal and vertical stack

Requirement:
All the images should be of same channel and format like RBG, Gray or BW

Solution:
Before stacking we can convert them into same channel stack it

"""
# reading the image
img = cv2.imread('Resources/small_bird.jpg')

# Horizontal stack
imgHorizontalStack = np.hstack((img, img))

# Vertical Stack
imgVerticalStack = np.vstack((img, img))

# show image
cv2.imshow("Hortizontal Stack Image", imgHorizontalStack)
cv2.imshow("Vertical Stack Image", imgVerticalStack)

# show the image for 5 seconds, 0 means undefinite
cv2.waitKey(10000)

# destroy all the image windows
cv2.destroyAllWindows()


"""
9.4 Write a program to read through the mbox-short.txt and figure out who has sent the greatest number of mail messages. The program looks for 'From ' lines and takes the second word of those lines as the person who sent the mail. The program creates a Python dictionary that maps the sender's mail address to a count of the number of times they appear in the file. After the dictionary is produced, the program reads through the dictionary using a maximum loop to find the most prolific committer.
"""

# Ask user to input file name.  If the input is less than 1, then default to the text file.
name = input("Enter file:")
if len(name) < 1:
    name = "mbox-short.txt"

# Open file and save data to the handle.
handle = open(name)

# Create a Dictionary using the handle
counts = dict()

# Loop through the lines of the document
for line in handle:

    # Go through each line and continue if it does not start with "From "
    if not line.startswith("From "):
        continue

    # Split the lines into words
    wds = line.split()

    # The email is always index number 1. I saved it to a friendly variable.
    emails = wds[1]

    # Go through the emails, check if the email is there, if the email is not there, add it to the dictionary, if the email is there, increment the value by 1.
    counts[emails] = counts.get(emails, 0) + 1

# Create variables that will hold the high cound and email.
hc = None
he = None

# Loop through the  for both keys and values.
# Key(k) will display emails
# Value(v) will display the count.
for k,v in counts.items() :

    # Create an if statement to search for the highest value.  If the count (or value = v) is None or greater then the high count
    if hc is None or v > hc:
        he = k # key
        hc = v # value

# Print Desired Output
print(he,hc)


def borrar(conjunto):
    try:
        n = int(input("numero a borrar (-1) para detener: "))
        while n != -1:
            if n in conjunto:
                conjunto.discard(n)
                print("numero eliminado: ", n)
            else:
                print("el numero no esta en el conjunto...")
            n = int(input("numero a borrar (-1) para detener: "))
    except ValueError:
        borrar(conjunto)

conjunto = set()
for i in range (9):
    conjunto.add(i+1)
print(conjunto)

borrar(conjunto)
print(conjunto)


# add two link list.

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

class Linklist:
    def __init__(self):
        self.start = None

    def inser_at_last(self,data):
        new_node = Node(data)
        if self.start == None:
            self.start = new_node
        else:
            temp = self.start
            while temp.next != None:
                temp = temp.next
            temp.next= new_node

    def reverse(self,head):
        curr = head
        prev = None
        while curr:
            forword = curr.next
            curr.next= prev
            prev = curr
            curr = forword
        return prev

    def lets_add(self,first,secound):
        final = Node(-1)
        tail = final
        # l1 = []
        carry = 0
        sum_ = 0

        while first != None and secound != None:
           sum_ = first.data + secound.data + carry
           digit = sum_ % 10
        #    l1.append(digit)
           tail.next = Node(digit)
           tail = tail.next
           carry = sum_ // 10
           first = first.next
           secound = secound.next

        while first != None:
            sum_ = first.data + carry
            digit = sum_ % 10
            # l1.append(digit)
            tail.next = Node(digit)
            tail = tail.next
            carry = sum_ // 10
            first = first.next

        while secound != None:
            sum_ = secound.data + carry
            digit = sum_ % 10
            # l1.append(digit)
            tail.next = Node(digit)
            tail = tail.next
            carry = sum_ // 10
            secound = secound.next

        while carry != 0:
            digit = carry % 10
            # l1.append(digit)
            tail.next = Node(digit)
            tail = tail.next
            carry = carry // 10

        final = final.next

        # print(l1)
        final = self.reverse(final)

        return final

    def add_two_lists(self,first,secound):

        first = self.reverse(first)
        secound = self.reverse(secound)

        ans = self.lets_add(first,secound)

        self.start = ans

        '''
        while first:
            print(first.data, end=" ")
            first = first.next
        print("")

        while secound:
            print(secound.data, end=" ")
            secound = secound.next
        '''

    def view_data(self):
        if self.start == None:
            print("Link list is empty.")
            return
        else:
            temp = self.start
            while temp != None:
                print(temp.data,end=" ")
                temp = temp.next
        print("")

my_list = Linklist()
my_list.inser_at_last(9)
my_list.inser_at_last(8)
my_list.inser_at_last(7)

my_list1 = Linklist()
my_list1.inser_at_last(9)
my_list1.inser_at_last(6)
my_list1.inser_at_last(5)
my_list1.inser_at_last(4)
my_list1.inser_at_last(2)

print("first list : ",my_list.view_data())
print("secound list : ",my_list1.view_data())

my_call = Linklist()

my_call.add_two_lists(my_list.start,my_list1.start)
my_call.view_data()


import st_pages
import streamlit as st
from langchain import OpenAI, PromptTemplate
from langchain.callbacks import get_openai_callback
from langchain.chains.question_answering import load_qa_chain  # type: ignore
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from PyPDF2 import PdfReader

st_pages.add_page_title()  # type: ignore

st.title("Analyze any PDF file with ChatGPT :robot_face:")
openai_key = st.secrets["OPENAI_KEY"]
upload_file = st.file_uploader("Load your own PDF file")

template = """You are an SQLite expert. Given an input question, first create a
syntactically correct SQLite query to run, then look at the results of the query and
return the answer to the input question. Unless the user specifies in the question a
specific number of examples to obtain, query for at most {top_k} results using the LIMIT
clause as per SQLite. You can order the results to return the most informative data in
the database. Never query for all columns from a table. You must query only the columns
that are needed to answer the question. Wrap each column name in double quotes (") to
denote them as delimited identifiers. Pay attention to use only the column names you
can see in the tables below. Be careful to not query for columns that do not exist.
Also, pay attention to which column is in which table.

Use the following format:

Question: Question here
SQLQuery: SQL Query to run
SQLResult: Result of the SQLQuery
Answer: Final answer here

Only use the following tables:
{table_info}

Question: {input}
"""
if upload_file is not None:
    pdf_reader = PdfReader(upload_file)
    text = ""
    for page in pdf_reader.pages:
        text += page.extract_text()

    splitter = CharacterTextSplitter(
        separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len
    )
    chunks = splitter.split_text(text)

    embeddings = OpenAIEmbeddings(client=None, openai_api_key=openai_key)

    knowledge_base = FAISS.from_texts(chunks, embeddings)  # type: ignore

    query = st.text_input(
        label="Any questions?", help="Ask any question based on the loaded file"
    )

    if query:
        docs = knowledge_base.similarity_search(query)
        prompt = PromptTemplate(input_variables=["input"], template=template)
        lang_model = OpenAI(
            openai_api_key=openai_key,
            temperature=0,
            max_tokens=300,
            client=None,
        )
        chain = load_qa_chain(lang_model, chain_type="stuff")

        with get_openai_callback() as cb:
            response = chain.run(input_documents=docs, question=query)

            st.sidebar.write(  # type: ignore
                f"Your request costs: {str(cb.total_cost)} USD"
            )
        st.write(response)  # type: ignore


#!/usr/bin/env python3
"""Cloudlens CLI
@author Michael Wan

Usage:
cloudlens [-h] {start,shutdown,config,uninstall,status} ...
cloudlens start [-h] [--yaml YAML] [--namespace NAMESPACE]
                [--labels LABELS [LABELS ...]]
                {webhook,testapp,deployment}
cloudlens shutdown [-h] [--namespace NAMESPACE]
                   [--labels LABELS [LABELS ...]] [--all-namespaces]
                   {webhook,testapp,deployment} [name]
cloudlens config [-h] --namespace NAMESPACE {key} apikey

Enables automatic Cloudlens sidecar agent injection, webhook deployment, and
easy Cloudlens API key configuration
"""

import os
import re
import argparse
import subprocess
import shlex
import json
import yaml

DIR_NAME = "cloudlens-cli"
WEBHOOK_NS = "default"

def colorize(text, color="default"):
    """Returns colorized text"""
    reset = '\033[0m'
    colormap = {
        "black": '\033[30m',
        "red": '\033[31m',
        "green": '\033[32m',
        "orange": '\033[33m',
        "blue": '\033[34m',
        "purple": '\033[35m',
        "cyan": '\033[36m',
        "lightgrey": '\033[37m',
        "darkgrey": '\033[90m',
        "lightred": '\033[91m',
        "lightgreen": '\033[92m',
        "yellow": '\033[93m',
        "lightblue": '\033[94m',
        "pink": '\033[95m',
        "lightcyan": '\033[96m',
    }
    colormap['error'] = colormap['lightred']
    colormap['success'] = colormap['green']
    colormap['warning'] = colormap['yellow']
    colormap['info'] = colormap['lightcyan']
    if color != "default" and color in colormap:
        return colormap[color] + text + reset
    return text

def log(text, color="default"):
    """Prints with color option"""
    print(colorize(text, color))

def cloudlens_cli_parser():
    """Creates argument parser"""
    parser = argparse.ArgumentParser(
        description=
        'Cloudlens CLI that facilitates webhook admission controller deployment.'
    )
    subparsers = parser.add_subparsers(help='sub-command help', dest='action')

    start_handler = subparsers.add_parser('start', help='start help')
    start_handler.add_argument(
        'object',
        choices=['webhook', 'testapp', 'deployment'],
        help='object to be acted on')
    start_handler.add_argument(
        '--yaml', dest='yaml', help='specify yaml file of deployment')
    start_handler.add_argument(
        '--namespace',
        dest='namespace',
        help='specify namespace to start deployment')
    start_handler.add_argument(
        '--labels', dest='labels', nargs='+', help='specify custom labels')

    shutdown_handler = subparsers.add_parser('shutdown', help='shutdown help')
    shutdown_handler.add_argument(
        'object',
        choices=['webhook', 'testapp', 'deployment'],
        help='object to be acted on')
    shutdown_handler.add_argument('name', nargs='?', const=None)
    shutdown_handler.add_argument(
        '--namespace',
        dest='namespace',
        help='specify namespace to shutdown deployment')
    shutdown_handler.add_argument(
        '--labels', dest='labels', nargs='+', help='specify labels of deployment(s) to shutdown')
    shutdown_handler.add_argument(
        '--all-namespaces', dest='all_namespaces', action='store_true')

    config_handler = subparsers.add_parser('config', help='config help')
    config_handler.add_argument(
        'object', choices=['key'], help='object to be acted on')
    config_handler.add_argument(
        'apikey', help='key value / file containing key')
    config_handler.add_argument('--namespace', dest='namespace', required=True)
    subparsers.add_parser('uninstall', help='uninstall help')
    subparsers.add_parser('status', help='status help')
    return parser

def handle_parse_errors(args, parser):
    """Handles errors in arguments"""
    if args.action == "start":
        if args.object == 'webhook' and "namespace" in args and args.namespace:
            parser.error(
                colorize(
                    "Namespace should not be specified for webhook.",
                    "error"))
        if args.object in ['webhook', 'testapp'] and args.yaml is not None:
            parser.error(
                colorize(
                    "YAML file should not be specified when starting webhook or testapp.",
                    "error"))
        if args.object == "deployment" and args.yaml is None:
            parser.error(
                colorize(
                    "Please specify a YAML file with the file flag to start an deployment.",
                    "error"))
    if args.action == "shutdown":
        if args.object == "deployment":
            if ("name" not in args or args.name is None) and ("labels" not in args or args.labels is None):
                parser.error(
                    colorize("Please specify either the name or the labels of the deployment to shutdown",
                             "error"))
            if "name" in args and args.name and "labels" in args and args.labels:
                parser.error(
                    colorize("Please specify only one of the options 'name' and 'label'",
                             "error"))
        if args.object in ['webhook', 'testapp'] and "name" in args and args.name:
            parser.error(
                colorize(
                    "Name should not be specified when shutting down webhook or testapp",
                    "error"))
        if args.all_namespaces and args.object == 'webhook':
            parser.error(
                colorize("Cannot use all namespace flag for webhook", "error"))
        if args.object in ['webhook', 'testapp'] and "labels" in args and args.labels:
            parser.error(
                colorize("Labels should not be specified for generic webhook or testapp.",
                    "error"))

def read_yaml(file):
    """Reads in a YAML file as specified by CLI"""
    fullpath = os.path.join(os.getcwd(), file)
    contents = None
    with open(fullpath, "r") as stream:
        try:
            contents = yaml.safe_load(stream)
        except yaml.YAMLError as err:
            log("Error upon reading %s" % file, "error")
            log(str(err), "error")
    return contents

def bash(cmd, keep_format=False, silent=False, display_err=True):
    """Method to facilitate running bash commands."""
    try:
        if keep_format:
            if not silent:
                ret = subprocess.run(cmd, shell=True)
            else:
                ret = subprocess.run(
                    cmd,
                    shell=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE)
        else:
            if not silent:
                ret = subprocess.run(" ".join(shlex.split(cmd)), shell=True)
            else:
                ret = subprocess.run(
                    " ".join(shlex.split(cmd)),
                    shell=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE)
        if silent and display_err and ret.returncode != 0:
            if ret.stderr:
                log("Error. %s" % ret.stderr.decode("utf-8").strip(), "error")
            elif ret.stdout:
                log("Error. %s" % ret.stdout.decode("utf-8").strip(), "error")
            else:
                log("Error. Reason unknown", "error")
        return ret.returncode == 0
    except Exception as err:
        log("*** Error ***", "error")
        log(str(err), "error")
        return False

def check_kubectl_installation():
    """Check whether Kubectl is installed on machine."""
    try:
        subprocess.check_output(["which", "kubectl"])
        return True
    except Exception as err:
        log("*** Error ***", "error")
        log(str(err), "error")
        return False

def get_all_namespaces():
    """Gets all namespaces"""
    try:
        ret = subprocess.check_output("kubectl get namespace", shell=True)
        ret = ret.decode("utf-8").strip().split("\n")
        for i in range(len(ret)):
            ret[i] = ret[i].split()[0]
        ret = ret[1:]
        return ret
    except Exception as err:
        log("*** Error ***", "error")
        log(str(err), "error")
        return None

def get_current_namespace():
    """Returns the current namespace name"""
    try:
        ret = subprocess.check_output(
            "kubectl config view --minify --output \
                                      'jsonpath={..namespace}'",
            shell=True)
        ret = ret.decode("utf-8")
        return ret
    except Exception as err:
        log("*** Error ***", "error")
        log(str(err), "error")
        return None

def api_config_exists(namespace):
    """Look for api secret config"""
    try:
        ret = subprocess.check_output(
            "kubectl get secrets --namespace=%s \
                                      -o json" % namespace,
            shell=True)
        ret = json.loads(ret.decode("utf-8"))
        for secret in ret["items"]:
            if secret["metadata"]["name"] == "cloudlens-config-secret":
                return True
        return False
    except Exception as err:
        log("*** Error ***", "error")
        log(str(err), "error")
        return False

def switch_namespace(namespace, silent=True):
    """Switches namespace"""
    if bash(
            "kubectl config set-context --current --namespace=%s" % namespace,
            silent=True):
        if not silent:
            log("Successfully switched to namespace %s" % namespace, "success")
        return True
    if not silent:
        log("Error upon switching to namespace %s" % namespace, "error")
    return False

def config_secret(apikey, namespace):
    """Configure API secret for given namespace"""
    if api_config_exists(namespace):
        log("Namespace key config already exists... Overwriting...", "warning")
        bash("kubectl delete secret cloudlens-config-secret", silent=True)
    create_secret_cmd = "kubectl create secret generic \
                         cloudlens-config-secret \
                         --from-literal=apikey=\"%s\" \
                         --namespace %s" % (apikey, namespace)
    if bash(create_secret_cmd, silent=True):
        log("Successfully configured key for namespace %s" % namespace,
            "success")
        return True
    log("Error upon key configuration for namespace %s" % namespace, "error")
    return False

def pods_status():
    """Gets the status of all deployed pods with cloudlens containers"""
    try:
        running = []
        ret = subprocess.check_output(
            'kubectl get pods -o=custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace \
            --all-namespaces',
            shell=True)
        ret = ret.decode("utf-8").strip().split("\n")
        for i in range(len(ret)):
            ret[i] = tuple(ret[i].split())
        ret = ret[1:]
        for pod, namespace in ret:
            try:
                containers = subprocess.check_output(
                    'kubectl get pods %s --namespace=%s -o \
                                                     jsonpath="{.spec.containers[*].image}"'
                    % (pod, namespace),
                    shell=True)
                containers = containers.decode("utf-8").split(' ')
                for container in containers:
                    if 'ixiacom/cloudlens-agent' in container:
                        running.append((pod, namespace))
                        break
            except Exception as c_err:
                log("*** Error ***", "error")
                log(str(c_err), "error")
        if running:
            log(
                "%s pods running with cloudlens containers installed:" % str(
                    len(running)), "success")
            for pod, namespace in running:
                log("\t%s (%s)" % (pod, namespace), "info")
            return len(running)
        log("No pods with cloudlens containers are running at the moment.",
            "success")
        return 0
    except Exception as p_err:
        log("*** Error ***", "error")
        log(str(p_err), "error")
        return -1

def webhook_status():
    """Check if webhook is successfully deployed"""
    namespace = get_current_namespace()
    if namespace != WEBHOOK_NS:
        log("Not in %s namespace... auto switching" % WEBHOOK_NS, "warning")
        switch_namespace(WEBHOOK_NS)
    check_exists = {
        "deployment":
        bash(
            "kubectl get deployment sidecar-injector-webhook-deployment",
            silent=True,
            display_err=False),
        "configmap":
        bash(
            "kubectl get configmap sidecar-injector-webhook-configmap",
            silent=True,
            display_err=False),
        "service":
        bash(
            "kubectl get service sidecar-injector-webhook-svc",
            silent=True,
            display_err=False),
        "mutatingwebhook":
        bash(
            "kubectl get mutatingwebhookconfiguration sidecar-injector-webhook-cfg",
            silent=True,
            display_err=False),
    }
    if namespace != WEBHOOK_NS:
        log("Switching back to namespace %s" % namespace, "warning")
        switch_namespace(namespace)
    webhook_errors = []
    for component in check_exists:
        if not check_exists[component]:
            webhook_errors.append(component)
    if webhook_errors:
        if len(webhook_errors) == 4:
            log("The webhook is not running.", "success")
        else:
            log(
                "%s errors. The following do not exist: %s" %
                (len(webhook_errors), ", ".join(webhook_errors)), "error")
        return False
    log("Webhook running with no issues.", "success")
    return True

def create_webhook():
    """Creates and deploys webhook in default namespace."""
    starting_ns = get_current_namespace()
    path_to_cur_dir = os.path.dirname(os.path.realpath(__file__))
    if starting_ns != WEBHOOK_NS:
        log("Not in namespace %s... switching" % starting_ns, "warning")
        switch_namespace(WEBHOOK_NS)
    gen_cert_cmd = "%s/deployment/webhook-create-signed-cert.sh \
                    --service sidecar-injector-webhook-svc \
                    --secret sidecar-injector-webhook-certs \
                    --namespace %s" % (path_to_cur_dir, WEBHOOK_NS)
    patch_cert_cmd = "cat %s/deployment/mutatingwebhook.yaml | \
                      %s/deployment/webhook-patch-ca-bundle.sh > \
                      %s/deployment/mutatingwebhook-ca-bundle.yaml" % \
             (path_to_cur_dir, path_to_cur_dir, path_to_cur_dir)
    apply_yamls = [
        "kubectl create -f %s/deployment/configmap.yaml" % path_to_cur_dir,
        "kubectl create -f %s/deployment/deployment.yaml" % path_to_cur_dir,
        "kubectl create -f %s/deployment/service.yaml" % path_to_cur_dir,
        "kubectl create -f %s/deployment/mutatingwebhook-ca-bundle.yaml" %
        path_to_cur_dir
    ]
    cmds = [gen_cert_cmd, patch_cert_cmd]
    cmds.extend(apply_yamls)
    ret = all([bash(cmd, silent=True) for cmd in cmds])
    if WEBHOOK_NS != starting_ns:
        log("Switching back to namespace %s" % starting_ns, "warning")
        switch_namespace(starting_ns)
    if ret:
        log("Successfully created webhook.", "success")
    else:
        log("Error upon webhook creation.", "error")

def remove_webhook():
    """Shutsdown the webhook and deletes all deployments used to configure webhook."""
    starting_ns = get_current_namespace()
    if starting_ns != WEBHOOK_NS:
        log("Not in namespace %s... switching" % WEBHOOK_NS, "warning")
        switch_namespace(WEBHOOK_NS)
    cmds = [
        "kubectl delete deployment sidecar-injector-webhook-deployment",
        "kubectl delete service sidecar-injector-webhook-svc",
        "kubectl delete configmap --all",
        "kubectl delete mutatingwebhookconfiguration --all",
    ]
    ret = all([bash(cmd, silent=True) for cmd in cmds])
    if WEBHOOK_NS != starting_ns:
        log("Switching back to namespace %s" % starting_ns, "warning")
        switch_namespace(starting_ns)
    if ret:
        log("Successfully removed webhook", "success")
    else:
        log("Error upon webhook deletion.", "error")

def start(file, labels=None, target_namespace=None):
    """Starts a deployment from a given file"""
    starting_ns = get_current_namespace()
    if target_namespace:
        if target_namespace not in get_all_namespaces():
            log("Error. Specified namespace is not a valid namespace", "error")
            return
        log("Namespace %s specified" % target_namespace, "warning")
        if target_namespace != starting_ns:
            log("Switching to target namespace",
                "warning")
            switch_namespace(target_namespace)
    else:
        log("No namespace specified. Using default", "warning")
        if starting_ns != "default":
            switch_namespace("default")
        target_namespace = "default"
    if not api_config_exists(target_namespace):
        log(
            "Warning. No API key secret stored in current namespace %s. \
            Learn more by running 'cloudlens config -h'" % target_namespace,
            "warning")
    contents = read_yaml(file)
    if not contents:
        log("Error. Could not read file %s" % file, "error")
    bash(
        "kubectl label namespace %s sidecar-injector=enabled \
         --overwrite" % target_namespace,
        silent=True)
    try:
        if 'metadata' not in contents['spec']['template']:
            contents['spec']['template']['metadata'] = {}
        meta = contents['spec']['template']['metadata']
        if labels:
            if 'labels' not in meta:
                meta['labels'] = {}
            for label in labels:
                parsed = re.split('''=(?=(?:[^'"]|'[^']*'|"[^"]*")*$)''',
                                  label)
                meta['labels'][parsed[0].strip("\'").strip(
                    '\"')] = parsed[1].strip("\'").strip('\"')
        if 'annotations' not in meta:
            meta['annotations'] = {}
        meta["namespace"] = target_namespace
        meta['annotations']['keysight.cloudlens.webhook/inject'] = "yes"
        yaml_content = yaml.dump(contents, default_flow_style=False)
        cmd = "cat <<EOF | kubectl create -f -\n" + yaml_content + "\nEOF"
        if bash(cmd, keep_format=True, silent=True):
            log("Successfully created deployment %s" % file, "success")
        else:
            log("Error upon starting deployment %s" % file, "error")
    except Exception as err:
        log("Error upon starting deployment %s" % str(err), "error")

def shutdown(name, labels=None, target_namespace=None, all_namespaces=False):
    """Shutdowns given deployment by name"""
    if target_namespace and target_namespace not in get_all_namespaces():
        log("Specified namespace is not a valid namespace", "error")
        return
    cur_namespace = get_current_namespace()
    all_ns = [target_namespace if target_namespace else "default"]
    if all_namespaces:
        log("Checking all namespaces...", "warning")
        all_ns = get_all_namespaces()
    elif target_namespace:
        log("%s specified as target namespace", "warning")
    else:
        log("No namespace specified. Using default", "warning")
    for namespace in all_ns:
        log("Checking namespace %s..." % namespace, "warning")
        if namespace != cur_namespace:
            switch_namespace(namespace)
            cur_namespace = namespace
        cmd = "kubectl delete deployment"
        if labels:
            cmd += " -l %s" % str(",".join(labels))
        elif name:
            cmd += " %s" % name
        if bash(cmd, silent=True, display_err=False):
            if name:
                log(
                    "Successfully deleted deployment with name %s in namespace %s" %
                    (name, namespace), "success")
            elif labels:
                log(
                    "Successfully deleted deployment with labels %s in namespace %s" %
                    (",".join(labels), namespace), "success")

def uninstall_cli():
    """Uninstalls the CLI and its dependencies."""
    cmds = [
        "echo 'Removing dependencies... '",
        "rm -rf ${HOME}/.%s" % DIR_NAME,
        "echo 'Success'",
        "echo ''",
        "echo 'Removing symlink...' ",
        "rm /usr/local/bin/cloudlens",
        "echo 'Success'",
        "echo ''",
    ]
    if all([bash(cmd) for cmd in cmds]):
        log("Successfully uninstalled Cloudlens CLI", "success")
    else:
        log("Error upon uninstalling CLI", "error")

def main():
    """Main function.

    Example:
        $ python cloudlens.py start webhook --apikey TESTAPIKEY
    """
    parser = cloudlens_cli_parser()
    args = parser.parse_args()

    handle_parse_errors(args, parser)

    if args.action == "uninstall":
        uninstall_cli()

    if not check_kubectl_installation():
        log(
            "Kubectl not installed. Please install by following \
            https://kubernetes.io/docs/tasks/tools/install-kubectl/", "error")
        exit()

    if args.action == "status":
        webhook_status()
        pods_status()
    if args.action == "start":
        obj = args.object
        if obj == "webhook":
            create_webhook()
        elif obj == "testapp":
            start(
                os.path.join(
                    os.getenv("HOME"), ".%s/sleep.yaml" % DIR_NAME),
                labels=args.labels,
                target_namespace=args.namespace)
        elif obj == "deployment":
            start(
                args.yaml, labels=args.labels, target_namespace=args.namespace)
    elif args.action == "shutdown":
        obj = args.object
        if obj == "webhook":
            remove_webhook()
        if obj == "testapp":
            shutdown(
                None,
                labels=["id=testapp"],
                target_namespace=args.namespace,
                all_namespaces=args.all_namespaces)
        elif obj == "deployment":
            shutdown(
                args.name,
                labels=args.labels,
                target_namespace=args.namespace,
                all_namespaces=args.all_namespaces)
    elif args.action == "config":
        obj = args.object
        if obj == "key":
            apikey = args.apikey
            namespace = args.namespace
            config_secret(apikey, namespace)

if __name__ == "__main__":
    main()


from __future__ import unicode_literals

import datetime

from django.utils.translation import ugettext as _

# Authentication and authorization
AUTH_GROUP_NAME='runplan-users'
NOPERM_TARGET='/accounts/noperm/'

# Query limits
RUNS_LIMIT=50
ACTIVITY_LIMIT=15
SHOUTS_LIMIT=10

# Timing thresholds
MEETTIME_THRESHOLD=datetime.timedelta(minutes=15)

# Email settings
EMAIL_FROM_ADDR = '<from address used for e-mail notification>'

EMAIL_SUBJECT_PREFIX = _('[runplan] ')
EMAIL_SUBJECT_TEMPLATES = {
    'run.create': _('%(user)s created new run %(run)s'),
    'run.edit': _('%(user)s edited run %(run)s'),
    'run.cancel': _('%(user)s canceled run %(run)s'),
    'run.attend': _('%(user)s attends on run %(run)s'),
    'run.revoke': _('%(user)s revokes for run %(run)s'),
    'run.transport.offer': _('%(user)s offered new transport for run %(run)s'),
    'run.transport.edit': _('%(user)s edited transport for run %(run)s'),
    'run.transport.cancel': _('%(user)s canceled transport for run %(run)s'),
    'run.transport.takeseat': _('%(user)s took seat on transport for run %(run)s'),
    'run.transport.freeseat': _('%(user)s freed seat on transport for run %(run)s'),
}

EMAIL_BODY_BACKLINK = '<url used as link to site in e-mail body>'
EMAIL_BODY_HEADER = ''
EMAIL_BODY_FOOTER = _('This is an auto-generated e-mail - please do not respond!')
EMAIL_BODY_TEMPLATES = {
    'run.create': _("""Link: %(link)s"""),
    'run.edit': _("""Link: %(link)s"""),
    'run.cancel': _("""Link: %(link)s"""),
    'run.attend': _("""Link: %(link)s"""),
    'run.revoke': _("""Link: %(link)s"""),
    'run.transport.offer': _("""Link: %(link)s"""),
    'run.transport.edit': _("""Link: %(link)s"""),
    'run.transport.cancel': _("""Link: %(link)s"""),
    'run.transport.takeseat': _("""Link: %(link)s"""),
    'run.transport.freeseat': _("""Link: %(link)s"""),
}

# Activity settings
ACTIVITY_TEXT_TEMPLATES = EMAIL_SUBJECT_TEMPLATES


from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Union, Any

from matplotlib import pyplot as plt
from numpy import ndarray, dtype, floating

from src.drawing.draw_linear_prog import DrawLinearProg
from src.drawing.draw_ose import DrawOSE

dict_profile_time = {
    ("06", "42"): "PM004A",
    ("07", "05"): "PM004D",
    ("07", "37"): "PM005A",
    ("08", "08"): "PM005D",
    ("09", "42"): "PM006A",
    ("10", "13"): "PM006D",
    ("11", "01"): "PM007A",
    ("11", "27"): "PM007D",
    ("13", "06"): "PM008A",
    ("13", "23"): "PM008D",
    ("16", "54"): "PM010A",
    ("17", "17"): "PM010D",
    ("17", "46"): "PM011A",
    ("18", "04"): "PM011D",
}

@dataclass
class DrawProfiles(DrawOSE, DrawLinearProg):
    """Class for plotting graphs after restoring profiles."""

    dataset_name: str = ("dataset_2_csv",)
    dir_profiles_name: str = "profiles_2"
    n_trials: int = 10

    def draw_ose_and_linprog(self, out_ose, out_linprog, folder_name: str) -> None:
        """Draw the profile reconstructed using OSE and LP."""
        path_out: Path = Path(Path.cwd().parent, "output", folder_name)
        path_out.mkdir(parents=True, exist_ok=True)
        for path_txt in path_out.glob("*.png"):
            try:
                path_txt.unlink()
            except OSError:
                ...
        plt.figure(figsize=(15, 12))
        for key in out_ose[0].keys():
            for k in range(2):
                plt.subplot(2, 2, k+1)
                h: ndarray[Any, dtype[floating]] = out_ose[k][key][0]
                out: tuple[
                    Union[ndarray[Any, dtype[floating]], Any]
                ] = out_ose[k][key][1]
                data_bars: tuple[list[float], list[float]] = out_ose[k][key][2]
                out_avg: ndarray[Any, dtype[floating]] = out_ose[k][key][3]
                out_er: ndarray[Any, dtype[floating]] = out_ose[k][key][4]
                sigma_1: float = out_ose[k][key][5]
                txt_path: Path = out_ose[k][key][6]
                name_height: dict[str, str] = out_ose[k][key][7]
                factor: float = out_ose[k][key][8]
                integral_mean: float = out_ose[k][key][9]
                integral_std: float = out_ose[k][key][10]
                integral_orig: float = out_ose[k][key][11]
                plt.bar(
                    x=[x_i + 25 for x_i in h],
                    height=[h_i for h_i in out[0]],
                    width=45,
                    linewidth=1,
                    edgecolor="black",
                    alpha=0.5,
                    color="red",
                    linestyle="-",
                    label="ose:one restored profile",
                )
                plt.bar(
                    x=[x_i + 25 for x_i in data_bars[0]],
                    height=[h_i * 50 for h_i in data_bars[1]],
                    width=45,
                    linewidth=1,
                    edgecolor="black",
                    alpha=0.5,
                    color="blue",
                    linestyle="-",
                    label="original profile",
                )
                plt.errorbar(
                    x=[x_i + 25 for x_i in h],
                    y=[y_i for y_i in out_avg],
                    yerr=[yerr_i for yerr_i in out_er],
                    fmt="o",
                    ecolor="black",
                    elinewidth=2.5,
                    capsize=4,
                    color="black",
                    label=f"ose:average restored n={self.n_trials}",
                )
                plt.axhline(y=50 * factor,
                            color='black',
                            linewidth=2,
                            label="priori profile")
                self.general_chart_settings(
                    info=[integral_mean, integral_std, integral_orig],
                    name_height=name_height,
                )
                print(f"ose:{txt_path.name}, {datetime.now()}")
            for k in range(2):
                plt.subplot(2, 2, k + 3)
                txt_path: Path = out_linprog[k][key][0]
                h: ndarray[Any, dtype[floating]] = out_linprog[k][key][1]
                out: tuple[
                    Union[ndarray[Any, dtype[floating]], Any]
                ] = out_linprog[k][key][2]
                out_avg: ndarray[Any, dtype[floating]] = out_linprog[k][key][3]
                out_er: ndarray[Any, dtype[floating]] = out_linprog[k][key][4]
                data_bars: tuple[list[float], list[float]] = out_linprog[k][key][5]
                sigma_1: float = out_linprog[k][key][6]
                num_max: int = out_linprog[k][key][7]
                name_height: dict[str, str] = out_linprog[k][key][8]
                integral_mean: float = out_linprog[k][key][9]
                integral_std: float = out_linprog[k][key][10]
                integral_orig: float = out_linprog[k][key][11]
                plt.bar(
                    x=[x_i + 25 for x_i in h],
                    height=[h_i for h_i in out],
                    width=45,
                    linewidth=1,
                    edgecolor="black",
                    alpha=0.5,
                    color="red",
                    linestyle="-",
                    label="ose:one restored profile",
                )
                plt.bar(
                    x=[x_i + 25 for x_i in data_bars[0]],
                    height=[h_i for h_i in data_bars[1]],
                    width=45,
                    linewidth=1,
                    edgecolor="black",
                    alpha=0.5,
                    color="blue",
                    linestyle="-",
                    label="original profile",
                )
                plt.errorbar(
                    x=[x_i + 25 for x_i in h],
                    y=[y_i for y_i in out_avg],
                    yerr=[yerr_i for yerr_i in out_er],
                    fmt="o",
                    ecolor="black",
                    elinewidth=2.5,
                    capsize=4,
                    color="black",
                    label=f"linear prog:average restored n={self.n_trials}",
                )
                self.general_chart_settings(
                    info=[integral_mean, integral_std, integral_orig],
                    name_height=name_height,
                )
            plt.savefig(
                Path(path_out, f'{key.split(".")[0]}.png'), bbox_inches="tight"
            )
            plt.figure(figsize=(15, 12))

    def calculate_pipeline(self, pipeline) -> None:
        for calc in pipeline:
            if (
                "sigma_2" in calc.keys()
                and self.dataset_name != "dataset_3_csv"
            ):
                folder_name: str = f"{self.dir_profiles_name},sigma_1={calc.get('sigma_1')},sigma_2={calc.get('sigma_2')}"
                self.draw_ose(
                    self.make_all_necessary_calculations_for_ose(
                        sigma_1=calc.get("sigma_1"),
                        sigma_2=calc.get("sigma_2"),
                    ),
                    folder_name=folder_name,
                )
            elif (
                "sigma_2" not in calc.keys()
                and self.dataset_name == "dataset_3_csv"
            ):
                folder_name: str = f"{self.dir_profiles_name},sigma_1={calc.get('sigma_1')},num_max={calc.get('num_max')}"
                self.draw_linear_prog(
                    self.make_all_necessary_calculations_for_linear_prog(
                        num_max=calc.get("num_max"),
                        sigma_1=calc.get("sigma_1"),
                    ),
                    folder_name=folder_name,
                )

    def calculate_pipeline_ose(self, pipeline):
        for calc in pipeline:
            folder_name: str = f"{self.dir_profiles_name},sigma_1={calc.get('sigma_1')},sigma_2={calc.get('sigma_2')}"
            out_results_1 = self.make_all_necessary_calculations_for_ose(sigma_1=calc.get("sigma_1"),
                                                                         sigma_2=calc.get("sigma_2"),
                                                                         h_0=50)
            out_results_2 = self.make_all_necessary_calculations_for_ose(sigma_1=calc.get("sigma_1"),
                                                                         sigma_2=calc.get("sigma_2"),
                                                                         h_0=200)
        return out_results_1, out_results_2, folder_name

    def calculate_pipeline_linprog(self, pipeline):
        for calc in pipeline:
            folder_name: str = f"{self.dir_profiles_name},sigma_1={calc.get('sigma_1')},sigma_2={calc.get('sigma_2')}"
            out_results_3 = self.make_all_necessary_calculations_for_linear_prog(num_max=1,
                                                                                sigma_1=calc.get("sigma_1"))
            out_results_4 = self.make_all_necessary_calculations_for_linear_prog(num_max=2,
                                                                                sigma_1=calc.get("sigma_1"))
        return out_results_3, out_results_4, folder_name

if __name__ == "__main__":
    n_trials = 13
    list_profiles_datasets = [
        # {"dataset_name": "dataset_3_csv", "dir_profiles_name": "profiles_1"},
        # {"dataset_name": "dataset_3_csv", "dir_profiles_name": "profiles_2"},
        # {"dataset_name": "dataset_2_csv", "dir_profiles_name": "profiles_1"},
        {"dataset_name": ["dataset_2_csv", "dataset_3_csv"], "dir_profiles_name": "profiles_2"},
    ]
    list_dictionary_of_calculations = [
        # {
        #     "sigma_1": 0,
        #     "sigma_2": 0,
        # },
        # {
        #     "sigma_1": 0.000001,
        #     "sigma_2": 0.000001,
        # },
        # {
        #     "sigma_1": 0.0001,
        #     "sigma_2": 0.0001,
        # },
        # {
        #     "sigma_1": 0.01,
        #     "sigma_2": 0.01,
        # },
        # {
        #     "sigma_1": 0.1,
        #     "sigma_2": 0.1,
        # },
        {
            "sigma_1": 0,
            "sigma_2": 0,
        }
        # {
        #     "sigma_1": 0.1,
        #     "num_max": 1,
        # },
        # {
        #     "sigma_1": 0.3,
        #     "num_max": 1,
        # },
        # {
        #     "sigma_1": 0.1,
        #     "num_max": 2,
        # },
        # {
        #     "sigma_1": 0.3,
        #     "num_max": 2,
        # },
    ]
    for p_d in list_profiles_datasets:
        obj = DrawProfiles(
            dataset_name=p_d["dataset_name"][0],
            dir_profiles_name=p_d["dir_profiles_name"],
            n_trials=n_trials,
        )
        out_results_1, out_results_2, folder_name = obj.calculate_pipeline_ose(pipeline=list_dictionary_of_calculations)
        obj = DrawProfiles(
            dataset_name=p_d["dataset_name"][1],
            dir_profiles_name=p_d["dir_profiles_name"],
            n_trials=n_trials,
        )
        out_results_3, out_results_4, folder_name = obj.calculate_pipeline_linprog(pipeline=list_dictionary_of_calculations)
        obj.draw_ose_and_linprog(out_ose=[out_results_1, out_results_2],
                                 out_linprog=[out_results_3, out_results_4],
                                 folder_name=folder_name)


import jax.numpy as np

### 2D fvm discretization
def BC_surf(BC, value, dx=None, neighbor=None):
    if BC == 0:
        return 2*value - neighbor
    if BC == 1:
        return neighbor + dx*value

def get_bound_values(f,BCs,dX):
    return [BC_surf(BCs[0][0],BCs[1][0],-dX[0],f[[0],:]),
            BC_surf(BCs[0][1],BCs[1][1],dX[0],f[[-1],:]),
            BC_surf(BCs[0][2],BCs[1][2],-dX[1],f[:,[0]]),
            BC_surf(BCs[0][3],BCs[1][3],dX[1],f[:,[-1]])]

# 2D diffusion: central difference
def diffusion(f,f_b,miu,dX):
    dif = ((np.diff(f,axis=0,append=f_b[1]) - np.diff(f,axis=0,prepend=f_b[0]))/dX[0]*dX[1] +
           (np.diff(f,axis=1,append=f_b[3]) - np.diff(f,axis=1,prepend=f_b[2]))/dX[1]*dX[0])*miu
    return dif

# 2D convection: QUICK: 3rd order upwind
def convection(f,f_b,vel_f,dX,theta = 0.25):
    u_f,v_f = vel_f
    fx = np.concatenate((f_b[0],
                    f_b[0],
                    f,
                    f_b[1],
                    f_b[1]),axis=0)
    fy = np.concatenate((f_b[2],
                        f_b[2],
                        f,
                        f_b[3],
                        f_b[3]),axis=1)

    f_face_x = (theta*(fx[1:-2,:]/2+fx[2:-1,:]/2) + (1-theta)*(3*fx[1:-2,:]/2-fx[:-3,:]/2)*(u_f>=0)
                                                  + (1-theta)*(3*fx[2:-1,:]/2-fx[3:,:]/2)*(u_f<0))
    f_face_y = (theta*(fy[:,1:-2]/2+fy[:,2:-1]/2) + (1-theta)*(3*fy[:,1:-2]/2-fy[:,:-3]/2)*(v_f>=0)
                                                  + (1-theta)*(3*fy[:,2:-1]/2-fy[:,3:]/2)*(v_f<0))
    flux = ((f_face_x[1:,:,:]*u_f[1:,:,:] - f_face_x[:-1,:,:]*u_f[:-1,:,:])*dX[1] +
            (f_face_y[:,1:,:]*v_f[:,1:,:] - f_face_y[:,:-1,:]*v_f[:,:-1,:])*dX[0] )
    return flux

# compute face velocity from cell values
##### modificaiton requried: rhie chow interpolation
def get_face_values(vel,BC_info,dX):
    vel_bc = get_bound_values(vel,BC_info,dX)
    u = np.concatenate((vel_bc[0][:,:,[0]],
                    vel[:,:,[0]],
                    vel_bc[1][:,:,[0]]),axis=0)
    u_f = (u[1:,:]+u[:-1,:])/2
    v = np.concatenate((vel_bc[2][:,:,[1]],
                        vel[:,:,[1]],
                        vel_bc[3][:,:,[1]]),axis=1)
    v_f = (v[:,1:]+v[:,:-1])/2
    return u_f,v_f

# 2D gradient: central difference
def gradient(f,f_b,dX):
    return np.concatenate(((np.diff(f,axis=0,append=f_b[1]) + np.diff(f,axis=0,prepend=f_b[0]))/dX[0]/2.,
                (np.diff(f,axis=1,append=f_b[3]) + np.diff(f,axis=1,prepend=f_b[2]))/dX[1]/2.),axis=-1)

# # assuming zero gradient at the boundary
# def gradient(p):
#     p_b = np.pad(p,((1,1),(1,1),(0,0)),mode='symmetric')
#     p_b = p_b.at[0,0,0].set(0)
# #     p_b = np.pad(p,((1,1),(1,1),(0,0)),mode='constant',constant_values=0)
#     return np.concatenate(((p_b[2:,1:-1]-p_b[:-2,1:-1])/(dX[0]*2),
#                 (p_b[1:-1,2:]-p_b[1:-1,:-2])/(dX[1]*2)),axis=-1)


#!/usr/bin/env python

import tkinter

class MyApp(tkinter.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()

        self.eintraege = ["Berlin", "London", "Moskau", "Ottawa", "Paris", "Rom", "Tokio", "Washington DC"]
        self.lb = tkinter.Listbox(master)
        self.lb.insert("end", *self.eintraege)
        self.lb.pack()

if __name__ == "__main__":
    root = tkinter.Tk()
    app = MyApp(root)
    app.mainloop()


##### import needed packages
from brian2 import *
from brian2.units.constants import zero_celsius, gas_constant as R, faraday_constant as F
import numpy as np

##### import functions
import functions.calculations as calc

# =============================================================================
# Temperature
# =============================================================================
T_celsius = 37

# =============================================================================
# Permeabilities
# =============================================================================
##### Dividing factor for permeabilities in the somatic region (makes currents smaller)
dividing_factor = 30
##### permeabilites active compartments
P_Na = 51.5*um/second
P_K = 2.0*um/second
P_KLT = 0.018*um/second
P_HCN = 0.0108*um/second
##### permeabilites somatic region
P_Na_somatic_region = P_Na / dividing_factor
P_K_somatic_region = P_K / dividing_factor
P_KLT_somatic_region = P_KLT / dividing_factor
P_HCN_somatic_region = P_HCN / dividing_factor

# =============================================================================
# Conductivities
# =============================================================================
# conductivity of leakage channels
g_L = 728*siemens/meter**2
g_L_somatic_region = g_L / dividing_factor

# =============================================================================
# Ion concentrations
# =============================================================================
Na_i = 10*mole/meter**3
Na_e = 142*mole/meter**3
K_i = 141*mole/meter**3
K_e = 4.2*mole/meter**3
C_i = 60*mole/meter**3
C_e = 15*mole/meter**3

# =============================================================================
# Resistivities
# =============================================================================
##### axoplasmatic resistivity
rho_in = 70*ohm*cm
##### external resistivity
rho_out = 300*ohm*cm

# =============================================================================
# Other parameters
# =============================================================================
##### Myelin layers soma and presomatic region
myelin_layers_somatic_region = 4

# =============================================================================
# Differential equations
# =============================================================================
eqs = '''
I_Na = P_Na*m**3*h*(v*F**2)/(R*T_kelvin) * (Na_e-Na_i*exp(v*F/(R*T_kelvin)))/(exp(v*F/(R*T_kelvin))-1) : amp/meter**2
I_K = P_K*n**2*(v*F**2)/(R*T_kelvin) * (K_e-K_i*exp(v*F/(R*T_kelvin)))/(exp(v*F/(R*T_kelvin))-1) : amp/meter**2
I_KLT = P_KLT*w**4*z*(v*F**2)/(R*T_kelvin) * (K_e-K_i*exp(v*F/(R*T_kelvin)))/(exp(v*F/(R*T_kelvin))-1) : amp/meter**2
I_HCN = P_HCN*r*(v*F**2)/(R*T_kelvin) * (C_e-C_i*exp(v*F/(R*T_kelvin)))/(exp(v*F/(R*T_kelvin))-1) : amp/meter**2
I_L = g_L*(E_Leak-(v-V_res)) : amp/meter**2
Im = I_Na + I_K + I_KLT + I_HCN + I_L + g_myelin*(-(v-V_res)): amp/meter**2
I_stim = stimulus(t,i) : amp (point current)
dm/dt = alpha_m * (1-m) - beta_m * m : 1
dn/dt = alpha_n * (1-n) - beta_n * n : 1
dh/dt = alpha_h * (1-h) - beta_h * h : 1
dw/dt = alpha_w * (1-w) - beta_w * w : 1
dz/dt = alpha_z * (1-z) - beta_z * z : 1
dr/dt = alpha_r * (1-r) - beta_r * r : 1
alpha_m = 0.49/mV*((v-V_res)-25.41*mV)/(1-exp((25.41*mV-(v-V_res))/(6.06*mV))) * 2.2**(0.1*(T_celsius-20))/ms : Hz
alpha_n = 0.02/mV*((v-V_res)-35*mV)/(1-exp((35*mV-(v-V_res))/(10*mV))) * 3**(0.1*(T_celsius-20))/ms : Hz
alpha_h = 0.09/mV*(-27.74*mV-(v-V_res))/(1-exp(((v-V_res)+27.74*mV)/(9.06*mV))) * 2.9**(0.1*(T_celsius-20))/ms : Hz
beta_m = 1.04/mV*(21*mV-(v-V_res))/(1-exp(((v-V_res)-21*mV)/(9.41*mV))) * 2.2**(0.1*(T_celsius-20))/ms : Hz
beta_n = 0.05/mV*(10*mV-(v-V_res))/(1-exp(((v-V_res)-10*mV)/(10*mV))) * 3**(0.1*(T_celsius-20))/ms : Hz
beta_h = 3.7/(1+exp((56*mV-(v-V_res))/(12.5*mV))) * 2.9**(0.1*(T_celsius-20))/ms : Hz
w_inf = 1/(exp(13/5-(v-V_res)/(6*mV))+1)**(1/4) : 1
tau_w = 0.2887 + (17.53*exp((v-V_res)/(45*mV)))/(3*exp(17*(v-V_res)/(90*mV))+15.791) : 1
alpha_w = w_inf/tau_w * 3**(0.1*(T_celsius-37))/ms : Hz
beta_w = (1-w_inf)/tau_w * 3**(0.1*(T_celsius-37))/ms : Hz
z_inf = 1/(2*(exp((v-V_res)/(10*mV)+0.74)+1))+0.5 : 1
tau_z = 9.6225 + (2073.6*exp((v-V_res)/(8*mV)))/(9*(exp(7*(v-V_res)/(40*mV))+1.8776)) : 1
alpha_z = z_inf/tau_z * 3**(0.1*(T_celsius-37))/ms : Hz
beta_z = (1-z_inf)/tau_z * 3**(0.1*(T_celsius-37))/ms : Hz
r_inf = 1/(exp((v-V_res)/(7*mV)+62/35)+1) : 1
tau_r = 50000/(711*exp((v-V_res)/(12*mV)-3/10)+51*exp(9/35-(v-V_res)/(14*mV)))+25/6 : 1
alpha_r = r_inf/tau_r * 3.3**(0.1*(T_celsius-37))/ms : Hz
beta_r = (1-r_inf)/tau_r * 3.3**(0.1*(T_celsius-37))/ms : Hz
P_Na : meter/second
P_K : meter/second
P_KLT : meter/second
P_HCN : meter/second
g_L : siemens/meter**2
g_myelin : siemens/meter**2
E_Leak : volt
V_res : volt
T_celsius : 1
T_kelvin : kelvin
Na_i : mole/meter**3
Na_e : mole/meter**3
K_i : mole/meter**3
K_e : mole/meter**3
C_i : mole/meter**3
C_e : mole/meter**3
'''

# =============================================================================
#  Morphologic data
# =============================================================================
##### structure
nof_segments_presomatic_region = 10
nof_segments_soma = 10
nof_axonal_internodes = 10 # have to be at least 5
##### lengths
length_peripheral_terminal = 10*um
length_internodes_dendrite = [175,175,175,175,175,50]*um
length_internodes_axon = [150,200,250,300,350]*um # the last value defines the lengths of further internodes
length_nodes = 1*um
length_presomatic_region = 100*um
length_soma = 30*um
##### diameters
diameter_dendrite = 3*um
diameter_somatic_region = 2*um
diameter_soma = 10*um
diameter_axon = 3*um

# =============================================================================
# Capacitivites
# =============================================================================
##### membrane capacitivity one layer (calculated with the values given in Briaire and Frijns 2005 page 146)
c_m_layer = 2.801*uF/cm**2

# =============================================================================
# Condactivities internodes
# =============================================================================
##### membrane conductivity somatic region one layer (calculated with the values given in Briaire and Frijns 2005 page 146)
g_m_layer = 0.6*msiemens/cm**2

# =============================================================================
# Noise factor
# =============================================================================
k_noise = 0.00001*uA*np.sqrt(second/um**3)

# =============================================================================
# Electrode
# =============================================================================
electrode_distance = 300*um

# =============================================================================
# Display name for plots
# =============================================================================
display_name = "Briaire and Frijns 2005 a."
display_name_short = "Briaire 05 a."

# =============================================================================
# Define inter-pulse intervalls for refractory curve calculation
# =============================================================================
inter_pulse_intervals = np.hstack([np.linspace(0.8, 0.85, num=20, endpoint = False),
                                   np.linspace(0.85, 1.3, num=15, endpoint = False),
                                   np.linspace(1.3, 5, num=15)])*1e-3

# =============================================================================
# Calculations
# =============================================================================
##### Temperature
T_kelvin = zero_celsius + T_celsius*kelvin

##### rates for resting potential
alpha_m_0 = 0.49*(-25.41)/(1-np.exp(25.41/6.06)) * 2.2**(0.1*(T_celsius-20))
alpha_n_0 = 0.02*(-35)/(1-np.exp(35/10)) * 3**(0.1*(T_celsius-20))
alpha_h_0 = 0.09*(-27.74)/(1-np.exp(27.74/9.06)) * 2.9**(0.1*(T_celsius-20))
beta_m_0 = 1.04*21/(1-np.exp(-21/9.41)) * 2.2**(0.1*(T_celsius-20))
beta_n_0 = 0.05*10/(1-np.exp(-10/10)) * 3**(0.1*(T_celsius-20))
beta_h_0 = 3.7/(1+np.exp(56/12.5)) * 2.9**(0.1*(T_celsius-20))

##### initial values for gating variables
m_init = alpha_m_0 / (alpha_m_0 + beta_m_0)
n_init = alpha_n_0 / (alpha_n_0 + beta_n_0)
h_init = alpha_h_0 / (alpha_h_0 + beta_h_0)
w_init = 1/(np.exp(13/5)+1)**(1/4)
z_init = 1/(2*(np.exp(0.74)+1))+0.5
r_init = 1/(np.exp(+62/35)+1)

##### Potentials
# Resting potential (calculated with Goldman equation)
V_res = (R*T_kelvin)/F * np.log((P_K*n_init**2*K_e + P_Na*h_init*m_init**3*Na_e + P_KLT*z_init*w_init**4*K_e + P_HCN*r_init*C_e)/
         (P_K*n_init**2*K_i + P_Na*h_init*m_init**3*Na_i + P_KLT*z_init*w_init**4*K_i + P_HCN*r_init*C_i))

# Nerst potential for leakage current
E_L = (-1/g_L)*(P_Na*m_init**3*h_init*(V_res*F**2)/(R*T_kelvin) *
             (Na_e-Na_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
             P_K*n_init**2*(V_res*F**2)/(R*T_kelvin) *
             (K_e-K_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
             P_KLT*z_init*w_init**4*(V_res*F**2)/(R*T_kelvin) *
             (K_e-K_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
             P_HCN*r_init*(V_res*F**2)/(R*T_kelvin) *
             (C_e-C_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))))

E_L_somatic_region = (-1/g_L_somatic_region)*(P_Na_somatic_region*m_init**3*h_init*(V_res*F**2)/(R*T_kelvin) *
                      (Na_e-Na_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
                      P_K_somatic_region*n_init**2*(V_res*F**2)/(R*T_kelvin) *
                      (K_e-K_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
                      P_KLT_somatic_region*z_init*w_init**4*(V_res*F**2)/(R*T_kelvin) *
                      (K_e-K_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))) +
                      P_HCN_somatic_region*r_init*(V_res*F**2)/(R*T_kelvin) *
                      (C_e-C_i*np.exp(V_res*F/(R*T_kelvin)))/(1-np.exp(V_res*F/(R*T_kelvin))))

##### structure of ANF
# structure of ANF
# terminal = 0
# internode = 1
# node = 2
# presomatic region = 3
# Soma = 4
structure = np.array([0] + list(np.tile([1,2],6)) + list(np.tile([3],nof_segments_presomatic_region)) + [2] +
                           list(np.tile([4],nof_segments_soma)) + [2] + list(np.tile([1,2],nof_axonal_internodes-1)) + [1])
# indexes presomatic region
index_presomatic_region = np.argwhere(structure == 3)
start_index_presomatic_region = int(index_presomatic_region[0])
# indexes of soma
index_soma = np.argwhere(structure == 4)
start_index_soma = int(index_soma[0])
end_index_soma = int(index_soma[-1])
# further structural data
nof_comps = len(structure)
nof_comps_dendrite = len(structure[:start_index_soma])
nof_comps_axon = len(structure[end_index_soma+1:])

#####  Compartment lengths
# initialize
compartment_lengths = np.zeros_like(structure)*um
# peripheral terminal
compartment_lengths[np.where(structure == 0)] = length_peripheral_terminal
# internodes dendrite
compartment_lengths[0:start_index_soma][structure[0:start_index_soma] == 1] = length_internodes_dendrite
# internodes axon
compartment_lengths[end_index_soma+1:][structure[end_index_soma+1:] == 1] = list(list(length_internodes_axon) +
                         list(np.tile(length_internodes_axon[-1],nof_axonal_internodes-5)))
# nodes
compartment_lengths[np.where(structure == 2)] = length_nodes
# presomatic region
compartment_lengths[np.where(structure == 3)] = length_presomatic_region/nof_segments_presomatic_region
# soma
compartment_lengths[np.where(structure == 4)] = length_soma/nof_segments_soma
# total length neuron
length_neuron = sum(compartment_lengths)

##### Compartment diameters
# initialize
compartment_diameters = np.zeros(nof_comps+1)*um
# dendrite
compartment_diameters[0:start_index_presomatic_region+1] = diameter_dendrite
dendrite_outer_diameter = diameter_dendrite / 0.6 # see Gillespie 1983
# region before soma
compartment_diameters[start_index_presomatic_region+1:start_index_soma+1] = diameter_somatic_region
# soma
compartment_diameters[start_index_soma+1:end_index_soma+1] = diameter_soma
# node after soma
compartment_diameters[end_index_soma+1] = diameter_somatic_region
# axon
compartment_diameters[end_index_soma+2:] = diameter_axon
axon_outer_diameter = diameter_axon / 0.6 # see Gillespie 1983

#####  Compartment middle point distances (needed for plots)
distance_comps_middle = np.zeros_like(compartment_lengths)
distance_comps_middle[0] = 0.5*compartment_lengths[0]
for ii in range(0,nof_comps-1):
    distance_comps_middle[ii+1] = 0.5*compartment_lengths[ii] + 0.5*compartment_lengths[ii+1]

##### Capacitivites
# initialize
c_m = np.zeros_like(structure)*uF/cm**2
# peripheral terminal and nodes
c_m[np.where(np.logical_or(structure == 0, structure == 2))] = c_m_layer
# somatic region
c_m[np.where(np.logical_or(structure == 3, structure == 4))] = c_m_layer/(1+myelin_layers_somatic_region)
# values for internodes are zero

##### Condactivities internodes
# initialize
g_m = np.zeros_like(structure)*msiemens/cm**2
# somatic region
g_m[np.where(np.logical_or(structure == 3, structure == 4))] = g_m_layer/(1+myelin_layers_somatic_region)
# values for internodes are zero

##### Axoplasmatic resistances
compartment_center_diameters = np.zeros(nof_comps)*um
compartment_center_diameters = (compartment_diameters[0:-1] + compartment_diameters[1:]) / 2
R_a = (compartment_lengths*rho_in) / ((compartment_center_diameters*0.5)**2*np.pi)

##### Surface arias
# lateral surfaces
m = [np.sqrt(abs(compartment_diameters[i+1] - compartment_diameters[i])**2 + compartment_lengths[i]**2)
           for i in range(0,nof_comps)]
# total surfaces
A_surface = [(compartment_diameters[i+1] + compartment_diameters[i])*np.pi*m[i]*0.5
           for i in range(0,nof_comps)]

##### Noise term
P_Na_vector = np.zeros(nof_comps)*0*meter/second
P_Na_vector[:] = P_Na
P_Na_vector[structure == 1] = 0*meter/second
P_Na_vector[structure == 3] = P_Na_somatic_region
P_Na_vector[structure == 4] = P_Na_somatic_region
noise_term = np.sqrt(A_surface*P_Na_vector)

##### Compartments to plot
# get indexes of all compartments that are not segmented
indexes_comps = np.where(np.logical_or(np.logical_or(structure == 0, structure == 1), structure == 2))
# calculate middle compartments of presomatic region and soma
middle_comp_presomatic_region = int(start_index_presomatic_region + np.floor((nof_segments_presomatic_region)/2))
middle_comp_soma = int(start_index_soma + np.floor((nof_segments_soma)/2))
# create array with all compartments to plot
comps_to_plot = np.sort(np.append(indexes_comps, [middle_comp_presomatic_region, middle_comp_soma]))

# =============================================================================
# Set up the model
# =============================================================================
def set_up_model(dt, model, update = False):
    """This function calculates the stimulus current at the current source for
    a single monophasic pulse stimulus at each point of time

    Parameters
    ----------
    dt : time
        Sets the defaultclock.
    model : module
        Contains all morphologic and physiologic data of a model

    Returns
    -------
    neuron
        Gives back a brian2 neuron
    model
        Gives back the whole module
    """

    start_scope()

    ##### Update model parameters (should be done, if original parameters have been changed)
    if update:
        ##### Temperature
        model.T_kelvin = model.zero_celsius + model.T_celsius*kelvin

        ##### rates for resting potential
        alpha_m_0 = 0.49*(-25.41)/(1-np.exp(25.41/6.06)) * 2.2**(0.1*(model.T_celsius-20))
        alpha_n_0 = 0.02*(-35)/(1-np.exp(35/10)) * 3**(0.1*(model.T_celsius-20))
        alpha_h_0 = 0.09*(-27.74)/(1-np.exp(27.74/9.06)) * 2.9**(0.1*(model.T_celsius-20))
        beta_m_0 = 1.04*21/(1-np.exp(-21/9.41)) * 2.2**(0.1*(model.T_celsius-20))
        beta_n_0 = 0.05*10/(1-np.exp(-10/10)) * 3**(0.1*(model.T_celsius-20))
        beta_h_0 = 3.7/(1+np.exp(56/12.5)) * 2.9**(0.1*(model.T_celsius-20))

        ##### initial values for gating variables
        model.m_init = alpha_m_0 / (alpha_m_0 + beta_m_0)
        model.n_init = alpha_n_0 / (alpha_n_0 + beta_n_0)
        model.h_init = alpha_h_0 / (alpha_h_0 + beta_h_0)

        ##### Potentials
        # Resting potential (calculated with Goldman equation)
        model.V_res = (model.R*model.T_kelvin)/model.F * np.log((model.P_K*model.n_init**2*model.K_e + model.P_Na*model.h_init*model.m_init**3*model.Na_e +
                      model.P_KLT*model.z_init*model.w_init**4*model.K_e + model.P_HCN*model.r_init*model.C_e)/
                 (model.P_K*model.n_init**2*model.K_i + model.P_Na*model.h_init*model.m_init**3*model.Na_i +
                  model.P_KLT*model.z_init*model.w_init**4*model.K_i + model.P_HCN*model.r_init*model.C_i))

        # Nerst potential for leakage current
        model.E_L = (-1/model.g_L)*(model.P_Na*model.m_init**3*model.h_init*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                     (model.Na_e-model.Na_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                     model.P_K*model.n_init**2*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                     (model.K_e-model.K_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                     model.P_KLT*model.z_init*model.w_init**4*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                     (model.K_e-model.K_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                     model.P_HCN*model.r_init*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                     (model.C_e-model.C_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))))

        model.E_L_somatic_region = (-1/model.g_L_somatic_region)*(model.P_Na_somatic_region*model.m_init**3*model.h_init*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                                     (model.Na_e-model.Na_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                                     model.P_K_somatic_region*model.n_init**2*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                                     (model.K_e-model.K_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                                     model.P_KLT_somatic_region*model.z_init*model.w_init**4*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                                     (model.K_e-model.K_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +
                                     model.P_HCN_somatic_region*model.r_init*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *
                                     (model.C_e-model.C_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))))

        ##### Potentials
        # Resting potential (calculated with Goldman equation)
        model.V_res = (model.R*model.T_kelvin)/model.F * np.log((model.P_K*model.n_init**2*model.K_e + model.P_Na*model.h_init*model.m_init**3*model.Na_e)/\
                 (model.P_K*model.n_init**2*model.K_i + model.P_Na*model.h_init*model.m_init**3*model.Na_i))

        # Nerst potential for leakage current; leakage chanels were excluded but could be added by using: g_L*(E_L-(v-V_res))
        model.E_L = (-1/model.g_L)*(model.P_Na*model.m_init**3*model.h_init*(model.V_res*model.F**2)/(model.R*model.T_kelvin) *\
                     (model.Na_e-model.Na_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))) +\
                     model.P_K*model.n_init**2*(model.V_res*F**2)/(model.R*model.T_kelvin) *\
                     (model.K_e-model.K_i*np.exp(model.V_res*model.F/(model.R*model.T_kelvin)))/(1-np.exp(model.V_res*model.F/(model.R*model.T_kelvin))))

        ##### structure of ANF
        # structure of ANF
        # terminal = 0
        # internode = 1
        # node = 2
        # presomatic region = 3
        # Soma = 4
        model.structure = np.array([0] + list(np.tile([1,2],6)) + list(np.tile([3],model.nof_segments_presomatic_region)) + [2] + \
                                   list(np.tile([4],model.nof_segments_soma)) + [2] + list(np.tile([1,2],model.nof_axonal_internodes-1)) + [1])
        # indexes presomatic region
        model.index_presomatic_region = np.argwhere(model.structure == 3)
        model.start_index_presomatic_region = int(model.index_presomatic_region[0])
        # indexes of soma
        model.index_soma = np.argwhere(model.structure == 4)
        model.start_index_soma = int(model.index_soma[0])
        model.end_index_soma = int(model.index_soma[-1])
        # further structural data
        model.nof_comps = len(model.structure)
        model.nof_comps_dendrite = len(model.structure[:model.start_index_soma])
        model.nof_comps_axon = len(model.structure[model.end_index_soma+1:])

        #####  Compartment lengths
        # initialize
        model.compartment_lengths = np.zeros_like(model.structure)*um
        # peripheral terminal
        model.compartment_lengths[np.where(model.structure == 0)] = model.length_peripheral_terminal
        # internodes dendrite
        model.compartment_lengths[0:model.start_index_soma][model.structure[0:model.start_index_soma] == 1] = model.length_internodes_dendrite
        # internodes axon
        model.compartment_lengths[model.end_index_soma+1:][model.structure[model.end_index_soma+1:] == 1] = list(list(model.length_internodes_axon) +
                         list(np.tile(model.length_internodes_axon[-1],model.nof_axonal_internodes-5)))
        # nodes
        model.compartment_lengths[np.where(model.structure == 2)] = model.length_nodes
        # presomatic region
        model.compartment_lengths[np.where(model.structure == 3)] = model.length_presomatic_region/model.nof_segments_presomatic_region
        # soma
        model.compartment_lengths[np.where(model.structure == 4)] = model.length_soma/model.nof_segments_soma
        # total length neuron
        model.length_neuron = sum(model.compartment_lengths)

        ##### Compartment diameters
        # initialize
        model.compartment_diameters = np.zeros(model.nof_comps+1)*um
        # dendrite
        model.compartment_diameters[0:model.start_index_presomatic_region+1] = model.diameter_dendrite
        # region before soma
        model.compartment_diameters[model.start_index_presomatic_region+1:model.start_index_soma+1] = model.diameter_somatic_region
        # soma
        model.compartment_diameters[model.start_index_soma+1:model.end_index_soma+1] = model.diameter_soma
        # node after soma
        model.compartment_diameters[model.end_index_soma+1] = model.diameter_somatic_region
        # axon
        model.compartment_diameters[model.end_index_soma+2:] = model.diameter_axon

        #####  Compartment middle point distances (needed for plots)
        model.distance_comps_middle = np.zeros_like(model.compartment_lengths)
        model.distance_comps_middle[0] = 0.5*model.compartment_lengths[0]
        for ii in range(0,model.nof_comps-1):
            model.distance_comps_middle[ii+1] = 0.5*model.compartment_lengths[ii] + 0.5*model.compartment_lengths[ii+1]

        ##### Capacitivites
        # initialize
        model.c_m = np.zeros_like(model.structure)*uF/cm**2
        # peripheral terminal and nodes
        model.c_m[np.where(np.logical_or(model.structure == 0, model.structure == 2))] = model.c_m_layer
        # somatic region
        model.c_m[np.where(np.logical_or(model.structure == 3, model.structure == 4))] = model.c_m_layer/(1+model.myelin_layers_somatic_region)
        # values for internodes are zero

        ##### Condactivities internodes
        # initialize
        model.g_m = np.zeros_like(model.structure)*msiemens/cm**2
        # somatic region
        model.g_m[np.where(np.logical_or(model.structure == 3, model.structure == 4))] = model.g_m_layer/(1+model.myelin_layers_somatic_region)
        # values for internodes are zero

        ##### Axoplasmatic resistances
        model.compartment_center_diameters = np.zeros(model.nof_comps)*um
        model.compartment_center_diameters = (model.compartment_diameters[0:-1] + model.compartment_diameters[1:]) / 2
        model.R_a = (model.compartment_lengths*model.rho_in) / ((model.compartment_center_diameters*0.5)**2*np.pi)

        ##### Surface arias
        # lateral surfaces
        m = [np.sqrt(abs(model.compartment_diameters[i+1] - model.compartment_diameters[i])**2 + model.compartment_lengths[i]**2)
                   for i in range(0,model.nof_comps)]
        # total surfaces
        model.A_surface = [(model.compartment_diameters[i+1] + model.compartment_diameters[i])*np.pi*m[i]*0.5
                   for i in range(0,model.nof_comps)]

        ##### Noise term
        model.P_Na_vector = np.zeros(model.nof_comps)*0*meter/second
        model.P_Na_vector[:] = model.P_Na
        model.P_Na_vector[model.structure == 1] = 0*meter/second
        model.P_Na_vector[model.structure == 3] = model.P_Na/model.dividing_factor
        model.P_Na_vector[model.structure == 4] = model.P_Na/model.dividing_factor
        model.noise_term = np.sqrt(model.A_surface*model.P_Na_vector)

        ##### Compartments to plot
        # get indexes of all compartments that are not segmented
        model.indexes_comps = np.where(np.logical_or(np.logical_or(model.structure == 0, model.structure == 1), model.structure == 2))
        # calculate middle compartments of presomatic region and soma
        model.middle_comp_presomatic_region = int(model.start_index_presomatic_region + np.floor((model.nof_segments_presomatic_region)/2))
        model.middle_comp_soma = int(model.start_index_soma + np.floor((model.nof_segments_soma)/2))
        # create array with all compartments to plot
        model.comps_to_plot = np.sort(np.append(model.indexes_comps, [model.middle_comp_presomatic_region, model.middle_comp_soma]))

    ##### initialize defaultclock
    defaultclock.dt = dt

    ##### define morphology
    morpho = Section(n = model.nof_comps,
                     length = model.compartment_lengths,
                     diameter = model.compartment_diameters)

    ##### define neuron
    neuron = SpatialNeuron(morphology = morpho,
                           model = model.eqs,
                           Cm = model.c_m,
                           Ri = model.rho_in,
                           method="exponential_euler")

    ##### initial values
    neuron.v = model.V_res
    neuron.m = model.m_init
    neuron.n = model.n_init
    neuron.h = model.h_init
    neuron.w = model.w_init
    neuron.z = model.z_init
    neuron.r = model.r_init

    ##### Set parameter values of differential equations
    # permeabilities peripheral terminal and active compartments
    neuron.P_Na[np.asarray(np.where(np.logical_or(model.structure == 0, model.structure == 2)))] = model.P_Na
    neuron.P_K[np.asarray(np.where(np.logical_or(model.structure == 0, model.structure == 2)))] = model.P_K
    neuron.P_KLT[np.asarray(np.where(np.logical_or(model.structure == 0, model.structure == 2)))] = model.P_KLT
    neuron.P_HCN[np.asarray(np.where(np.logical_or(model.structure == 0, model.structure == 2)))] = model.P_HCN
    neuron.g_L[np.asarray(np.where(np.logical_or(model.structure == 0, model.structure == 2)))] = model.g_L

    # permeabilities internodes
    neuron.P_Na[np.asarray(np.where(model.structure == 1))] = 0*meter/second
    neuron.P_K[np.asarray(np.where(model.structure == 1))] = 0*meter/second
    neuron.P_KLT[np.asarray(np.where(model.structure == 1))] = 0*meter/second
    neuron.P_HCN[np.asarray(np.where(model.structure == 1))] = 0*meter/second
    neuron.g_L[np.asarray(np.where(model.structure == 1))] = 0*siemens/meter**2

    # conductances
    neuron.g_myelin = model.g_m

    # permeabilities presomatic region
    neuron.P_Na[index_presomatic_region] = model.P_Na_somatic_region
    neuron.P_K[index_presomatic_region] = model.P_K_somatic_region
    neuron.P_KLT[index_presomatic_region] = model.P_KLT_somatic_region
    neuron.P_HCN[index_presomatic_region] = model.P_HCN_somatic_region
    neuron.g_L[index_presomatic_region] = model.g_L_somatic_region

    # permeabilities soma
    neuron.P_Na[index_soma] = model.P_Na_somatic_region
    neuron.P_K[index_soma] = model.P_K_somatic_region
    neuron.P_KLT[index_soma] = model.P_KLT_somatic_region
    neuron.P_HCN[index_soma] = model.P_HCN_somatic_region
    neuron.g_L[index_soma] = model.g_L_somatic_region

    # Nernst potential for leakage current
    neuron.E_Leak = model.E_L
    neuron.E_Leak[index_presomatic_region] = E_L_somatic_region
    neuron.E_Leak[model.index_soma] = E_L_somatic_region

    # other parameters
    neuron.V_res = model.V_res
    neuron.T_celsius = model.T_celsius
    neuron.T_kelvin = model.T_kelvin
    neuron.Na_i = model.Na_i
    neuron.Na_e = model.Na_e
    neuron.K_i = model.K_i
    neuron.K_e = model.K_e
    neuron.C_i = model.C_i
    neuron.C_e = model.C_e

    return neuron, model


import numpy as np
import matplotlib.pyplot as plt
from agents.agent import OUNoise
from mpl_toolkits.mplot3d import Axes3D

def plot_trajectory(task, ep_to_plot, pos_all, xmax=150, ymax=150, zmin=0, zmax=300, ax=None):
    """
    plot trajectories of given episodes

    ep_to_plot: list, episodes to plot
    pos_all: numpy array, shape (num_ep, max_t, 3), x, y, z positions
    xmax: x axis limits for plotting, [-xmax, xmax]
    ymax: y axis limits for plotting, [-ymax, ymax]
    zmin, zmax: z axis limits for plotting, [zmin, zmax]
    ax: plot on a specified ax (for subplot)
    """

    cmaps = ['Greens', 'Purples', 'Oranges', 'Blues', 'Reds',
             'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu',
             'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', 'YlGn',
             'viridis', 'plasma', 'inferno', 'magma', 'cividis',
             'binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink',
             'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia',
             'hot', 'afmhot', 'gist_heat', 'copper']

    xt, yt, zt = task.target_pos
    x0, y0, z0 = task.sim.init_pose[:3]

    if ax is None:
        fig = plt.figure(figsize=(6, 5))
        ax = plt.subplot(111, projection='3d')

    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    if len(ep_to_plot) == 1:
        ax.set_title("Trajectory of the trained agent, \n initial: {}, target: {}".\
                 format([int(x0), int(y0), int(z0)], [int(xt), int(yt), int(zt)]))
    else:
        ax.set_title("Trajectories of episode {} to {}, \n initial: {}, target: {}".\
                     format(ep_to_plot[0]+1, ep_to_plot[-1]+1,
                            [int(x0), int(y0), int(z0)], [int(xt), int(yt), int(zt)]))
    ax.set_xlim(-xmax, xmax)
    ax.set_ylim(-ymax, ymax)
    ax.set_zlim(zmin, zmax)
    for ii, ep in enumerate(ep_to_plot):
        xs = pos_all[ep, :, 0]
        ys = pos_all[ep, :, 1]
        zs = pos_all[ep, :, 2]
        xs = xs[np.isfinite(xs)]
        ys = ys[np.isfinite(ys)]
        zs = zs[np.isfinite(zs)]
        ax.plot3D(xs, ys, zs, 'gray') # line
        ax.scatter(xs, ys, zs, c=zs, cmap='GnBu')

def plot_test_results(task, results):
    """
    plot testing results, one episode

    results: output from ddpg_agent.test()
    """
    plt.figure(figsize=(14, 3))
    plt.subplot(151)
    plt.title("target_pos={}".format(task.target_pos))
    plt.plot(results['time'], results['x'], label='x')
    plt.plot(results['time'], results['y'], label='y')
    plt.plot(results['time'], results['z'], label='z')
    plt.legend()
    plt.xlabel("time, s")

    plt.subplot(152)
    plt.title("velocity, m/s")
    plt.plot(results['time'], results['x_velocity'], label='v_x')
    plt.plot(results['time'], results['y_velocity'], label='v_y')
    plt.plot(results['time'], results['z_velocity'], label='v_z')
    plt.legend()
    plt.xlabel("time, s")

    plt.subplot(153)
    plt.title("Euler angles")
    plt.plot(results['time'], results['phi'], label='phi')
    plt.plot(results['time'], results['theta'], label='theta')
    plt.plot(results['time'], results['psi'], label='psi')
    plt.legend()
    plt.xlabel("time, s")

    plt.subplot(154)
    plt.title("angular velocity")
    plt.plot(results['time'], results['phi_velocity'], label='v_phi')
    plt.plot(results['time'], results['theta_velocity'], label='v_theta')
    plt.plot(results['time'], results['psi_velocity'], label='v_psi')
    plt.legend()
    plt.xlabel("time, s")

    plt.subplot(155)
    plt.title("roter speed, rps")
    plt.plot(results['time'], results['rotor_speed1'], label='rotor 1')
    plt.plot(results['time'], results['rotor_speed2'], label='rotor 2')
    plt.plot(results['time'], results['rotor_speed3'], label='rotor 3')
    plt.plot(results['time'], results['rotor_speed4'], label='rotor 4')
    plt.legend()
    plt.xlabel("time, s")

    plt.tight_layout()
    plt.show()


#
# 災害画像と非災害画像の名前を連番に変更する
#

import glob
import os

# ディレクトリがdisasterとnon_disasterなので，これをループするようにする
prefix_name = ["", "non_"]

for pre in prefix_name:
    path = "../disaster_decision/" + pre + "disaster/*"

    # ファイル名を取得(lsと同じ)
    files = glob.glob(path)
    #print(files)

    basename = pre + "disasterIMG_"

    ct = 0
    for filename in files:

        print(filename)

        # ファイル名と拡張子に分ける
        root, ext = os.path.splitext(filename)

        # 拡張子をすべて小文字にする（例：JPG -> jpg）
        ext = ext.lower()

        # リネームする
        new_filename = path[:-1] + basename + str(ct) + ext
        #print(new_filename)
        os.rename(filename, new_filename)

        ct += 1

    print("")
    print("[%s] is finished!"%(pre))