"""
.. index:: Extensions; index_styling

==============================
PSphinxTheme.ext.index_styling
==============================

Overview
========
**improves css styling for genindex**

This Sphinx extension intercepts & modifies the general index data before it is rendered to html, adding some additional css
classes to help *P-SphinxTheme* (e.g. :doc:`/main_theme`) provide additional per-type styling for index entries.

Internals
=========
This extension adds the following css classes to ``genindex.html``:

- For all entries referencing an ``attribute``, ``method``, ``class``, ``function``, or ``module``:

  - The text containing the type of the entry (e.g. ``attribute`` or ``method``) is wrapped in a

   :samp:`<span class="category {type}">...</span>` tag.

  - If the entry contains a location (e.g. ``myclass in module myapp``), the ``myapp`` portion is wrapped in a

   ``...`` tag.

- Entries which don't fit into one of the above categories are not modified.

"""
from re import (
   compile as re_compile,
)

# noinspection PyPep8Naming
from jinja2 import (
   escape,
   Markup as literal,
)

prefix = r'^(?P<name>.*)\('
suffix = r'\)$'
_attr_re = re_compile(prefix + r'(?P<left>)(?P<loc>.*)(?P<right> attribute)' + suffix)
_meth_re = re_compile(prefix + r'(?P<left>)(?P<loc>.*)(?P<right> method)' + suffix)
_fc_re = re_compile(prefix + r'(?P<left>class in |in module )(?P<loc>.*)(?P<right>)' + suffix)
_mod_re = re_compile(prefix + r'module' + suffix)

def format_index_name(name):
   """ format_index_name

   :param name:
   :return:
   """
   loc = ''
   type_ = ''
   left = ''
   right = ''
   while True:
      m = _attr_re.match(name)
      if m:
         name, left, loc, right = m.group('name', 'left', 'loc', 'right')
         type_ = 'attribute'
         break
      m = _meth_re.match(name)
      if m:
         name, left, loc, right = m.group('name', 'left', 'loc', 'right')
         type_ = 'method'
         break
      m = _fc_re.match(name)
      if m:
         name, left, loc, right = m.group('name', 'left', 'loc', 'right')
         if left.startswith('class'):
            type_ = 'class'
         else:
            type_ = 'function'
         break
      m = _mod_re.match(name)
      if m:
         name = m.group('name')
         left = 'module'
         loc = right = ''
         type_ = 'module'
         break
      return name
   if loc:
      loc = literal('') + escape(loc) + literal('')
   cat = left + loc + right
   return escape(name) + literal('') + escape(cat) + literal('')

# noinspection PyUnusedLocal
def mangle_index(app, pagename, templatename, ctx, event_arg):
   """ mangle_index

   :param app:
   :param pagename:
   :param templatename:
   :param ctx:
   :param event_arg:
   :return:
   """
   if pagename != 'genindex':
      return
   fmt = format_index_name
   for key, entries in ctx['genindexentries']:
      for idx, entry in enumerate(entries):
         name, (links, subitems) = entry
         entries[idx] = fmt(name), (links, subitems)
         for idx_, entry_ in enumerate(subitems):
            name, links = entry_
            subitems[idx_] = fmt(name), links

def setup(app):
   """ register extension
   """
   app.connect('html-page-context', mangle_index)


from pathlib import Path
import matplotlib.pyplot as plt

import numpy as np
import tensorflow as tf
import keras
from keras import Model
from tensorflow.keras import backend as K
from tensorflow.keras.utils import load_img, img_to_array, save_img
from keras.applications import VGG19
from keras.applications.vgg19 import preprocess_input

from utils import deprocess_image, save_animation

# Load images
content_image_path = Path('data') / 'src' / 'content' / 'autumn_road.jpg'
style_image_path = Path('data') / 'src' / 'style' / 'waves.jpg'
output_folder = Path('data') / 'output'

original_width, original_height = keras.utils.load_img(content_image_path).size
print(original_width, original_height)

img_height = 300
img_width = round(original_width * img_height / original_height)
print(img_width, img_height)

base_image = img_to_array(load_img(content_image_path, target_size=(img_height, img_width), interpolation='bicubic'))
style_image = img_to_array(load_img(style_image_path, target_size=(img_height, img_width), interpolation='bicubic'))

fig, ax = plt.subplots(1, 2, figsize=(12, 5))
ax[0].imshow(base_image / 255.0)
ax[0].axis('off')
ax[0].set_title('Base Image')
ax[1].imshow(style_image / 255.0)
ax[1].axis('off')
ax[1].set_title('Style Image')

fig.show()

# Define VGG model
vgg = VGG19(weights='imagenet', include_top=False)
output_dict = {layer.name: layer.output for layer in vgg.layers}
model = Model(inputs=vgg.input, outputs=output_dict)

def content_loss_fn(base_features, combined_features):
    """Compute MSE loss between `base_features` and `combined_features`"""
    return tf.reduce_sum(tf.square(base_features - combined_features))

def variance_loss_fn(img):
    height, width = img.shape[1:3]
    a = tf.square(img[:, height - 1, :width - 1, :] - img[:, 1:, :width - 1, :])
    b = tf.square(img[:, height - 1, :width - 1, :] - img[:, :height - 1, 1:, :])

    return tf.reduce_sum(a + b)

def style_loss_fn(style_img, combined_img):
    def gram_matrix(feature_matrix):
        flattened_feature_matrix = K.batch_flatten(K.permute_dimensions(feature_matrix, (2, 0, 1)))
        gram = K.dot(flattened_feature_matrix, K.transpose(flattened_feature_matrix))
        return gram

    style_img_gram_matrix = gram_matrix(style_img)
    combined_img_gram_matrix = gram_matrix(combined_img)

    return tf.reduce_sum(tf.square(style_img_gram_matrix - combined_img_gram_matrix))

# Parameters
content_loss_weight = 1e-5
style_loss_weight = 2.5e-3
variance_loss_weight = 1e-6

init_methods = ['content', 'style', 'noise']
reconstruction_types = ['content', 'style', 'both']

init_method = 'content'  # One of 'content', 'style' or 'noise'
reconstruction_type = 'both'  # One of 'content', 'style' or 'both'
epochs = 2000
num_epochs_per_save = 100
learning_rate = 2.0

style_feature_layers = ['block1_conv1', 'block2_conv1', 'block3_conv1', 'block4_conv1', 'block5_conv1']
content_feature_layer = 'block2_conv2'

base_image_tensor = preprocess_input(np.expand_dims(base_image.copy(), axis=0))
style_image_tensor = preprocess_input(np.expand_dims(style_image.copy(), axis=0))

if init_method not in init_methods:
    raise ValueError('Initialization method {init_method} not supported, choose one of {*init_methods}')

if reconstruction_type not in reconstruction_types:
    raise ValueError('Reconstructing {reconstruction_type} not supported, choose one of {*reconstruction_methods}')

if init_method == 'content':
    combined_image_tensor = tf.Variable(base_image_tensor.copy())
elif init_method == 'noise':
    combined_image_tensor = tf.Variable(np.random.random(base_image_tensor.shape), dtype=np.float32)
else:
    combined_image_tensor = tf.Variable(style_image_tensor.copy())

content_losses = []
style_losses = []
variance_losses = []

total_losses = []

optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate, beta_1=0.5)

for epoch in range(epochs + 1):
    with tf.GradientTape() as tp:
        input_tensor = tf.concat([base_image_tensor, style_image_tensor, combined_image_tensor], 0)
        features = model(input_tensor)

        content_features_base_image = features[content_feature_layer][0]
        content_features_combined_image = features[content_feature_layer][2]

        content_loss = content_loss_weight * content_loss_fn(content_features_base_image, content_features_combined_image)

        style_loss = 0.0
        for layer in style_feature_layers:
            style_features_style_image = features[layer][1]
            style_features_combined_image = features[layer][2]
            channels = 3
            size = img_height * img_width
            style_loss_l = style_loss_fn(style_features_style_image, style_features_combined_image)
            style_loss_l = style_loss_l / (4.0 * (channels ** 2) * (size ** 2))
            style_loss += style_loss_l / (len(style_feature_layers))

        style_loss = style_loss_weight * style_loss

        variance_loss = variance_loss_fn(combined_image_tensor)
        variance_loss = variance_loss_weight * variance_loss

        content_losses.append(content_loss)
        style_losses.append(style_loss)
        variance_losses.append(variance_loss)

        if reconstruction_type == 'content':
            total_loss = content_loss
        elif reconstruction_type == 'style':
            total_loss = style_loss
        else:
            total_loss = content_loss + style_loss + variance_loss

        total_losses.append(total_loss.numpy())

    print(f"[Epochs: {epoch}/{epochs}] Total loss: {total_loss:.2f}, content loss: {content_loss:.2f}, style loss: {style_loss:.4f}, variance loss: {variance_loss:.2f}")
    grad = tp.gradient(total_loss, combined_image_tensor)
    optimizer.apply_gradients([(grad, combined_image_tensor)])

    # Apply Gradients
    if epoch % num_epochs_per_save == 0:
        # Save combined image
        combined_image = combined_image_tensor.numpy()[0]
        combined_image = deprocess_image(combined_image)
        fname = output_folder / f"{content_image_path.stem}_and_{style_image_path.stem}" / reconstruction_type / f'regenerate__{epoch:04}.png'
        fname.parent.mkdir(parents=True, exist_ok=True)
        save_img(fname, combined_image)

save_animation(output_folder, content_image_path, style_image_path, reconstruction_type)

fig, ax = plt.subplots(2, 2, figsize=(10, 10))
ax[0, 0].plot(np.log10(total_losses), '-.')
ax[0, 0].set_title('Total loss')
ax[0, 1].plot(np.log10(content_losses[1:]), '-.')
ax[0, 1].set_title('Content Loss')
ax[1, 0].plot(np.log10(style_losses), '-.')
ax[1, 0].set_title('Style Loss')
ax[1, 1].plot(np.log10(variance_losses), '-.')
ax[1, 1].set_title('Total variance loss')

fig.suptitle('Training losses', fontsize=15)

fig.savefig(output_folder / f"{content_image_path.stem}_and_{style_image_path.stem}" / reconstruction_type / 'training_losses.png')


from time import sleep
from django.core.management.base import BaseCommand
from smm.models import Newsletter
from datetime import datetime, timedelta

class Command(BaseCommand):
    def handle(self, *args, **options):
        news = Newsletter.objects.all()
        today = datetime.now().date()
        for new in news:
            last = new.logs.all().order_by('-last_attempt').first()
            if last and last.last_attempt.date() + timedelta(days=new.frequency) > today:
                send(new)
            sleep(5)

def send(newsletter):
    print(f"Отправка рассылки для {newsletter}")


'''
Created on 10.10.2016

@author: michael
'''
import unittest
from injector import Injector
from alex_test_utils import TestEnvironment, MODE_SIMPLE,\
    load_table_data
from alexandriabase import AlexBaseModule
from alexandriabase.daos import DaoModule
from alexplugins.systematic.tkgui import SystematicGuiPluginModule
from alexplugins.systematic import SYSTEMATIC_DAO_KEY, SYSTEMATIC_SERVICE_KEY,\
    SYSTEMATIC_PDF_GENERATION_SERVICE_KEY

class TestDaoModuleConfiguration(unittest.TestCase):

    def setUp(self):
        self.env = TestEnvironment(mode=MODE_SIMPLE)

    def tearDown(self):
        self.env.cleanup()

    def test_configuration(self):

        injector = Injector([
                        AlexBaseModule(),
                        DaoModule(),
                        SystematicGuiPluginModule()
                         ])

        injector.get(SYSTEMATIC_DAO_KEY)
        injector.get(SYSTEMATIC_SERVICE_KEY)
        injector.get(SYSTEMATIC_PDF_GENERATION_SERVICE_KEY)

if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()


from datetime import date
from dateutil.relativedelta import relativedelta

class Timing:

    def calc_growth_begin_date(
        self,
        growth_begin_month: int,
        analysis_start_date: date
    ) -> date:
        return analysis_start_date+relativedelta(months=growth_begin_month-1)

    def __init__(
        self,
        analysis_length_years: int,
        analysis_start_date: date,
        growth_begin_month: int,
        residual_months: int=12
    ):
        self.analysis_length_years = analysis_length_years
        self.analysis_length_months = analysis_length_years * 12

        self.analysis_start_date = analysis_start_date
        self.analysis_start_month = 1
        self.residual_months = residual_months

        self.growth_begin_month = growth_begin_month
        self.growth_begin_date = self.calc_growth_begin_date(growth_begin_month, analysis_start_date)

    def json(self):
        return self.__dict__


"""
Sum of all Subarrays
https://www.geeksforgeeks.org/sum-of-all-subarrays/
"""
from typing import List
from test_tool import assert_value

class Solution:
    def subarraySum(self, arr: List[int]) -> int:
        res = 0
        n = len(arr)
        for i in range(n):
            res += (i + 1) * (n - i) * arr[i]

        return res

    def _subarraySum_brute_force(self, arr: List[int]) -> int:
        res = 0
        n = len(arr)
        for start in range(n):
            curr = 0
            for end in range(start, n):
                curr += arr[end]
                res += curr
        return res

assert_value(20, Solution().subarraySum, arr=[1, 2, 3])


import sys
from contextlib import suppress
from datetime import date
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from decimal import Decimal
from enum import Enum
from typing import Any
from typing import Callable
from typing import Mapping
from typing import Type
from typing import TypeVar

import cattr
import dateutil.parser
from attr import fields
from pytimeparse.timeparse import timeparse  # type: ignore
from typing_extensions import get_args

T = TypeVar("T")  # pylint: disable=invalid-name
NoneType = type(None)

class ReversedEnum(Enum):
    ...

class StructureError(ValueError):
    pass

class PEP563NotImplementedError(StructureError, NotImplementedError):
    pass

class Converter(cattr.Converter):
    """cattrs converter patched to correctly load complex attrs structures.

    Keep in mind that __future__.annotations import is not supported when using this class!
    """

    def __init__(self):
        super().__init__()

        self.register_structure_hook(Decimal, self._structure_decimal)
        self.register_unstructure_hook(Decimal, self._unstructure_decimal)

        self.register_structure_hook(NoneType, lambda obj, cls: obj)

        self.register_structure_hook(datetime, self._structure_datetime)
        self.register_unstructure_hook(datetime, self._unstructure_datetime)
        self.register_structure_hook(date, self._structure_date)
        self.register_unstructure_hook(date, self._unstructure_date)
        self.register_structure_hook(timedelta, self._structure_timedelta)
        self.register_unstructure_hook(timedelta, self._unstructure_timedelta)
        self.register_structure_hook(ReversedEnum, self._structure_reversed_enum)
        self.register_unstructure_hook(ReversedEnum, self._unstructure_reversed_enum)

    def structure_attrs_fromdict(self, obj: Mapping, cl: Type[T]) -> T:
        """Instantiate an attrs class from a mapping.

        Raises human-readable StructureError exceptions on failure.
        """
        try:
            # self._eval_str_types(cl)
            return super().structure_attrs_fromdict(obj or {}, cl)
        # NOTE: If exception has occurred while structuring nested attrs class raise it directly without further processing
        except StructureError:
            raise
        except Exception as exc:
            last_frame_locals = sys.exc_info()[2].tb_next.tb_frame.f_locals  # type: ignore
            human_class = last_frame_locals["cl"].__qualname__

            if isinstance(exc, TypeError) and "required keyword-only" in str(exc):
                exc_message = " ".join(str(exc).split()[1:])
                message = f"Cannot structure {human_class}: {exc_message}"
            else:
                value = last_frame_locals["val"]
                try:
                    human_type = last_frame_locals["a"]["type"].__name__
                except (KeyError, TypeError, AttributeError):
                    human_type = str(last_frame_locals["a"].type)
                message = f"Cannot structure {human_class}: {value} is not an instance of {human_type}"

            raise StructureError(message) from exc

    @classmethod
    def _eval_str_types(cls, attrs_class: Type[T]) -> None:
        """Evaluate Attribute.type from string annotations.

        When using attr.dataclass(kw_only=True) decorator attrs set type of generated Optional attribs to their string
        representations making impossible for cattrs to correctly structure them. This class fixes this issue evaluating
        strings back into Type objects before structuring.
        """
        for attrib in attrs_class.__attrs_attrs__:  # type: ignore
            if isinstance(attrib.type, str):
                try:
                    object.__setattr__(attrib, "type", eval(attrib.type))  # pylint: disable=eval-used
                except NameError as exc:
                    raise PEP563NotImplementedError("`Postponed Evaluation of Annotations is not supported") from exc

    @staticmethod
    def _get_dis_func(union: Type) -> Callable[..., Type]:
        """Fetch or try creating a disambiguation function for a Union.

        This algorithm is more strict than default Converter"s one and will fail if data contains redundant attributes.
        However lots of complex edge cases are covered.
        """
        union_types = get_args(union)
        if NoneType in union_types:  # type: ignore
            union_types = tuple(e for e in union_types if e is not NoneType)  # type: ignore

        if not all(hasattr(e, "__attrs_attrs__") for e in union_types):
            raise StructureError(
                f"Cannot structure {union}: only unions of attr classes are supported currently. Register a structure hook manually."
            )

        if len(union_types) < 2:
            raise StructureError(f"Cannot structure {union}: at least two classes required.")

        cls_and_attrs = [(cl, {at.name for at in fields(cl)}) for cl in union_types]

        if len([attrs for _, attrs in cls_and_attrs if len(attrs) == 0]) > 1:
            raise StructureError(f"Cannot structure {union}: at least two classes have no attributes.")

        cls_and_attrs.sort(key=lambda c_a: len(c_a[1]))

        def _dis_func(data: Mapping) -> Type:
            if not isinstance(data, Mapping):
                raise StructureError(f"Cannot structure {union}: only mappings are supported as input.")
            for cls, cls_keys in cls_and_attrs:
                if all([data_key in cls_keys for data_key in data]):
                    return cls
            raise StructureError(f"Cannot structure {union}: {data} does not match any of generic arguments")

        return _dis_func

    @staticmethod
    def _structure_decimal(obj: Any, cls: Type) -> Decimal:
        return cls(str(obj))

    @staticmethod
    def _unstructure_decimal(obj: Decimal) -> str:
        return str(obj)

    @staticmethod
    def _structure_datetime(obj: Any, cls: Type) -> datetime:  # pylint: disable=unused-argument
        with suppress(ValueError, TypeError):
            return datetime.utcfromtimestamp(float(obj)).replace(tzinfo=timezone.utc)
        with suppress(dateutil.parser.ParserError):
            return dateutil.parser.parse(obj)
        raise ValueError

    @staticmethod
    def _unstructure_datetime(obj: datetime) -> float:
        return obj.timestamp()

    @staticmethod
    def _structure_date(obj: Any, cls: Type) -> date:  # pylint: disable=unused-argument
        with suppress(ValueError, TypeError):
            return date.fromtimestamp(float(obj))
        with suppress(dateutil.parser.ParserError):
            dt = dateutil.parser.parse(obj)  # pylint: disable=invalid-name
            return date(year=dt.year, month=dt.month, day=dt.day)
        raise ValueError

    @staticmethod
    def _unstructure_date(obj: date) -> float:
        return datetime(obj.year, obj.month, obj.day, tzinfo=timezone.utc).timestamp()

    @staticmethod
    def _structure_timedelta(obj: Any, cls: Type) -> timedelta:  # pylint: disable=unused-argument
        with suppress(ValueError, TypeError):
            return timedelta(seconds=int(obj))
        with suppress(TypeError):
            return timedelta(seconds=timeparse(obj))
        raise ValueError

    @staticmethod
    def _unstructure_timedelta(obj: timedelta) -> float:
        return obj.total_seconds()

    @staticmethod
    def _structure_reversed_enum(obj: str, cls: Type[ReversedEnum]) -> ReversedEnum:
        return cls[obj]

    @staticmethod
    def _unstructure_reversed_enum(obj: ReversedEnum) -> str:
        return obj.name


from collections import defaultdict

"""
Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Example 2:

Input: strs = [""]
Output: [[""]]
Example 3:

Input: strs = ["a"]
Output: [["a"]]

Constraints:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] consists of lowercase English letters.
"""

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        # setup a hashmap with the default values being a list
        res = defaultdict(list)

        # for each string in the list of strings
        for s in strs:
            # setup a count array representing each letter in the alphabet
            count = [0] * 26
            # for each character in the string
            for c in s:
                # get the ascii value of the character subtract it from the ascii value of a and that gives us our index for the count array
                # then each time a letter appears increment the value in the array by 1
                count[ord(c) - ord("a")] +=  1

                # Ex. a -> 80 - 80 = 0 so a is the first index so on so fourth
                # then index 0 == "a" = 1 or count[0] = 1

            # then after the count is created for each string make the count array a tuple because arrays can't be keys then append the string to the array in the hashmap
            res[tuple(count)].append(s)

        # finally return the values in the hashmap
        return res.values()


import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn.decomposition import NMF

# Enable oneDNN optimization
TF_ENABLE_ONEDNN_OPTS=1

# List of GPUs set up for acceleration
print("Num GPUs Available: ", len(tf.config.experimental.list_physical_devices('GPU')))

# Seed for reproducibility
np.random.seed(5)

# Loading TCGA-BRCA data
data_matrix = pd.read_csv("../Data/TCGA_BRCA_0toAvg.csv", index_col=0)
data_tensor = tf.constant(data_matrix, dtype=tf.float32)

# NMF function
def compute_nmf(data, rank, max_iter=200, lr=0.01):
    rows, cols = data.shape
    W = tf.Variable(tf.abs(tf.random.normal((rows, rank))), dtype=tf.float32)
    H = tf.Variable(tf.abs(tf.random.normal((rank, cols))), dtype=tf.float32)
    optimizer = tf.optimizers.Adam(lr)

    for iteration in range(max_iter):
        with tf.GradientTape() as tape:
            WH = tf.matmul(W, H)
            loss = tf.reduce_sum(tf.square(data - WH))
        gradients = tape.gradient(loss, [W, H])
        optimizer.apply_gradients(zip(gradients, [W, H]))
    return W, H, loss.numpy()

# Compute NMF for a range of ranks
ranks = range(1, 50)
errors = []

for rank in ranks:
    W, H, error = compute_nmf(data_tensor, rank)
    errors.append(error)
    print(f"Rank {rank} error: {error}")

# Display errors
for rank, error in zip(ranks, errors):
    print(f"Rank {rank}: {error}")

plt.figure(figsize=(10, 6))
plt.plot(ranks, errors, marker='o', linestyle='-')
plt.title('Reconstruction Error vs Rank')
plt.xlabel('Rank')
plt.ylabel('Reconstruction Error')
plt.grid(True)
plt.savefig('"../Figures/rank_evolution_plot.pdf', format='pdf', bbox_inches='tight')
pd.DataFrame(errors).to_csv("../Results/RecErrors.csv", index=False)


# coding: utf-8
import os
import shutil
from collections import namedtuple
import pprint
import subprocess as sp

class CompileError(Exception):
    pass

def _print(obj):
    """Print wrapper for prettyprint"""
    pp = pprint.pformat(obj, indent=1, width=150, depth=None)
    print(pp)

def _input(*args, **kw):
    """Strip input values"""
    return input(*args, **kw).strip()

def call(cmd, terminal='/bin/bash'):
    """
    Exec command into terminal.

    :param cmd: command string
    :param terminal: path to terminal
    :return: namedtuple('result', ['err', 'out'])
    """
    result = namedtuple('result', ['err', 'out'])
    with sp.Popen(cmd, shell=True, executable=terminal, stdout=sp.PIPE, stderr=sp.PIPE) as pipe:
        err = pipe.stderr.readlines()
        out = pipe.stdout.readlines()
    decode = lambda x: x.decode('utf-8').strip()
    result.err = tuple(map(decode, err))
    result.out = tuple(map(decode, out))
    return result

def idl_listdir(path=None):
    if not path:
        path = os.getcwd()
    listdir = (x for x in os.listdir(path) if x.endswith('.idl'))
    return listdir

def copy_idl(dir_from, dir_to):
    """

    :param dir_from:
    :param dir_to:
    :return:
    """
    for idl in idl_listdir(dir_from):
        path = f'{dir_from}/{idl}'
        shutil.copy(path, dir_to)
        print(f'copied file={path}')

def compile(name, preprocessor_path=None):
    """
    Метод компиляции idl с помощью omniidl в *.py модули.
    Скомпилированные файлы и пакеты с зависимостями будут распологаться в текущем каталоге.

    :param name: имя idl-файла
    :param preprocessor_path: путь для препроцессора, где лежат компилируемые idl
    :return:
    """
    if not preprocessor_path:
        cmd= f'omniidl -bpython -I . {name}'
    else:
        cmd= f'omniidl -bpython -I {preprocessor_path} {preprocessor_path}/{name}'

    res = call(cmd)
    if res.err:
        print(res.err)
        raise CompileError()

def all_compile(path=None):
    """
    Компилиция всех idl-файлов.

    :param path: путь директории, где находятся idl;
    :return: список нескомпилированных idl.
    """
    bad_idl = []
    for idl in idl_listdir(path):
        try:
            compile(idl, path)
        except CompileError:
            bad_idl.append(idl)
    print(f"Compiling are finished. Uncompile idl's: {bad_idl}")
    return bad_idl

if __name__ == '__main__':
    base_dir = '/root/corba/omniORB'
    dir_from = f'{base_dir}/omniORB_install/share/idl/omniORB/'
    dir_to = f'{base_dir}/idl'
    u2000_dir = f'{base_dir}/U2000'

    if not os.path.exists(u2000_dir):
        os.mkdir(u2000_dir)
    os.chdir(u2000_dir)
    copy_idl(dir_from, dir_to)
    all_compile(dir_to)


#!/usr/bin/env python

'''Plist operation'''

from __future__ import unicode_literals

import re
import zipfile
import biplist

def get_plist_from_ipa(path):
    '''Get plist file from IPA

    @param path: IPA file path
    @return plist bytes
    '''

    plist_file_re = re.compile(r'Payload/.*\.app/Info.plist')

    try:
        ipa = zipfile.ZipFile(path)
    except:
        raise IOError('Failed to read IPA file')

    file_list = ipa.namelist()

    plist_path = ""
    for file_name in file_list:
        if plist_file_re.match(file_name):
            plist_path = file_name
            break

    else:
        raise NameError('Info.plist not found in this IPA')

    try:
        plist = ipa.read(plist_path)
    except:
        raise IOError('Fail to read plist')

    return plist

def get_info(path):
    '''Get plist file from IPA

    @param path: IPA file path
    @return {'version': '', 'build': '', 'identifier': '', 'name':''}
    '''

    base_attrs = {
        'version':    b'CFBundleShortVersionString',
        'build':      b'CFBundleVersion',
        'identifier': b'CFBundleIdentifier',
        'name':       b'CFBundleDisplayName',
    }

    try:
        plist = biplist.readPlistFromString(get_plist_from_ipa(path))
    except:
        raise IOError('Fail to read plist')

    return {k: plist.get(v).decode() for k, v in base_attrs.items()} #pylint: disable=E1103


import faker_example
import manual_example
import transform
import mock_from_schema

from hypothesis import given, settings
from hypothesis import strategies as st
import string
import pytest
from pyspark.sql import SparkSession

import util
from hypothesis_example import description

# run pytest with -s to see the test cases printed during execution

def compare_results(expected, result):
    for case in expected:
        user = case['user']
        species = case['species']
        result_case = [r for r in result if r['user'] == user]
        if len(result_case) == 0:
            pytest.fail(f"Expected case: {case}. Could not find user {user} in result {result}")
        print(f"Result: {result_case}")
        print(f"Expected: {case}")
        assert result_case[0]['species'] == species

# The first time the spark fixture is used, the startup time will be
# part of the test time. Without deadline=None, hypothesis will recognize
# the outlier runtime and mark it as an error, as it can be indicative of
# flaky test behavior.
# https://hypothesis.readthedocs.io/en/latest/settings.html?highlight=deadline#hypothesis.settings.deadline
@settings(deadline=None)
@given(description(), st.emails())
def test_transform_hypothesis(spark_context, description, emails):
    species = description[0]
    desc = description[1]
    test_df = spark_context.parallelize([{'description': desc, 'user': emails}]).toDF()
    expected_df = spark_context.parallelize([{'species': species, 'user': emails}]).toDF()
    df_with_species = transform.apply_species_label(util.species_list, test_df)
    print("description:", desc, "species:", species)

    assert df_with_species.select('species','user').subtract(expected_df).rdd.isEmpty()

def test_transform_manual(spark_context):
    """
    Test apply_species label with a few rows of hand curated test
    data.
    """
    data, expected = manual_example.create_test_data()
    test_df = spark_context.parallelize(data).toDF()
    df_with_species = transform.apply_species_label(util.species_list, test_df)
    with_species = df_with_species.toPandas().to_dict('records')
    compare_results(expected, with_species)

def fake_ids(value):
    if 'species' in str(value):
        return value

def test_transform_faker(spark_context):
    data, expected = faker_example.create_test_data(100)

    test_df = spark_context.parallelize(data).toDF()
    df_with_species = transform.apply_species_label(util.species_list, test_df)
    with_species = df_with_species.toPandas().to_dict('records')
    compare_results(expected, with_species)

def test_transform_faker_distributed(spark_context):
    data, expected = faker_example.create_test_data_distributed(100)

    test_df = spark_context.parallelize(data).toDF()
    df_with_species = transform.apply_species_label(util.species_list, test_df)
    with_species = df_with_species.toPandas().to_dict('records')
    compare_results(expected, with_species)

from schemas import survey_data
def test_transform_schema():
    data, expected = mock_from_schema.generate_data_expected(survey_data, 10)
    df_with_species = transform.apply_species_label(util.species_list, data)
    df_with_species.select("user", "description", "species").show(10, False)
    with_species = df_with_species.toPandas().to_dict('records')
    compare_results(expected, with_species)


import json
import logging

import lxml.etree
import lxml.html

from pyscrapers.core.url_set import UrlSet

def get_my_content(r):
    """
    the return from the server in vk is not a standard HTML.
    this is why we must cut it up and cant use the regular
    'get_real_content' helper.
    """
    r.raise_for_status()
    str_content = r.content.decode(errors='ignore')
    str_content = str_content[str_content.find('<input'):]
    c = str.encode('') + str.encode(str_content) + str.encode('')
    root = lxml.html.fromstring(c)
    return root

def yield_json_objs_and_base(r):
    for x in get_my_content(r).xpath('//a[@onclick]'):
        onclick = x.attrib['onclick']
        if onclick.startswith('return showPhoto'):
            json_str = onclick[onclick.find('{'):onclick.rfind('}') + 1]
            # bas string, need fix lots of things...
            json_str = json_str.replace('\'', '"').replace('jumpTo', '"jumpTo"').replace('z:', '"z":')
            json_obj = json.loads(json_str)
            base = json_obj['temp']['base']
            if base == '':
                continue
            yield json_obj, base

def scrape_vk(user_id: str, session, url_set: UrlSet) -> None:
    logger = logging.getLogger(__name__)
    url = 'https://vk.com/al_photos.php'

    count = 0
    got = 1
    while got:
        got = 0
        data = {
            'act': 'show_albums',
            'al': '2',
            'owner': user_id,
            'offset': count,
        }
        logger.debug('doing request %d', count)
        r = session.post(url, data=data)
        for base, json_obj in yield_json_objs_and_base(r):
            got = get_urls(base, got, json_obj, url_set)
        count += got

def get_urls(base, got, json_obj, url_set):
    largest = 0
    largest_url = None
    min_len = min(len(v) for k, v in json_obj['temp'].items() if k.endswith('_'))
    if min_len == 3:
        for k, v in json_obj['temp'].items():
            if k != 'base':
                size = v[1] * v[2]
                if size > largest:
                    largest = size
                    largest_url = v[0]
        url_set.append(base + largest_url + '.jpg')
        got += 1
    if min_len == 1:
        for k, v in json_obj['temp'].items():
            if k != 'base':
                url_set.append(base + v[0] + '.jpg')
        got += 1
    return got

def get_total_images(logger, session, url, user_id):
    data = {
        'act': 'show_albums',
        'al': '1',
        'owner': user_id,
    }
    r = session.post(url, data=data)
    root = get_my_content(r)

    e_albums = root.xpath('//div[@class="photos_album_title_wrap"]')
    albums = {}
    for x in e_albums:
        name_of_album = x.getparent().getparent().getparent().getparent().attrib['id'].split('?')[0]
        e_len = x.xpath('.//div[@class="photos_album_counter fl_r"]/text()')
        albums[name_of_album] = int(e_len[0])
    logger.debug(albums)
    total_images = 0
    for v in albums.values():
        logger.debug('got [%d] partial images', v)
        total_images += v
    logger.debug('got [%d] potential images', total_images)


import json
import requests
from bs4 import BeautifulSoup

# Total Pages
PAGES = 20
START_PAGE = 0
links = []
lines = []

# Scrape Base Links
for i in range(START_PAGE, PAGES):
    # Scrape
    URL = "https://pickupline.net/page/" + str(i) + "?s="
    page = requests.get(URL)
    soup = BeautifulSoup(page.content, "html.parser")

    # Get main content
    content = soup.find(id="main")

    # Get Children
    children = content.findChildren("article", recursive=False)
    for child in children:
        # Get href
        d = child.findChild("div", recursive=False)
        dd = d.findChild("div", recursive=False)
        figure = dd.findChild("figure", recursive=False)
        a = figure.findChild("a", recursive=False)
        href = a.get("href")
        links.append(href)
        # print(href)

    print(str(i) + " done")

# Scrape Actual Lines
for link in links:
    # Define Local Lines
    ourLines = []

    # Define Base url
    base_url = link

    # Remove the first 23 elements bcuz they're just the url stuff
    # Also remove the last char using rstrip (ikr python)
    base_intent = base_url[24:len(base_url)].rstrip()

    # Now, split the base intent into two parts according to the slash
    intents = base_intent.split("/")
    categorical_intent = intents[0]
    sub_intent = intents[1]

    # Remove the substring '-pickup-lines' and hyphens
    sub_intent = sub_intent.replace("-", " ").replace(" pick up lines", "")
    categorical_intent = categorical_intent.replace("-", " ").replace(" pick up lines", "")

    # Scrape
    page = requests.get(link)
    soup = BeautifulSoup(page.content, "html.parser")

    # Find all Table Rows
    elements = soup.findAll('tr')
    for row in elements:
        td = row.findChild("td")
        txt = str(td)
        buf = ""
        started = False
        for char in txt:
            if char == ">":
                started = True
                continue

            if char == "<":
                started = False
                continue

            elif started == True:
                buf += char
        ourLines.append(buf)

    lines.append({"url": base_url, "categorical-intent": categorical_intent,
                 "intent": sub_intent, "lines": ourLines, "count": len(ourLines)})
    print("Done : ", link)

linesJSON = json.dump(lines, open("lines2.json", "w+"))
linksJSON = json.dump(links, open("links2.json", "w+"))


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

from random import randint
from numpy import array
import time
import enum

# Using enum class create enumerations
class E(enum.Enum):
   SPARSE     = 0
   DENSE      = 1
   UNORIENTED = 2
   ORIENTED   = 3
   MAX_INT    = 99999999

class Graph:
#    numberNodes    : number of nodes on the graph
#    startNode      : start node
#    structureKind  : SPARSE or DENSE
#    unoriented     : UNORIENTED or ORIENTED
    def __init__(self, numberNodes, startNode, structureKind, orientation):
        self.numberNodes   = numberNodes
        self.startNode     = startNode
        self.numberEdges   = 0
        self.structureKind = structureKind
        self.orientation   = orientation
        self.graph         = array([ [None] * numberNodes ] * numberNodes)

    def addEdge(self, frm, to, weight, orientation):
        self.graph[frm][to] = weight
        self.numberEdges   += 1

        if (orientation == E.UNORIENTED):
            self.graph[to][frm] = weight
            self.numberEdges += self.numberEdges

    def getGraph(self):

        for i in range(self.numberNodes):
            for j in range(self.numberNodes):
                if i != j:
                    if self.orientation == E.ORIENTED:
                        if self.structureKind == E.SPARSE:

                            edg = 0
                            for e in range(self.numberNodes):
                                if self.graph[i][j] != None:
                                    edg += 1
                                if edg == 2:
                                    break

                            if edg < 2:
                                self.addEdge(i, j, randint(1, 1000), E.ORIENTED)

                        else:
                            self.addEdge(i, j, randint(1, 1000), E.ORIENTED)

                    else:
                        if self.graph[i][j] == None:

                            if self.structureKind == E.SPARSE:
                                edg = 0
                                for e in range(self.numberNodes):
                                    if self.graph[i][j] != None:
                                        edg += 1
                                    if edg == 2:
                                        break

                                if edg < 2:
                                    self.addEdge(i, j, randint(1, 1000), E.ORIENTED)
                            else:

                                self.addEdge(i, j, randint(1, 1000), E.UNORIENTED)

        return self

class Prim():
    def __init__(self, graph):
        self.graph = graph

    def minKey(self, nodeKey, exploredNodes):
        minValue = E.MAX_INT.value
        minIndex = -1

        for i in range(self.graph.numberNodes):
            if not exploredNodes[i] and (nodeKey[i] < minValue):
                minValue = nodeKey[i]
                minIndex = i

        return minIndex

    def findRoute(self):
        ret           = array([None] * self.graph.numberNodes)
        nodeKey       = array([E.MAX_INT.value] * self.graph.numberNodes)
        exploredNodes = array([False] * self.graph.numberNodes)

        nodeKey[0] = 0

        for i in range(self.graph.numberNodes - 1):
            u = self.minKey(nodeKey, exploredNodes)
            exploredNodes[u] = True

            for j in range(self.graph.numberNodes):
                if self.graph.graph[u][j] and not exploredNodes[j] and (self.graph.graph[u][j] < nodeKey[j]):
                    ret[j] = u
                    nodeKey[j] = self.graph.graph[u][j]

        return ret

    def showResult(self):

        res = self.findRoute()

        print("from/to      weight")
        for i in range(1, self.graph.numberNodes):
            print(res[i], " - ", i , "       " , self.graph.graph[i][res[i]])

class Djikstra():
    def __init__(self, graph):
        self.graph = graph

    def minDist(self, nodeKey, exploredNodes):
        minValue = E.MAX_INT.value
        minIndex = -1

        for i in range(self.graph.numberNodes):
            if not exploredNodes[i] and (nodeKey[i] <= minValue):
                minValue = nodeKey[i]
                minIndex = i

        return minIndex

    def findRoute(self):
        ret           = array([E.MAX_INT.value] * self.graph.numberNodes)
        exploredNodes = array([False] * self.graph.numberNodes)

        ret[self.graph.startNode] = 0

        for i in range(self.graph.numberNodes - 1):
            u = self.minDist(ret, exploredNodes)
            exploredNodes[u] = True

            for j in range(self.graph.numberNodes):
                if self.graph.graph[u][j] and not exploredNodes[j] and ret[u] != E.MAX_INT.value and (ret[u] + self.graph.graph[u][j] < ret[j]):

                    ret[j] = ret[u] + self.graph.graph[u][j]

        return ret

outLoop = 15
innerLoop = 20
numberOfNodes = 3
structure = E.SPARSE
orientation = E.ORIENTED

#g = Graph(8, 0, structure, E.UNORIENTED)
#
#g.addEdge(0, 1, 14, E.UNORIENTED)
#g.addEdge(0, 2, 3, E.UNORIENTED)
#g.addEdge(1, 3, 6, E.UNORIENTED)
#g.addEdge(1, 2, 10, E.UNORIENTED)
#g.addEdge(1, 4, 5, E.UNORIENTED)
#g.addEdge(2, 5, 8, E.UNORIENTED)
#g.addEdge(3, 4, 4, E.UNORIENTED)
#g.addEdge(4, 5, 2, E.UNORIENTED)
#g.addEdge(4, 6, 9, E.UNORIENTED)
#g.addEdge(5, 7, 15, E.UNORIENTED)
#
#print(g.graph)
#
#Prim(g).showResult()

#p = Graph(5, 0, structure, E.ORIENTED)
#
#p.addEdge(0, 1, 10, E.ORIENTED)
#p.addEdge(0, 2, 5, E.ORIENTED)
#p.addEdge(1, 2, 2, E.ORIENTED)
#p.addEdge(1, 3, 1, E.ORIENTED)
#p.addEdge(2, 1, 3, E.ORIENTED)
#p.addEdge(2, 3, 9, E.ORIENTED)
#p.addEdge(2, 4, 2, E.ORIENTED)
#p.addEdge(3, 4, 4, E.ORIENTED)
#p.addEdge(4, 0, 7, E.ORIENTED)
#p.addEdge(4, 3, 6, E.ORIENTED)
#
#print(p.graph)
#
#Djikstra(p).findRoute()

print('Algorithm;NumberOfNodes;TypeGraph;Orientation;Loops;Time')

for i in range(outLoop):

    numberOfNodes += 10
    currentGraph = Graph(numberOfNodes, 0, structure, orientation).getGraph()

    accTime = 0
    for j in range(innerLoop):
        start = time.time()
        Prim(currentGraph).findRoute()
        end = time.time()

        accTime += (end - start)
    print('PRIM;' + str(numberOfNodes) + ';' + structure.name + ';' + orientation.name + ';' + str(innerLoop) + ';' + str(accTime))

    accTime = 0
    for j in range(innerLoop):
        start = time.time()
        Djikstra(currentGraph).findRoute()
        end = time.time()

        accTime += (end - start)
    print('DJIKSTRA;' + str(numberOfNodes) + ';' + structure.name + ';' + orientation.name + ';' + str(innerLoop) + ';' + str(accTime))


import pybaseball
import requests
import json
import time
from pybaseball import lahman
from pybaseball import schedule_and_record
from pybaseball import statcast, playerid_lookup, statcast_pitcher
from pybaseball import pitching_stats
from pybaseball import cache
from datetime import datetime
from bs4 import BeautifulSoup
import mlbstatsapi

# cache.enable()
def getPlayer(id):
    mlb = mlbstatsapi.Mlb()

    stats = ['career']
    groups = ['hitting', 'pitching']

    status = {}
    player_status = mlb.get_player_stats(id, stats, groups)

    if 'hitting' in player_status:
        status['hitting'] = player_status['hitting']['career'].splits[0].stat.__dict__

        if 'winloss' in player_status['hitting']:
            print(player_status['hitting']['winloss'].__dict__)
    if 'pitching' in player_status:
        status['hitting'] = player_status['pitching']['career'].splits[0].stat.__dict__

    return json.dumps(status)

def getPlayers(teamId=None):
    start = time.time()
    if teamId is not None:
        response = requests.get("https://statsapi.mlb.com/api/v1/teams/" + teamId + "/roster/fullName")

        players = response.text
        return players
    else:
        mlb = mlbstatsapi.Mlb()
        people = mlb.get_people()
        teams = mlb.get_teams()
        players = []

        mlbteams = {}
        for team in teams:
            mlbteams['{}'.format(team.id)] = team

        limit = 10
        i = -1
        while i < limit:
            i = i + 1
            person = people[i]

            player = {
                'id': person.id,
                'fullname': person.fullname,
                'age': person.currentage,
                'team': mlbteams['{}'.format(person.currentteam['id'])].name,
                'position': person.primaryposition.name
            }

            stats = ['career']
            groups = ['hitting', 'pitching']
            params = {'season': 2022}
            player_status = mlb.get_player_stats(person.id, stats, groups, **params)

            hitting_stat = {}
            pitching_stat = {}

            if 'hitting' in player_status:
                hitting_stat = player_status['hitting']['career'].splits[0].stat.__dict__
            if 'pitching' in player_status:
                pitching_stat = player_status['pitching']['career'].splits[0].stat.__dict__

            player['hittingstat'] = hitting_stat
            player['pitchingstat'] = pitching_stat

            # players.append(player[0]['splits'][0])
            players.append(player)

    print('execusion time: {}'.format(time.time() - start))
    # return json.dumps(players)

def getTeams():
    response = requests.get("http://statsapi.mlb.com/api/v1/teams?sportId=1")

    # Parse the JSON response
    teams = response.text

    return teams

def getSchedule(date):
    # today = datetime.now().strftime('%Y-%m-%d')
    response = requests.get("https://statsapi.mlb.com/api/v1/schedule?gameType=R&sportId=1&date=" + date)

    # Parse the JSON response
    schedule = response.text

    return schedule


from nltk.tokenize import word_tokenize
import gensim
import numpy as np
import pandas as pd

def recommend_materials(project_description):
    """
    Return list of maps of format:
        "course_link": mat["course_link"],
        "lesson_name": mat["lesson_name"]
    """
    dictionary = gensim.corpora.Dictionary.load("gensim/coursera_gensim_dict.dict")
    tf_idf = gensim.models.TfidfModel.load("gensim/coursera_gensim_tfidf.model")
    sims = gensim.similarities.Similarity.load("gensim/coursera_gensim_sims.sims")

    query_doc = [w.lower() for w in word_tokenize(project_description)]
    query_doc_bow = dictionary.doc2bow(query_doc)

    query_doc_tf_idf = tf_idf[query_doc_bow]
    ranked_lectures = np.argsort(sims[query_doc_tf_idf])[::-1]

    df = pd.read_csv("coursera_data.csv")
    best_lectures_info = df.iloc[ranked_lectures[:5]]

    return [{"course_link": row["course_link"], "lesson_name": row["lesson_name"]} for _, row in best_lectures_info.iterrows()]


from threading import * # handles threading so GUI doesnt freeze during main functions
import websocket # pip install websocket-client
from tkinter import * # handles GUI
import tkinter as tk # handles GUI
from tkinter import filedialog # handles opening Results and Config file paths
from PIL import Image, ImageTk # handles GUI Image
import os  # for working with opening files with applications like excel and notepad
import configparser # handles config files
from time import sleep

configParser = configparser.RawConfigParser() # config
configFile = 'Config.txt'
configParser.read(configFile)
pumpIP = configParser.get('Config', 'pumpIP')
pumpSpeed = configParser.get('Config', 'pumpSpeed')
pumpSteps = configParser.get('Config', 'pumpSteps')
pumpHalfStep = configParser.get('Config', 'pumpHalfStep')
rotTableIP = configParser.get('Config', 'rotTableIP')
rotTableSpeed = configParser.get('Config', 'rotTableSpeed')
rotTableSteps = configParser.get('Config', 'rotTableSteps')
rotTableHalfStep = configParser.get('Config', 'rotTableHalfStep')
enableEncoders = configParser.get('Config', 'enableEncoders')
resetEncoders = configParser.get('Config', 'resetEncoders')
manualSpeed = configParser.get('Config', 'manualSpeed')
primeSpeed = configParser.get('Config', 'primeSpeed')
primeSteps = configParser.get('Config', 'primeSteps')
deprimeSpeed = configParser.get('Config', 'deprimeSpeed')
deprimeSteps = configParser.get('Config', 'deprimeSteps')
# only set in config
# warning setting both as primary will cause GPIOs to short
# remove GPIO cable if setting both to primary
pumpPrimary = configParser.get('Config', 'pumpPrimary')
rotTablePrimary = configParser.get('Config', 'rotTablePrimary')
devMode = configParser.get('Config', 'devMode')
enableWebserial = 0
manualPump = 0
sleepTime = 0.25
sendParameters1 = 1 # send parameters only the first go or if they changed
sendParameters2 = 1 # send parameters only the first go or if they changed

# Driver code
#if __name__ == "__main__":
# create a GUI window
gui = Tk()
for i in range(8):  ###rows = 8
    gui.columnconfigure(i, weight=1, minsize=110)
    gui.rowconfigure(i, weight=1, minsize=10)

    for j in range(0, 7): ###column = 7
        frame = tk.Frame(master=gui,relief=tk.RAISED,borderwidth=2)

gui.configure(background="Black") # set the background colour of GUI window
gui.title("Project Sticky Fingers") # set the title of GUI window
gui.wm_iconbitmap('icon.ico')
# set the configuration of GUI window
if devMode == '1':
    guiGeometry = "1000x400"
else:
    guiGeometry = "1000x300"
gui.geometry(guiGeometry) # width by length
gui.resizable(width=True, height=True)

def openLocalConfig():
    os.startfile("Config.txt") #local folderConfig

menubar = Menu(gui, background='#ff8000', foreground='black', activebackground='white', activeforeground='black')
help = Menu(menubar, tearoff=0)
help.add_command(label="Local Config", command=openLocalConfig)
menubar.add_cascade(label="Options", menu=help)
gui.config(menu=menubar)

def setPumpIP(event):
    global pumpIP, sendParameters2
    pumpIP=pumpIP_var.get()
    pumpIPText.config(text="Pump IP: "+ pumpIP)
    pumpIP_var.set('')
    sendParameters2 = 1
    return
pumpIP_var = tk.StringVar()
expression_field = tk.Entry(gui, font=(12), relief="groove", textvariable=pumpIP_var, borderwidth=10)
expression_field.grid(row=1, column=0, columnspan=2)
expression_field.bind('<Return>',setPumpIP)
expression_field.icursor('end')
pumpIP_var.set('')
expression_field.update()
pumpIPText = tk.Label(gui, text="Connecting Pump", height=2, width=40, font='12', fg='black', bg='white', relief="groove")
pumpIPText.grid(row=1, column=2, columnspan=2)
pumpIPText.update()

def setrotTableIP(event):
    global rotTableIP, sendParameters1
    rotTableIP=rotTableIP_var.get()
    rotTableIPText.config(text="Rotary Table IP: "+ rotTableIP)
    rotTableIP_var.set('')
    sendParameters1 = 1
    return
rotTableIP_var = tk.StringVar()
expression_field5 = tk.Entry(gui, font=(12), relief="groove", textvariable=rotTableIP_var, borderwidth=10)
expression_field5.grid(row=1, column=4, columnspan=2)
expression_field5.bind('<Return>',setrotTableIP)
expression_field5.icursor('end')
rotTableIP_var.set('')
expression_field5.update()
rotTableIPText = tk.Label(gui, text="Connecting Rotary Table", height=2, width=40, font='12', fg='black', bg='white', relief="groove")
rotTableIPText.grid(row=1, column=6, columnspan=2)
rotTableIPText.update()

if devMode == '1':
    def webSerialFunction():
        global enableWebserial
        if enableWebserial == 0:
            ws1.send("wser:1")
            print("rotTable: "+ ws1.recv())
            sleep(sleepTime)
            ws2.send("wser:1")
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            enableWebserial = 1
            webSerialButton.config(text='Disable Webserial')
        else:
            ws1.send("wser:0")
            print("rotTable: "+ ws1.recv())
            sleep(sleepTime)
            ws2.send("wser:0")
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            enableWebserial = 0
            webSerialButton.config(text='Enable Webserial')

    webSerialButton= Button(gui,text='Enable Webserial',font='12',fg='white',bg='dark blue',borderwidth=5,command=webSerialFunction,height=1,width=15)
    webSerialButton.grid(row=8,column=4,columnspan=2)
    webSerialButton.update()

    def setPumpSpeed(event):
        global pumpSpeed, sendParameters2
        pumpSpeed=pumpSpeed_var.get()
        pumpSpeedText.config(text="Pump Speed: "+ pumpSpeed)
        pumpSpeed_var.set('')
        sendParameters2 = 1
        return
    pumpSpeed_var = tk.StringVar()
    expression2_field = tk.Entry(gui, font=(12), relief="groove", textvariable=pumpSpeed_var, borderwidth=10)
    expression2_field.grid(row=2, column=0, columnspan=2)
    expression2_field.bind('<Return>',setPumpSpeed)
    expression2_field.icursor('end')
    pumpSpeed_var.set('')
    expression2_field.update()
    pumpSpeedText = tk.Label(gui, text="Pump Speed: "+ pumpSpeed, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    pumpSpeedText.grid(row=2, column=2, columnspan=2)
    pumpSpeedText.update()

    def setManualSpeed(event):
        global manualSpeed, sendParameters2
        manualSpeed=manualSpeed_var.get()
        manualSpeedText.config(text="Manual Speed: "+ manualSpeed)
        manualSpeed_var.set('')
        sendParameters2 = 1
        return
    manualSpeed_var = tk.StringVar()
    expression11_field = tk.Entry(gui, font=(12), relief="groove", textvariable=manualSpeed_var, borderwidth=10)
    expression11_field.grid(row=8, column=0, columnspan=2)
    expression11_field.bind('<Return>',setManualSpeed)
    expression11_field.icursor('end')
    manualSpeed_var.set('')
    expression11_field.update()
    manualSpeedText = tk.Label(gui, text="Manual Speed: "+ manualSpeed, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    manualSpeedText.grid(row=8, column=2, columnspan=2)
    manualSpeedText.update()

    def setPumpSteps(event):
        global pumpSteps, sendParameters2
        pumpSteps=pumpSteps_var.get()
        pumpStepsText.config(text="Pump Steps: "+ pumpSteps)
        pumpSteps_var.set('')
        sendParameters2 = 1
        return
    pumpSteps_var = tk.StringVar()
    expression3_field = tk.Entry(gui, font=(12), relief="groove", textvariable=pumpSteps_var, borderwidth=10)
    expression3_field.grid(row=3, column=0, columnspan=2)
    expression3_field.bind('<Return>',setPumpSteps)
    expression3_field.icursor('end')
    pumpSteps_var.set('')
    expression3_field.update()
    pumpStepsText = tk.Label(gui, text="Pump Steps: "+ pumpSteps, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    pumpStepsText.grid(row=3, column=2, columnspan=2)
    pumpStepsText.update()

    def setPrimeSpeed(event):
        global primeSpeed, sendParameters2
        primeSpeed=primeSpeed_var.get()
        primeSpeedText.config(text="Prime Speed: "+ primeSpeed)
        primeSpeed_var.set('')
        sendParameters2 = 1
        return
    primeSpeed_var = tk.StringVar()
    expression12_field = tk.Entry(gui, font=(12), relief="groove", textvariable=primeSpeed_var, borderwidth=10)
    expression12_field.grid(row=6, column=0, columnspan=2)
    expression12_field.bind('<Return>',setPrimeSpeed)
    expression12_field.icursor('end')
    primeSpeed_var.set('')
    expression12_field.update()
    primeSpeedText = tk.Label(gui, text="Prime Speed: "+ primeSpeed, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    primeSpeedText.grid(row=6, column=2, columnspan=2)
    primeSpeedText.update()

    def setPrimeSteps(event):
        global primeSteps, sendParameters2
        primeSteps=primeSteps_var.get()
        primeStepsText.config(text="Prime Steps: "+ primeSteps)
        primeSteps_var.set('')
        sendParameters2 = 1
        return
    primeSteps_var = tk.StringVar()
    expression13_field = tk.Entry(gui, font=(12), relief="groove", textvariable=primeSteps_var, borderwidth=10)
    expression13_field.grid(row=6, column=4, columnspan=2)
    expression13_field.bind('<Return>',setPrimeSteps)
    expression13_field.icursor('end')
    primeSteps_var.set('')
    expression13_field.update()
    primeStepsText = tk.Label(gui, text="Prime Steps: "+ primeSteps, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    primeStepsText.grid(row=6, column=6, columnspan=2)
    primeStepsText.update()

    def setDeprimeSpeed(event):
        global deprimeSpeed, sendParameters2
        deprimeSpeed=deprimeSpeed_var.get()
        deprimeSpeedText.config(text="Deprime Speed: "+ deprimeSpeed)
        deprimeSpeed_var.set('')
        sendParameters2 = 1
        return
    deprimeSpeed_var = tk.StringVar()
    expression14_field = tk.Entry(gui, font=(12), relief="groove", textvariable=deprimeSpeed_var, borderwidth=10)
    expression14_field.grid(row=7, column=0, columnspan=2)
    expression14_field.bind('<Return>',setDeprimeSpeed)
    expression14_field.icursor('end')
    deprimeSpeed_var.set('')
    expression14_field.update()
    deprimeSpeedText = tk.Label(gui, text="Deprime Speed: "+ deprimeSpeed, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    deprimeSpeedText.grid(row=7, column=2, columnspan=2)
    deprimeSpeedText.update()

    def setDeprimeSteps(event):
        global deprimeSteps, sendParameters2
        deprimeSteps=deprimeSteps_var.get()
        deprimeStepsText.config(text="Deprime Steps: "+ deprimeSteps)
        deprimeSteps_var.set('')
        sendParameters2 = 1
        return
    deprimeSteps_var = tk.StringVar()
    expression15_field = tk.Entry(gui, font=(12), relief="groove", textvariable=deprimeSteps_var, borderwidth=10)
    expression15_field.grid(row=7, column=4, columnspan=2)
    expression15_field.bind('<Return>',setDeprimeSteps)
    expression15_field.icursor('end')
    deprimeSteps_var.set('')
    expression15_field.update()
    deprimeStepsText = tk.Label(gui, text="Deprime Steps: "+ deprimeSteps, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    deprimeStepsText.grid(row=7, column=6, columnspan=2)
    deprimeStepsText.update()

    def setPumpHalfStep(event):
        global pumpHalfStep, sendParameters2
        pumpHalfStep=pumpHalfStep_var.get()
        pumpHalfStepText.config(text="Pump HalfStep: "+ pumpHalfStep)
        pumpHalfStep_var.set('')
        sendParameters2 = 1
        return
    pumpHalfStep_var = tk.StringVar()
    expression4_field = tk.Entry(gui, font=(12), relief="groove", textvariable=pumpHalfStep_var, borderwidth=10)
    expression4_field.grid(row=4, column=0, columnspan=2)
    expression4_field.bind('<Return>',setPumpHalfStep)
    expression4_field.icursor('end')
    pumpHalfStep_var.set('')
    expression4_field.update()
    pumpHalfStepText = tk.Label(gui, text="Pump HalfStep: "+ pumpHalfStep, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    pumpHalfStepText.grid(row=4, column=2, columnspan=2)
    pumpHalfStepText.update()

    def setrotTableSpeed(event):
        global rotTableSpeed, sendParameters1
        rotTableSpeed=rotTableSpeed_var.get()
        rotTableSpeedText.config(text="Rotary Table Speed: "+ rotTableSpeed)
        rotTableSpeed_var.set('')
        sendParameters1 = 1
        return
    rotTableSpeed_var = tk.StringVar()
    expression6_field = tk.Entry(gui, font=(12), relief="groove", textvariable=rotTableSpeed_var, borderwidth=10)
    expression6_field.grid(row=2, column=4, columnspan=2)
    expression6_field.bind('<Return>',setrotTableSpeed)
    expression6_field.icursor('end')
    rotTableSpeed_var.set('')
    expression6_field.update()
    rotTableSpeedText = tk.Label(gui, text="Rotary Table Speed: "+ rotTableSpeed, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    rotTableSpeedText.grid(row=2, column=6, columnspan=2)
    rotTableSpeedText.update()

    def setrotTableSteps(event):
        global rotTableSteps, sendParameters1
        rotTableSteps = rotTableSteps_var.get()
        if rotTableSteps == 'inf':
            rotTableStepsText.config(text="inf disabled on table")
            rotTableSteps1 = 0
        else:
            rotTableStepsText.config(text="Rotary Table Steps: "+ rotTableSteps)
        rotTableSteps_var.set('')
        sendParameters1 = 1
        return
    rotTableSteps_var = tk.StringVar()
    expression7_field = tk.Entry(gui, font=(12), relief="groove", textvariable=rotTableSteps_var, borderwidth=10)
    expression7_field.grid(row=3, column=4, columnspan=2)
    expression7_field.bind('<Return>',setrotTableSteps)
    expression7_field.icursor('end')
    rotTableSteps_var.set('')
    expression7_field.update()
    rotTableStepsText = tk.Label(gui, text="Rotary Table Steps: "+ rotTableSteps, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    rotTableStepsText.grid(row=3, column=6, columnspan=2)
    rotTableStepsText.update()

    def setrotTableHalfStep(event):
        global rotTableHalfStep, sendParameters1
        rotTableHalfStep=rotTableHalfStep_var.get()
        rotTableHalfStepText.config(text="Rotary Table HalfStep: "+ rotTableHalfStep)
        rotTableHalfStep_var.set('')
        sendParameters1 = 1
        return
    rotTableHalfStep_var = tk.StringVar()
    expression8_field = tk.Entry(gui, font=(12), relief="groove", textvariable=rotTableHalfStep_var, borderwidth=10)
    expression8_field.grid(row=4, column=4, columnspan=2)
    expression8_field.bind('<Return>',setrotTableHalfStep)
    expression8_field.icursor('end')
    rotTableHalfStep_var.set('')
    expression8_field.update()
    rotTableHalfStepText = tk.Label(gui, text="Rotary Table HalfStep: "+ rotTableHalfStep, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    rotTableHalfStepText.grid(row=4, column=6, columnspan=2)
    rotTableHalfStepText.update()

    def setEncoders(event):
        global enableEncoders, sendParameters1, sendParameters2, tablePosText, pumpPosText
        enableEncoders=enableEncoders_var.get()
        enableEncodersText.config(text="enableEncoders: "+ enableEncoders)
        enableEncoders_var.set('')
        sendParameters1 = 1 # send to both
        sendParameters2 = 1
        if enableEncoders == '0':
            tablePosText.destroy()
            pumpPosText.destroy()
        if enableEncoders == '1':
            encoderPositionText()
        return
    enableEncoders_var = tk.StringVar()
    expression9_field = tk.Entry(gui, font=(12), relief="groove", textvariable=enableEncoders_var, borderwidth=10)
    expression9_field.grid(row=5, column=0, columnspan=2)
    expression9_field.bind('<Return>',setEncoders)
    expression9_field.icursor('end')
    enableEncoders_var.set('')
    expression9_field.update()
    enableEncodersText = tk.Label(gui, text="enableEncoders: "+ enableEncoders, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    enableEncodersText.grid(row=5, column=2, columnspan=2)
    enableEncodersText.update()

    def reEncoders(event):
        global resetEncoders
        resetEncoders=resetEncoders_var.get()
        resetEncodersText.config(text="resetEncoders: "+ resetEncoders)
        resetEncoders_var.set('')
        return
    resetEncoders_var = tk.StringVar()
    expression10_field = tk.Entry(gui, font=(12), relief="groove", textvariable=resetEncoders_var, borderwidth=10)
    expression10_field.grid(row=5, column=4, columnspan=2)
    expression10_field.bind('<Return>',reEncoders)
    expression10_field.icursor('end')
    resetEncoders_var.set('')
    expression10_field.update()
    resetEncodersText = tk.Label(gui, text="resetEncoders: "+ resetEncoders, height=2, width=40, font='12', fg='black', bg='#3399ff', relief="groove")
    resetEncodersText.grid(row=5, column=6, columnspan=2)
    resetEncodersText.update()

def sendParams1():
    global sendParameters1
    # send parameters
    if sendParameters1 == 1 :
        ws1.send("spee: " + rotTableSpeed)
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)
        ws1.send("half: " + rotTableHalfStep)
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)
        ws1.send("enen: " + enableEncoders)
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)
        ws1.send("prim: " + rotTablePrimary)
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)
        sendParameters1 = 0
def sendParams2():
    global sendParameters2
    # send parameters
    if sendParameters2 == 1 :
        ws2.send("spee: " + pumpSpeed)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("half: " + pumpHalfStep)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("enen: " + enableEncoders)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("prim: " + pumpPrimary)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("prsp: " + primeSpeed)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("prst: " + primeSteps)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("desp: " + deprimeSpeed)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws2.send("dest: " + deprimeSteps)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        sendParameters2 = 0

def primePump():
    ws2.send("stpr:") # runs pump priming
    print('Pump: ' + ws2.recv())
    msgRecv2 = ''
    while msgRecv2 != 'priming done':
        msgRecv2 = ws2.recv()
        print("pump: " + msgRecv2)
    #sleep(sleepTime)
    # try to keep delays to a minimum

def deprimePump():
    ws2.send("stde:") # runs pump depriming
    print('Pump: ' + ws2.recv())
    msgRecv2 = ''
    while msgRecv2 != 'depriming done':
        msgRecv2 = ws2.recv()
        print("pump: " + msgRecv2)
    sleep(sleepTime)

def rcv(ws1,ws2): # ws1=rotTable ; ws2=pump
    global pumpPosText, tablePosText, pumpSteps, rotTableSteps
    try :
        if enableEncoders == '1' and resetEncoders == '1':
            tablePosText.config(text='tablePos: 0')
            pumpPosText.config(text='pumpPos: 0')
            ws1.send("reset")
            print('rotTable: ' + ws1.recv())
            sleep(sleepTime)
            ws2.send("reset")
            print('Pump: ' + ws2.recv())
            sleep(sleepTime)
        sendParams1() # only send params if they have changed
        sendParams2()
        ws1.send("zero:0") # sets rotTable stepper current position to 0
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)

        primePump() # will also set current pos to zero

        # send secondary stepper first (waits on primary GPIO sync signal)
        if pumpSteps == "inf":
            ws2.send("gogo:") # pump non-block / non-accel runforever til stop: is called
        else:
            ws2.send("goto:" + pumpSteps)
        print('Pump: ' + ws2.recv())
        sleep(sleepTime)
        ws1.send("goto:" + rotTableSteps)
        print('rotTable: ' + ws1.recv())
        sleep(sleepTime)
        # wait for rotary table to send done signal
        msgRecv = ws1.recv()
        msgRecv = msgRecv.split(',')
        if msgRecv[0] == 'moving done':
            print("rotTable: " + msgRecv[0])
            print("rotTable: " + msgRecv[1])
            if enableEncoders == '1':
                tablePosText.config(text='tablePos: '+ msgRecv[1])
        msgRecv2 = ws2.recv()
        msgRecv2 = msgRecv2.split(',')
        if msgRecv2[0] == 'moving done':
            print("pump: " + msgRecv2[0])
            print("pump: " + msgRecv2[1])
            if enableEncoders == '1':
                pumpPosText.config(text='pumpPos:' + msgRecv2[1])
        deprimePump()
        # display logo to indicate everything is done
        ws1.send("logo:")
        print("rotTable: "+ ws1.recv())
        sleep(sleepTime)
        ws2.send("logo:")
        print("pump: " + ws2.recv())
    except:
        try:
            ws2.send("stop:") # pump non-block / non-accel runforever til stop: is called
            print("pump: " + ws2.recv())
            connectSteppers()
        except:
            connectSteppers()

def wifiThread():
    t1=Thread(target=rcv(ws1,ws2))
    t1.start()
    return
def runFunction():
    wifiThread()
    return
runButton= Button(gui,text='Run',font='12',fg='white',bg='blue',borderwidth=5,command=runFunction,height=1,width=10)
runButton.grid(row=0,column=0)
runButton.update()

def saveFunction():
    with open('Config.txt', 'w') as f:
        f.write('[Config]\n')
        f.write('pumpIP = ' + pumpIP + '\n')
        f.write('pumpSpeed = ' + pumpSpeed + '\n')
        f.write('pumpSteps = ' + pumpSteps + '\n')
        f.write('pumpHalfStep = ' + pumpHalfStep + '\n')
        f.write('rotTableIP = ' + rotTableIP + '\n')
        f.write('rotTableSpeed = ' + rotTableSpeed + '\n')
        f.write('rotTableSteps = ' + rotTableSteps + '\n')
        f.write('rotTableHalfStep = ' + rotTableHalfStep + '\n')
        f.write('enableEncoders = ' + enableEncoders + '\n')
        f.write('resetEncoders = ' + resetEncoders + '\n')
        f.write('manualSpeed = ' + manualSpeed + '\n')
        f.write('primeSpeed = ' + primeSpeed + '\n')
        f.write('primeSteps = ' + primeSteps + '\n')
        f.write('deprimeSpeed = ' + deprimeSpeed + '\n')
        f.write('deprimeSteps = ' + deprimeSteps + '\n')
        f.write('# only set in config\n# warning setting both as primary will cause GPIOs to short\n# remove GPIO cable if setting both to primary\n')
        f.write('rotTablePrimary = ' + rotTablePrimary + '\n')
        f.write('pumpPrimary = ' + pumpPrimary + '\n')
        f.write('devMode = ' + devMode + '\n')

saveButton= Button(gui,text='Save Config',font='12',fg='white',bg='blue',borderwidth=5,command=saveFunction,height=1,width=10)
saveButton.grid(row=0,column=1)
saveButton.update()

def closeFunction():
    try:
        try: # if rotTable is closed try to close pump
            ws1.send("print")
            ws1.close()
        except:
            pass
        ws2.send("print")
        ws2.close()
        gui.destroy()
    except:
        gui.destroy()
closeButton= Button(gui,text='Close',font='12',fg='white',bg='dark blue',borderwidth=5,command=closeFunction,height=1,width=15)
closeButton.grid(row=0,column=2)
closeButton.update()

def runPump():
    global manualPump, sendParameters2
    try:
        if manualPump == 0:
            ws2.send("spee:" + manualSpeed)
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            ws2.send("manu:1")
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            manualPump = 1
            manualPumpButton.config(text='Stop Pump')
        else:
            ws2.send("stop:")
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            print("pump: " + ws2.recv())
            sleep(sleepTime)
            manualPump = 0
            manualPumpButton.config(text='Manual Pump')
            sendParameters2 = 1 # need to re update update speed after running in manual mode

    except:
        connect2()
manualPumpButton= Button(gui,text='Manual Pump',font='12',fg='white',bg='dark blue',borderwidth=5,command=runPump,height=1,width=15)
manualPumpButton.grid(row=0,column=3)
manualPumpButton.update()

def encoderPositionText():
    global tablePosText, pumpPosText, enableEncoders
    if enableEncoders == '1':
        tablePosText = tk.Label(gui, text="pumpPos: 0", height=2, width=30, font='12', fg='white', bg='blue', relief="groove")
        tablePosText.grid(row=0, column=4, columnspan=2)
        tablePosText.update()

        pumpPosText = tk.Label(gui, text="tablePos: 0", height=2, width=30, font='12', fg='white', bg='blue', relief="groove")
        pumpPosText.grid(row=0, column=6, columnspan=2)
        pumpPosText.update()

encoderPositionText()

####IMG####
load= Image.open("logo4.ppm")
render = ImageTk.PhotoImage(load)
img = Label(gui, borderwidth=0, image=render)
img.grid(row=8, column=6, columnspan=2)
img.update()

def connect1():
    global ws1, rotTableIPText
    try:
        ws1 = websocket.WebSocket()
        ws1.connect("ws://"+ rotTableIP +"/python") # pump
        sendParams1() # send one time only parameters (unless devMode changes them)
        rotTableIPText.config(text="Rotary Table IP: "+ rotTableIP , bg='#3399ff')
    except:
        rotTableIPText.config(text="Rotary Table Failed: "+ rotTableIP, bg='red')
    return
def connect2():
    global ws2, pumpIPText
    try:
        ws2 = websocket.WebSocket()
        ws2.connect("ws://"+ pumpIP +"/python") # rotary table
        sendParams2() # send one time only parameters (unless devMode changes them)
        pumpIPText.config(text="Pump IP: "+ pumpIP, bg='#3399ff')
    except:
        pumpIPText.config(text="Pump Failed: "+ pumpIP, bg='red')
    return

def connectSteppers():
    connect1()
    connect2()
    return
def connectThread():
    t1=Thread(target=connectSteppers)
    t1.start()
    return
connectThread()

gui.mainloop() # start the GUI


from django.core.management.base import BaseCommand, CommandError
import os, requests
from cbimporter.models import cb_portfolio

TILL_URL = os.environ.get("TILL_URL")

class Command(BaseCommand):
	def handle(self, *args, **options):
		cb_portfolio.update_all()
		if cb_portfolio.is_high():
			cb_portfolio.update_high()
			sms_text = 'New High!\nTotal Value: %s'%(round(cb_portfolio.total_value,2))
			for account in cb_portfolio.account_set.all():
				sms_text += '\n%s: %s'%(account.currency, round(account.price, 2))
			requests.post(TILL_URL, json={
			    "phone": os.environ.get("CELL_PHONE"),
			    "text" : sms_text
			})


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

from setuptools import setup, find_packages

with open('README.rst') as f:
    readme = f.read()

with open('LICENSE') as f:
    license = f.read()

setup(
    name='accounts',
    version='0.1.0',
    description='Manage your accounts on comfortable way',
    long_description=readme,
    author='Chunlin Liu',
    author_email='chunlins@outlook.com',
    url='',
    license=license,
    packages=find_packages(exclude=('tests', 'docs')),
    install_requires=[
        'Click',
    ],
    entry_points="""
        [console_scripts]
        accounts=accounts.interface:accounts
    """,
)


import collections
import queue
from typing import Optional

from picoflexx import roypy
from picoflexx.royale.extension import roypycy
from picoflexx.roypy import DepthData
from ..frames.depth_frame import DepthFrame
from ..frames.ir_frame import IRFrame

FramePair = collections.namedtuple("FramePair", ["ir", "depth"])

class DepthDataListener(roypy.IDepthDataListener):
    current_index = 0

    def __init__(self, queue: queue.Queue):
        """
        Instantiate the DepthDataListener with the given queue.

        :param queue: The queue to which FramePairs will be added - usually has
         a size limit of 1
        """

        super().__init__()
        self.queue = queue
        self._ir_ref = None

        self._data_depth = None  # type: Optional[DepthData]
        self._data_ir = None  # type: Optional[roypycy.PyIrImage]

    def _check_frame(self):
        """
        Checks if the next depth and ir frame pair have arrived.

        If this is the case and the queue isn't full, add them to the queue.
        """

        if self._data_depth is None or self._data_ir is None:
            return
        if roypycy.get_depth_data_ts(self._data_depth) != self._data_ir.timestamp:
            return

        try:
            frame_depth = DepthFrame(self._data_depth)
            frame_ir = IRFrame(self._data_ir)
            frame_depth.index = frame_ir.index = self.current_index
            self.current_index += 1

            self.queue.put(FramePair(ir=frame_ir, depth=frame_depth), block=False)
        except queue.Full:
            pass  # dropping frame pair
        except Exception:
            import traceback

            traceback.print_exc()

        self._data_depth = None
        self._data_ir = None

    def onNewData(self, data: DepthData):
        self._data_depth = data
        self._check_frame()

    def onNewIrData(self, data: roypycy.PyIrImage):
        self._data_ir = data
        self._check_frame()


import gym
import balancing_robot
from stable_baselines3 import A2C, PPO
from stable_baselines3.common.policies import ActorCriticPolicy

env = gym.make('balancingrobot-v0', render=True)

model = A2C(ActorCriticPolicy, env, verbose=2)
model.learn(total_timesteps=50000)
print(f'Action space: {env.action_space}')
print(f'Obs space: {env.observation_space}')
print(f'Reward space: {env.reward_range}')
env.close()
print("Training FINISHED")
input()
obs = env.reset()
while True:
    action, _states = model.predict(obs, deterministic=True)
    obs, reward, done, info = env.step(action)
    env.render()
    if done:
        input(f'Reward: {reward}')
        obs = env.reset()

env.close()


#iniciamos el proyecto
from  Posts.Post1 import *
from Posts.Post2 import *
from flask import Flask,request
from flask_cors import CORS
from Probabilidades import *

app = Flask(__name__)
CORS(app) #restringimos y aseguramos solicitudes http externas

@app.route('/')

def home():
    return 'Hello, world!'

@app.route('/Configuracion', methods=['POST'])
def ProfileDesc():
    # Obtener los datos enviados en la solicitud en un string
    DatosXML = request.data
    #print(DatosXML)
    Solicitud1 = Peticion1()

    Solicitud1.LecturaXML(DatosXML,True)
    respuesta = Solicitud1.RespuestaS1()
    return respuesta

@app.route('/Mensajes', methods=['POST'])
def Mensajes():
    Solicitud2 = Peticion2()

    DatosXML = request.data  # rconoce las tildes
    Solicitud2.LeerXML(DatosXML,True,False)
    respuesta = Solicitud2.RespuestaS2()
    return respuesta

@app.route('/MensajesUsuarios', methods=['GET'])
def Tablas():
    Solicitud2 = Peticion2()
    Solicitud1 = Peticion1()

    Solicitud1.CargarBase()
    Solicitud2.CargarBase(True)
    pro = Probabilidad(Solicitud2.ListaMensajes,Solicitud1.Perfiles,Solicitud1.Descartadas,Solicitud2.Usuarios,Solicitud1.NombresPerfiles,'','')
    pro.AnalizarMensaje(True)

    respuesta = pro.respuesta()

    return respuesta

@app.route('/FiltroUsuarios', methods=['POST'])
def FiltroUsuarios():
    Solicitud2 = Peticion2()
    Solicitud1 = Peticion1()
    usuario = str(request.data)
    usuario = usuario.replace("b", "").replace("'", "")

    print('--->'+usuario+'<----')
    Solicitud1.CargarBase()
    Solicitud2.CargarBase(True)
    pro = Probabilidad(Solicitud2.ListaMensajes,Solicitud1.Perfiles,Solicitud1.Descartadas,Solicitud2.Usuarios,Solicitud1.NombresPerfiles,usuario,'')
    pro.AnalizarMensaje(True)

    respuesta = pro.respuesta()

    return respuesta

@app.route('/FiltroFechas', methods=['POST'])
def FiltroFechas():
    Solicitud2 = Peticion2()
    Solicitud1 = Peticion1()
    fecha = str(request.data)
    fecha = fecha.replace("b", "").replace("'", "")

    print('--->'+fecha+'<----')
    Solicitud1.CargarBase()
    Solicitud2.CargarBase(True)
    pro = Probabilidad(Solicitud2.ListaMensajes,Solicitud1.Perfiles,Solicitud1.Descartadas,Solicitud2.Usuarios,Solicitud1.NombresPerfiles,'',fecha)
    pro.AnalizarMensaje(True)

    respuesta = pro.respuesta()

    return respuesta

@app.route('/GetPesos', methods=['GET'])
def Pesos():
    Solicitud2 = Peticion2()
    Solicitud1 = Peticion1()

    Solicitud1.CargarBase()
    Solicitud2.CargarBase(True)
    pro = Probabilidad(Solicitud2.ListaMensajes,Solicitud1.Perfiles,Solicitud1.Descartadas,Solicitud2.Usuarios,Solicitud1.NombresPerfiles,'','')
    pro.AnalizarMensaje(False)
    pro.PesosUsuarioPerfil()
    respuesta = pro.respuesta()

    return respuesta

@app.route('/PesosUsuarios', methods=['POST'])
def PesosU():
    Solicitud2 = Peticion2()
    Solicitud1 = Peticion1()

    usuario = str(request.data)
    print(usuario)
    usuario = usuario.replace("b", "").replace("'", "")

    Solicitud1.CargarBase()
    Solicitud2.CargarBase(True)
    pro = Probabilidad(Solicitud2.ListaMensajes,Solicitud1.Perfiles,Solicitud1.Descartadas,Solicitud2.Usuarios,Solicitud1.NombresPerfiles,usuario,'')
    pro.AnalizarMensaje(False)
    pro.PesosUsuarioPerfil()
    respuesta = pro.respuesta()

    return respuesta

@app.route('/MensajesP', methods=['POST'])
def MensajesP():

    Solicitud2 = Peticion2()

    DatosXML = request.data  # rconoce las tildes
    Solicitud2.LeerXML(DatosXML,True,False)
    respuesta = Solicitud2.RespuestaP()
    return respuesta

@app.route('/BorrarBase', methods=['GET'])
def Borrar():

  with open("server\DataBase\Mensajes.xml", "w") as f:
            f.write("")

  with open("server\DataBase\PerfilesDescartes.xml", "w") as f:
            f.write("")

  return "El contenido del archivo ha sido borrado exitosamente."

if __name__ == '__main__':
    app.run(debug=True)


"""
Author: Gustavo Soares
"""

import numpy as np
import pandas as pd
from bloomberg import BBG
from datetime import timedelta
from pandas.tseries.offsets import BDay

class FXForwardTrackers(object):
    """
    Class for creating excess return indices for currencies using data from bloomberg.
    At the start date, we assume we trade 100 units of the base currency in 1M forward contracts.
    We mark-to-market the position over the month and then roll it into the new 1M forward at the end of the month
    """

    # Currently available currencies
    # TODO add 'DKK', 'ISK', 'SKK', 'HKD', 'CNY', 'MYR', 'THB', 'ARS', 'COP', 'PEN' to the list of currencies
    currencies = ['AUD', 'BRL', 'CAD', 'CHF', 'CLP', 'CZK', 'EUR', 'GBP', 'HUF', 'JPY', 'KRW',
                  'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'TRY', 'TWD', 'ZAR']

    point_divisor_dict = {'AUD': 10000,
                          'BRL': 10000,
                          'CAD': 10000,
                          'CHF': 10000,
                          'CLP': 1,
                          'CZK': 1000,
                          'EUR': 10000,
                          'GBP': 10000,
                          'HUF': 100,
                          'JPY': 100,
                          'KRW': 1,
                          'MXN': 10000,
                          'NOK': 10000,
                          'NZD': 10000,
                          'PHP': 1,
                          'PLN': 10000,
                          'SEK': 10000,
                          'SGD': 10000,
                          'TRY': 10000,
                          'TWD': 1,
                          'ZAR': 10000}

    fwd_1M_dict = {'AUD': 'AUD1M Curncy',
                   'BRL': 'BCN1M Curncy',
                   'CAD': 'CAD1M Curncy',
                   'CHF': 'CHF1M Curncy',
                   'CLP': 'CHN1M Curncy',
                   'CZK': 'CZK1M Curncy',
                   'EUR': 'EUR1M Curncy',
                   'GBP': 'GBP1M Curncy',
                   'HUF': 'HUF1M Curncy',
                   'JPY': 'JPY1M Curncy',
                   'KRW': 'KRW1M Curncy',
                   'MXN': 'MXN1M Curncy',
                   'NOK': 'NOK1M Curncy',
                   'NZD': 'NZD1M Curncy',
                   'PHP': 'PHP1M Curncy',
                   'PLN': 'PLN1M Curncy',
                   'SEK': 'SEK1M Curncy',
                   'SGD': 'SGD1M Curncy',
                   'TRY': 'TRY1M Curncy',
                   'TWD': 'NTN1M BGN Curncy',
                   'ZAR': 'ZAR1M Curncy'}

    quoted_as_XXXUSD = ['BRL', 'CAD', 'CHF', 'CLP', 'CZK', 'HUF', 'JPY', 'KRW', 'MXN', 'NOK',
                        'PHP', 'PLN', 'SGD', 'TRY', 'TWD', 'ZAR', 'SEK']

    iso_country_dict = {'AUD': 'AU',
                        'BRL': 'BR',
                        'CAD': 'CA',
                        'CHF': 'CH',
                        'CLP': 'CL',
                        'CZK': 'CZ',
                        'EUR': 'EU',
                        'GBP': 'GB',
                        'HUF': 'HU',
                        'JPY': 'JP',
                        'KRW': 'KR',
                        'MXN': 'MX',
                        'NOK': 'NO',
                        'NZD': 'NZ',
                        'PHP': 'PH',
                        'PLN': 'PL',
                        'SEK': 'SE',
                        'SGD': 'SG',
                        'TRY': 'TR',
                        'TWD': 'TW',
                        'ZAR': 'ZA'}

    def __init__(self, ccy_symbol, start_date='1999-12-31', end_date='today'):
        """
        Returns an object with the following attributes:
            - tickers: list with 2 strs with Bloomberg ticker for the spot rates and 1M forward rates
            - spot_rate: Series with the spot rate data
            - fwd: Series with the 1M fwd rate data
            - er_index: Series with the excess return index
            - ts_df: DataFrame with columns 'Spot', 'Fwd', and 'Excess Return Index'
        :param ccy_symbol: str, Currency symbol from Bloomberg
        :param start_date: str, when the tracker should start
        :param end_date: str, when the tracker should end
        """

        assert ccy_symbol in self.currencies, f'{ccy_symbol} not currently supported'

        self.bbg = BBG()
        self.ccy_symbol = ccy_symbol
        self.start_date = pd.to_datetime(start_date)
        self.end_date = pd.to_datetime(end_date)
        self.spot_rate = self._get_spot_rate()
        raw_fwd = self._get_1m_fwd_rate()
        self.country = self.iso_country_dict[self.ccy_symbol]
        self.fh_ticker = 'fx ' + self.country.lower() + ' ' + self.ccy_symbol.lower()
        self.df_metadata = self._get_metadata()

        # calculate forward outrights
        fwd_outrights = self.spot_rate + raw_fwd / self.point_divisor_dict[self.ccy_symbol]
        self.fwd_rate_bbg_data = fwd_outrights.fillna(method='ffill')

        # get all quotes vs. the USD
        if self.ccy_symbol in self.quoted_as_XXXUSD:
            bbg_raw_spot_data = 1/self.spot_rate
            fwd_outrights = 1/self.fwd_rate_bbg_data
        else:
            bbg_raw_spot_data = self.spot_rate
            fwd_outrights = self.fwd_rate_bbg_data

        self.df_tracker = self._calculate_tr_index(bbg_raw_spot_data, fwd_outrights)
        self.df_tracker = self._get_tracker_melted()

    @staticmethod
    def _calculate_tr_index(spot_rate, fwd_rate):

        ts_df = pd.concat([spot_rate, fwd_rate], axis=1, sort=True).fillna(method='ffill').dropna()
        ts_df.columns = ['spot', 'fwd_1m']
        er_index = pd.Series(index=ts_df.index)
        fwd_mtm = pd.Series(index=ts_df.index)
        st_dt = ts_df.index[0]
        er_index.iloc[0] = 100.
        strike = ts_df['fwd_1m'].iloc[0]
        holdings = 100. / strike
        # TODO: check if we need to use proper calendar for settlement_date calculation
        settlement_date = st_dt + timedelta(days=30) + BDay(2)
        last_rebalance = st_dt

        for d in ts_df.index[1:]:
            # TODO: check if we need to use proper calendar for day_count calculation
            day_count = (settlement_date - d).days

            spot_d = ts_df.loc[d, 'spot']
            fwd_d = ts_df.loc[d, 'fwd_1m']

            # Using DC 30/365 convention for mtm of the foward
            fwd_mtm[d] = np.interp(float(day_count), [2, 32], [spot_d, fwd_d])
            er_index[d] = er_index[last_rebalance] + holdings * (fwd_mtm[d] - strike)
            if d >= settlement_date:
                strike = ts_df.loc[d, 'fwd_1m']
                holdings = er_index[d] / strike
                settlement_date = d + timedelta(days=30) + BDay(2)
                last_rebalance = d

        return er_index.to_frame('er_index')

    def _get_spot_rate(self):
        spot_rate_bbg_ticker = self.ccy_symbol + ' Curncy'
        bbg_raw_spot_data = self.bbg.fetch_series(securities=spot_rate_bbg_ticker,
                                                  fields='PX_LAST',
                                                  startdate=self.start_date,
                                                  enddate=self.end_date)
        bbg_raw_spot_data.columns = [self.ccy_symbol]
        bbg_raw_spot_data = bbg_raw_spot_data.fillna(method='ffill').dropna()
        return bbg_raw_spot_data

    def _get_1m_fwd_rate(self):

        bbg_raw_fwd_data = self.bbg.fetch_series(securities=self.fwd_1M_dict[self.ccy_symbol],
                                                 fields='PX_LAST',
                                                 startdate=self.start_date,
                                                 enddate=self.end_date)
        bbg_raw_fwd_data.columns = [self.ccy_symbol]
        bbg_raw_fwd_data = bbg_raw_fwd_data.fillna(method='ffill').dropna()
        return bbg_raw_fwd_data

    def _get_metadata(self):
        df = pd.DataFrame(index=[0],
                          data={'fh_ticker': self.fh_ticker,
                                'asset_class': 'FX',
                                'type': 'currency forward',
                                'exchange_symbol': self.ccy_symbol,
                                'currency': 'USD',
                                'country': self.country,
                                'maturity': 1/12})
        return df

    def _get_tracker_melted(self):
        df = self.df_tracker[['er_index']].rename({'er_index': self.fh_ticker}, axis=1)
        df['time_stamp'] = df.index.to_series()
        df = df.melt(id_vars='time_stamp', var_name='fh_ticker', value_name='value')
        df = df.dropna()
        return df


import spacy
from bert_score import create_idf_dict, score
from spacy.tokens import Token
from typing import List, Tuple

from sacrerouge.metrics.interpretable_rouge.backends import Backend

@Backend.register('bertscore-backend')
class BertScoreBackend(Backend):
    def __init__(self, idf: bool):
        self.idf = idf
        self.nlp = spacy.load('en_core_web_sm')

    def _get_summary_strings(self, tokens: List[Token]) -> str:
        return ' '.join(list(map(lambda token: str(token), tokens)))

    def _get_dummy_token(self, text: str):
        doc = self.nlp.tokenizer.tokens_from_list([text])
        return doc[0]

    def get_matches_list(self,
                         summary_tokens_lists: List[List[Token]],
                         reference_tokens_lists: List[List[Token]]):
        summaries_list = [[self._get_summary_strings(summary_tokens) for summary_tokens in summary_tokens_list] for summary_tokens_list in summary_tokens_lists]
        references_list = [[self._get_summary_strings(reference_tokens) for reference_tokens in reference_tokens_list] for reference_tokens_list in reference_tokens_lists]

        if self.idf:
            unique_references = list(set(reference for references in references_list for reference in references))
            idf = create_idf_dict(unique_references, lang='en')
        else:
            idf = False

        input_candidates = []
        input_references = []
        empty_inputs = set()
        for i, (summaries, references) in enumerate(zip(summaries_list, references_list)):
            for j, summary in enumerate(summaries):
                if len(summary) == 0:
                    empty_inputs.add((i, j))
                else:
                    input_candidates.append(summary)
                    input_references.append(references)

        # Score the summaries
        precisions, recalls, f1s, precision_alignments_list, recall_alignments_list, precision_indices, recall_indices, precision_weights, recall_weights \
            = score(input_candidates, input_references,
                    lang='en',
                    idf=idf,
                    return_alignments=True)

        bos = self._get_dummy_token('<s>')
        eos = self._get_dummy_token('</s>')

        index = 0
        output_summary_tokens_list = []
        output_reference_precision_tokens_lists = []
        output_reference_recall_tokens_lists = []
        output_matches_precision_lists = []
        output_matches_recall_lists = []
        output_precision_weights_list = []
        output_recall_weights_lists = []
        for i, (summary_tokens_list, reference_tokens_list) in enumerate(zip(summary_tokens_lists, reference_tokens_lists)):
            for j, summary_tokens in enumerate(summary_tokens_list):
                if (i, j) in empty_inputs:
                    output_summary_tokens_list.append([])
                    output_reference_precision_tokens_lists.append([[]])
                    output_reference_recall_tokens_lists.append([[]])
                    output_matches_precision_lists.append([[]])
                    output_matches_recall_lists.append([[]])
                    output_precision_weights_list.append([])
                    output_recall_weights_lists.append([[]])
                else:
                    # The BertScore tokenizer only allows for 512 subword tokens (including <s> and </s>).
                    # This potentially means we need to truncate input summary
                    p_weight = precision_weights[index]
                    if len(p_weight) < len(summary_tokens) + 2:
                        print(f'Warning: Truncating summary from {len(summary_tokens)} to {len(p_weight) - 2} tokens')
                        summary_tokens = summary_tokens[:len(p_weight) - 2]

                    # The BertScore code adds <s> and </s> tokens to the start and end of the sequence. Some
                    # tokens are aligned to these special tokens. To be faithful to the original code, we allow for this
                    # by adding dummy tokens to the summaries.
                    output_summary_tokens_list.append([bos] + summary_tokens + [eos])

                    precision_index = precision_indices[index]
                    recall_index = recall_indices[index]

                    r_weight = recall_weights[index]
                    recall_reference_tokens = reference_tokens_list[recall_index]
                    if len(r_weight) < len(recall_reference_tokens) + 2:
                        print(f'Warning: Truncating reference from {len(recall_reference_tokens)} to {len(r_weight) - 2} tokens')
                        recall_reference_tokens = recall_reference_tokens[:len(r_weight) - 2]

                    output_reference_precision_tokens_lists.append([[bos] + reference_tokens_list[precision_index] + [eos]])
                    output_reference_recall_tokens_lists.append([[bos] + recall_reference_tokens + [eos]])

                    output_matches_precision_lists.append([precision_alignments_list[index]])
                    output_matches_recall_lists.append([recall_alignments_list[index]])

                    output_precision_weights_list.append(p_weight)
                    output_recall_weights_lists.append([r_weight])

                    index += 1

        return output_summary_tokens_list, output_reference_precision_tokens_lists, output_reference_recall_tokens_lists, \
               output_matches_precision_lists, output_matches_recall_lists, \
               output_precision_weights_list, output_recall_weights_lists

    def get_total_weight(self, matches: List[Tuple[int, int, float]]) -> float:
        unique_matches = set(matches)
        score = sum(weight for _, _, weight in unique_matches)
        return score