from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import permissions

schema_view = get_schema_view(
    openapi.Info(
        title="ECO TAXI",
        default_version='v1',
        description="API for Evion",
        terms_of_service="https://evion.kg",
        contact=openapi.Contact(email="evionteam1@gmail.com"),
        license=openapi.License(name="Evion"),
    ),
    public=True,
    permission_classes=[permissions.AllowAny],
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', schema_view.with_ui('swagger',
         cache_timeout=0), name='schema-swagger-ui'),
    path('user/', include('djoser.urls')),
    path('login/', include('djoser.urls.jwt')),
    path('', include('apps.users.urls')),
    path('drivers/', include('apps.drivers.urls'))
]

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL,
                          document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)


from datetime import timedelta

from django.db import models
from django.utils import timezone

class TOTPRequestQuerySet(models.QuerySet):
    def is_valid(self, receiver, request, code):
        current_time = timezone.now()
        result = self.filter(
            receiver=receiver,
            request_id=request,
            code=code,
            created__lt=current_time,
            created__gt=current_time - timedelta(seconds=300),
        ).exists()
        return result


"""
this file contains two functions, one that converts denary numbers between 255 and 0 inclusive into 8 bit unsigned binary numbers,
and another that uses the first to convert denary numbers (with the same size limitations) into 2 digit hexadecimal numbers
"""
# ive purposefully made these functions less efficient tha they could be so i would have to use more problem solving and have more fun whilst making them.

def den_to_bin_function(den_num):
    loop_counter = 0# a counter to prevent infinite loops later on in the larger while loop section

    bin_list = []# the list that the binary digits are inserted in

    if den_num > 255 or den_num < 0: # sees if den num is out of bounds of an unsigned 8 bit binary number
        return -1

    power_of_two = 0 # var to strore the order of the power of 2 that the current digit is

    for i in range(den_num):# works out the maximum order of 2 is required for the binary number e.g order 7 is 2**7 = 128
        if den_num - (2**i) > 0:
            power_of_two = i

    while den_num > 0:# the main loop that actually gets stuff done
        if den_num - 2**power_of_two > 0:# if den_num - 2**power_of_two is positive add 1 to the binary number
            den_num = den_num - 2**power_of_two
            power_of_two = power_of_two - 1# decrease the value of power_of_two by 1 so that next binary place can be checked to see if it neeeds to be a 1 or 0
            bin_list.append(1)
            # the green comments in the main code are for bug fixing

        elif den_num - 2**power_of_two < 0 and den_num > 0:# if den_num - 2**power_of_two is negativ add o to the binary number
            power_of_two = power_of_two - 1# decrease the pwer f two so that the next figot of the bianry number is checked
            bin_list.append(0)

        elif den_num - 2**power_of_two == 0:# this is so that numbers like 128 are represented properly as 1000 0000 and not 1 and have all the correct trailling 0's
            bin_list.append(1)

            den_num = den_num - 2**power_of_two# decrease the power of 2 to check neck binary digit
            if 2**power_of_two > 0:# if there are still orders of 2 go through

                while power_of_two - 1 > -1 and loop_counter < 10:# adds as many trailing 0 are needed so the binary num is corrct
                    power_of_two = power_of_two - 1
                    bin_list.append(0)
                    loop_counter += 1# makes sure the program doesnt accidently run in infinte loops, it did that a lot before adding this

    # makes all outputs 8 bit
    #print("dfdfdfdfdfdf")
    if len(bin_list) <= 8:
        num_front_padding = 8 - len(bin_list)
        for i in range(num_front_padding):
            bin_list.insert(0, 0)

        # makes the binary list into a string
        bin_num_str = "".join(map(str,bin_list))
        # returns the binary number string
        return bin_num_str

#print(den_to_bin_function(169))

# this converts denary to hex by using the previous function to convert den to bin and then converts the bin to hex

def den_to_hex(denary_num):
    # this is a dictionary conating all 4 bit binary values and their corresponding hex values
    bin_hex_dict = {
        "0000" : "0",
        "0001" : "1",
        "0010" : "2",
        "0011" : "3",
        "0100" : "4",
        "0101" : "5",
        "0110" : "6",
        "0111" : "7",
        "1000" : "8",
        "1001" : "9",
        "1010" : "A",
        "1011" : "B",
        "1100" : "C",
        "1101" : "D",
        "1110" : "E",
        "1111" : "F",
    }

    binary_num_str = den_to_bin_function(denary_num)

    hex_num_list = []# list containg hex digits

    for i in range(len(binary_num_str)//4):# finds the incusive start and exclusive end positions fro the string splicing for comparing hex and binary nibbles
        if i == 0:
            start_pos = 0
            end_pos = 4

        else:
            start_pos = i * 4 # this will be used inclusively
            end_pos = start_pos + 4 # this will be used exclusively

        #for i in range(len(binary_num_str)//4):

        print(bin_hex_dict.get(binary_num_str[start_pos:end_pos]))
        hex_num_list.append( bin_hex_dict[binary_num_str[start_pos:end_pos]])

    hex_num_str = "".join(map(str,hex_num_list))
    return hex_num_str

print(den_to_hex(15))

Feb half term homework/den_to_bin_or_hex_final_version.py


import aio_pika
import backoff
from aio_pika import exceptions

class RabbitConsumer:
    def __init__(self, dsn):
        self.dsn = dsn
        self.connection = None
        self.channel = None

    @backoff.on_exception(backoff.expo, exceptions.CONNECTION_EXCEPTIONS, max_tries=5, max_time=15)
    async def get_connection(self):
        if self.connection is None:
            self.connection = await aio_pika.connect_robust(
                self.dsn,
                timeout=10.0,
            )
        return self.connection

    @backoff.on_exception(backoff.expo, exceptions.CONNECTION_EXCEPTIONS, max_tries=5, max_time=15)
    async def get_channel(self):
        if self.connection is None:
            self.get_connection()
        if self.channel is None:
            self.channel = await self.connection.channel()
        return self.channel


import time

def parse(line):
    line = line.split(':')
    sensor = line[0]
    beacon = line[1]
    sensor = sensor[10:].split(',')
    beacon = beacon[22:].split(',')
    sensor = (int(sensor[0][2:]), int(sensor[1][3:]))
    beacon = (int(beacon[0][2:]), int(beacon[1][3:]))
    return sensor, beacon

def generate_manhattan_square(sensor, beacon, y, no_beacon_positions):
    mh_distance = abs(sensor[0] - beacon[0]) + abs(sensor[1] - beacon[1])
    y_distance = abs(sensor[1] - y)
    if y_distance <= mh_distance:
        x_distance = mh_distance - y_distance
        left = sensor[0]
        right = sensor[0]
        while right <= sensor[0] + x_distance:
            no_beacon_positions.add((left, y))
            no_beacon_positions.add((right, y))
            left -= 1
            right += 1
    no_beacon_positions.discard(beacon)

with open('input.txt') as f:
    start = time.time()
    y = 2000000
    no_beacon_positions = set()
    for line in f.read().split('\n'):
        sensor, beacon = parse(line)
        print('Checking for sensor', sensor, 'and beacon', beacon)
        generate_manhattan_square(sensor, beacon, y, no_beacon_positions)
    print('Number of positions with no beacons :', len(no_beacon_positions))
    print('Time taken :', time.time() - start)


from collections import Counter

class Solution:
    def minSetSize(self, arr: List[int]) -> int:

        c = Counter(arr).most_common()

        target_len = len(arr) // 2

        count = 0

        for i in range(len(c)):

            count += c[i][1]

            if count >= target_len: return i + 1

Reduce Array Size to The Half  Solution.py


import pandas as pd
import numpy as np
import tensorflow as tf
import re
from nltk.corpus import stopwords
import time
from tensorflow.python.layers.core import Dense
from tensorflow.python.ops.rnn_cell_impl import _zero_state_tensors

from TextProcessUtil import *
from Seq2SeqParams import *

class Seq2SeqTF(object):
    def __init__(self, params):
        self.params = params
        return None

    def model_inputs(self):
        '''Create palceholders for inputs to the model'''

        self.input_data = tf.placeholder(tf.int32, [None, None], name='input')
        self.targets = tf.placeholder(tf.int32, [None, None], name='targets')
        self.lr = tf.placeholder(tf.float32, name='learning_rate')

        self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')

        self.summary_length = tf.placeholder(tf.int32, (None,), name='summary_length')
        self.max_summary_length = tf.reduce_max(self.summary_length, name='max_dec_len')
        self.text_length = tf.placeholder(tf.int32, (None,), name='text_length')

        return self.input_data, self.targets, self.lr, self.keep_prob, self.summary_length, self.max_summary_length, self.text_length

    def process_encoding_input(self, target_data, vocab_to_int, batch_size):
        '''Remove the last word id from each batch and concat the <GO> to the begining of each batch'''

        ending = tf.strided_slice(target_data, [0, 0], [batch_size, -1], [1, 1])
        dec_input = tf.concat([tf.fill([batch_size, 1], vocab_to_int['<GO>']), ending], 1)

        return dec_input

    def encoding_layer(self, rnn_size, sequence_length, num_layers, rnn_inputs, keep_prob):
        '''Create the encoding layer'''

        for layer in range(num_layers):
            with tf.variable_scope('encoder_{}'.format(layer)):
                cell_fw = tf.contrib.rnn.LSTMCell(rnn_size,
                                                initializer=tf.random_uniform_initializer(-0.1, 0.1, seed=2))
                cell_fw = tf.contrib.rnn.DropoutWrapper(cell_fw,
                                                        input_keep_prob = keep_prob)

                cell_bw = tf.contrib.rnn.LSTMCell(rnn_size,
                                                initializer=tf.random_uniform_initializer(-0.1, 0.1, seed=2))
                cell_bw = tf.contrib.rnn.DropoutWrapper(cell_bw,
                                                        input_keep_prob = keep_prob)

                enc_output, enc_state = tf.nn.bidirectional_dynamic_rnn(cell_fw,
                                                                        cell_bw,
                                                                        rnn_inputs,
                                                                        sequence_length,
                                                                        dtype=tf.float32)
        # Join outputs since we are using a bidirectional RNN
        enc_output = tf.concat(enc_output,2)

        return enc_output, enc_state

    def training_decoding_layer(self, dec_embed_input, summary_length, dec_cell, initial_state, output_layer,
                            vocab_size, max_summary_length):
        '''Create the training logits'''

        training_helper = tf.contrib.seq2seq.TrainingHelper(inputs=dec_embed_input,
                                                            sequence_length=summary_length,
                                                            time_major=False)

        training_decoder = tf.contrib.seq2seq.BasicDecoder(dec_cell,
                                                        training_helper,
                                                        initial_state,
                                                        output_layer)

        training_logits, _, _ = tf.contrib.seq2seq.dynamic_decode(training_decoder,
                                                            output_time_major=False,
                                                            impute_finished=True,
                                                            maximum_iterations=max_summary_length)
        return training_logits

    def inference_decoding_layer(self, embeddings, start_token, end_token, dec_cell, initial_state, output_layer,
                                max_summary_length, batch_size):
        '''Create the inference logits'''

        start_tokens = tf.tile(tf.constant([start_token], dtype=tf.int32), [batch_size], name='start_tokens')

        inference_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(embeddings,
                                                                    start_tokens,
                                                                    end_token)

        inference_decoder = tf.contrib.seq2seq.BasicDecoder(dec_cell,
                                                            inference_helper,
                                                            initial_state,
                                                            output_layer)

        inference_logits, _, _ = tf.contrib.seq2seq.dynamic_decode(inference_decoder,
                                                                output_time_major=False,
                                                                impute_finished=True,
                                                                maximum_iterations=max_summary_length)

        return inference_logits

    def decoding_layer(self, dec_embed_input, embeddings, enc_output, enc_state, vocab_size, text_length, summary_length,
                    max_summary_length, rnn_size, vocab_to_int, keep_prob, batch_size, num_layers):
        '''Create the decoding cell and attention for the training and inference decoding layers'''

        for layer in range(num_layers):
            with tf.variable_scope('decoder_{}'.format(layer)):
                lstm = tf.contrib.rnn.LSTMCell(rnn_size,
                                            initializer=tf.random_uniform_initializer(-0.1, 0.1, seed=2))
                dec_cell = tf.contrib.rnn.DropoutWrapper(lstm,
                                                        input_keep_prob = keep_prob)

        output_layer = Dense(vocab_size,
                            kernel_initializer = tf.truncated_normal_initializer(mean = 0.0, stddev=0.1))

        attn_mech = tf.contrib.seq2seq.BahdanauAttention(rnn_size,
                                                    enc_output,
                                                    text_length,
                                                    normalize=False,
                                                    name='BahdanauAttention')

        dec_cell = tf.contrib.seq2seq.AttentionWrapper(dec_cell,
                                                            attn_mech,
                                                            rnn_size)

        initial_state = dec_cell.zero_state(dtype=tf.float32, batch_size=batch_size)
        #initial_state = tf.contrib.seq2seq.AttentionWrapperState(enc_state[0],
        #                                                               _zero_state_tensors(rnn_size,
        #                                                                                batch_size,
        #                                                                                tf.float32),
        #                                                        time = 0 ,alignments=None , alignment_history=())
        with tf.variable_scope("decode"):
            training_logits = self.training_decoding_layer(dec_embed_input,
                                                    summary_length,
                                                    dec_cell,
                                                    initial_state,
                                                    output_layer,
                                                    vocab_size,
                                                    max_summary_length)
        with tf.variable_scope("decode", reuse=True):
            inference_logits = self.inference_decoding_layer(embeddings,
                                                        vocab_to_int['<GO>'],
                                                        vocab_to_int['<EOS>'],
                                                        dec_cell,
                                                        initial_state,
                                                        output_layer,
                                                        max_summary_length,
                                                        batch_size)

        return training_logits, inference_logits

    def seq2seq_model(self,input_data, target_data, keep_prob, text_length, summary_length, max_summary_length,
                  vocab_size, rnn_size, num_layers, vocab_to_int, batch_size, word_embedding_matrix):
        '''Use the previous functions to create the training and inference logits'''

        # Use Numberbatch's embeddings and the newly created ones as our embeddings
        embeddings = word_embedding_matrix

        enc_embed_input = tf.nn.embedding_lookup(embeddings, input_data)
        enc_output, enc_state = self.encoding_layer(rnn_size, text_length, num_layers, enc_embed_input, keep_prob)

        dec_input = self.process_encoding_input(target_data, vocab_to_int, batch_size)
        dec_embed_input = tf.nn.embedding_lookup(embeddings, dec_input)

        training_logits, inference_logits  = self.decoding_layer(dec_embed_input,
                                                            embeddings,
                                                            enc_output,
                                                            enc_state,
                                                            vocab_size,
                                                            text_length,
                                                            summary_length,
                                                            max_summary_length,
                                                            rnn_size,
                                                            vocab_to_int,
                                                            keep_prob,
                                                            batch_size,
                                                            num_layers)

        return training_logits, inference_logits

    def buildGraph(self,vocab_to_int, word_embedding_matrix):
        # Build the graph
        self.train_graph = tf.Graph()
        # Set the graph to default to ensure that it is ready for training
        with self.train_graph.as_default():

            # Load the model inputs
            input_data, targets, lr, keep_prob, summary_length, max_summary_length, text_length = self.model_inputs()

            # Create the training and inference logits
            training_logits, inference_logits = self.seq2seq_model(tf.reverse(input_data, [-1]),
                                                            targets,
                                                            keep_prob,
                                                            text_length,
                                                            summary_length,
                                                            max_summary_length,
                                                            len(vocab_to_int)+1,
                                                            self.params.rnn_size,
                                                            self.params.num_layers,
                                                            vocab_to_int,
                                                            self.params.batch_size,
                                                            word_embedding_matrix)

            # Create tensors for the training logits and inference logits
            training_logits = tf.identity(training_logits.rnn_output, 'logits')
            inference_logits = tf.identity(inference_logits.sample_id, name='predictions')

            # Create the weights for sequence_loss
            masks = tf.sequence_mask(summary_length, max_summary_length, dtype=tf.float32, name='masks')

            with tf.name_scope("optimization"):
                # Loss function
                self.cost = tf.contrib.seq2seq.sequence_loss(
                    training_logits,
                    targets,
                    masks)

                # Optimizer
                optimizer = tf.train.AdamOptimizer(self.params.learning_rate)

                # Gradient Clipping
                gradients = optimizer.compute_gradients(self.cost)
                capped_gradients = [(tf.clip_by_value(grad, -5., 5.), var) for grad, var in gradients if grad is not None]
                self.train_op = optimizer.apply_gradients(capped_gradients)
        print("Graph is built.")

    def train(self,sorted_summaries_short, sorted_texts_short, summaries_lengths, texts_lengths,vocab_to_int):
        # Train the Model
        learning_rate_decay = 0.95
        min_learning_rate = 0.0005
        display_step = 20 # Check training loss after every 20 batches
        stop_early = 0
        stop = 3 # If the update loss does not decrease in 3 consecutive update checks, stop training
        per_epoch = 3 # Make 3 update checks per epoch
        update_check = (len(sorted_texts_short)//self.params.batch_size//per_epoch)-1

        update_loss = 0
        batch_loss = 0
        summary_update_loss = [] # Record the update losses for saving improvements in the model

        checkpoint = "best_model.ckpt"
        with tf.Session(graph=self.train_graph) as sess:
            sess.run(tf.global_variables_initializer())

            # If we want to continue training a previous session
            #loader = tf.train.import_meta_graph("./" + checkpoint + '.meta')
            #loader.restore(sess, checkpoint)

            for epoch_i in range(1, self.params.epochs+1):
                update_loss = 0
                batch_loss = 0
                for batch_i, (summaries_batch, texts_batch, summaries_lengths, texts_lengths) in enumerate(
                        get_batches(sorted_summaries_short, sorted_texts_short, self.params.batch_size,vocab_to_int)):
                    start_time = time.time()
                    _, loss = sess.run(
                        [self.train_op, self.cost],
                        {self.input_data: texts_batch,
                        self.targets: summaries_batch,
                        self.lr: self.params.learning_rate,
                        self.summary_length: summaries_lengths,
                        self.text_length: texts_lengths,
                        self.keep_prob: self.params.keep_probability})

                    batch_loss += loss
                    update_loss += loss
                    end_time = time.time()
                    batch_time = end_time - start_time

                    if batch_i % display_step == 0 and batch_i > 0:
                        print('Epoch {:>3}/{} Batch {:>4}/{} - Loss: {:>6.3f}, Seconds: {:>4.2f}'
                            .format(epoch_i,
                                    self.params.epochs,
                                    batch_i,
                                    len(sorted_texts_short) // self.params.batch_size,
                                    batch_loss / display_step,
                                    batch_time*display_step))
                        batch_loss = 0

                    if batch_i % update_check == 0 and batch_i > 0:
                        print("Average loss for this update:", round(update_loss/update_check,3))
                        summary_update_loss.append(update_loss)

                        # If the update loss is at a new minimum, save the model
                        if update_loss <= min(summary_update_loss):
                            print('New Record!')
                            stop_early = 0
                            saver = tf.train.Saver()
                            saver.save(sess, checkpoint)

                        else:
                            print("No Improvement.")
                            stop_early += 1
                            if stop_early == stop:
                                break
                        update_loss = 0

                # Reduce learning rate, but not below its minimum value
                self.params.learning_rate *= learning_rate_decay
                if self.params.learning_rate < min_learning_rate:
                    self.params.learning_rate = min_learning_rate

                if stop_early == stop:
                    print("Stopping Training.")
                    break


from odoo import api, fields, models, _
from odoo.exceptions import UserError

class ResPartner(models.Model):
    _inherit = 'res.partner'

    address_indicator = fields.Selection([('residential', "🏠 Residential"), ('commercial', "🏢 Commercial")], readonly=True)
    ship_stored_hash = fields.Char(readonly=True)
    ship_live_hash = fields.Char(compute='_compute_ship_address_dirty', store=True)
    ship_address_dirty = fields.Boolean(compute='_compute_ship_address_dirty', store=True)

    @api.model
    def get_address_hash(self, street: str, street2: str, city: str, state_id: int, zip: str, country_id: int, address_indicator):
        return hash((
            street or False,
            street2 or False,
            city or False,
            int(state_id or False),
            zip or False,
            int(country_id or False),
            address_indicator or False
        ))

    @api.depends('street', 'street2', 'city', 'state_id', 'zip', 'country_id', 'address_indicator', 'ship_stored_hash')
    def _compute_ship_address_dirty(self):
        """ Has the address changed since the last verification? """

        for partner_id in self:
            partner_id.ship_live_hash = self.get_address_hash(
                partner_id.street,
                partner_id.street2,
                partner_id.city,
                partner_id.state_id.id,
                partner_id.zip,
                partner_id.country_id.id,
                partner_id.address_indicator
            )
            partner_id.ship_address_dirty = partner_id.ship_stored_hash != partner_id.ship_live_hash

    def action_verify_ship_address(self):
        self.ensure_one()

        ship_api_id = self.env.user.company_id.address_verify_ship_api_id
        if ship_api_id:
            success, message, user_confirm, data = ship_api_id._verify_address(
                self.name,
                self.commercial_partner_id.name,
                self.phone or self.mobile
                or self.parent_id.phone or self.parent_id.mobile
                or self.commercial_partner_id.phone or self.commercial_partner_id.mobile,
                self.street,
                self.street2,
                self.city,
                self.state_id.code,
                self.zip,
                self.country_id.code
            )
            if success:
                if user_confirm:
                    data.update({'partner_id': self.id, 'message': message})
                    return {
                        'name': "Verify Address",
                        'view_mode': 'form',
                        'res_model': 'res.partner.verify',
                        'res_id': self.env['res.partner.verify'].create(data).id,
                        'type': 'ir.actions.act_window',
                        'target': 'new'
                    }
                else:
                    self.write(data)
                    self.ship_stored_hash = self.ship_live_hash
            else:
                raise UserError(_("Could not verify the shipping address. Please double check it carefully.\n\n%s") % message)
        else:
            raise UserError(_("Odoo has not been setup for address verification yet.\nPlease select the shipping api to use for address verification in settings."))


import shutil

from jinja2 import Environment, FileSystemLoader

from fixtures import stream_list, topic_list, chat_list
from config import BASE_URL, INSTANCE_TITLE

environment = Environment(loader=FileSystemLoader("templates"), autoescape=True)
stream_list_template = environment.get_template("stream_list.html.jinja2")
topic_list_template = environment.get_template("topic_list.html.jinja2")
topic_chat_template = environment.get_template("topic_chat.html.jinja2")

with open("./rendered/index.html", mode="w+", encoding="utf-8") as f:
    f.write(
        stream_list_template.render(
            base_url=BASE_URL,
            page_title=INSTANCE_TITLE,
            title=INSTANCE_TITLE,
            last_updated_str="Archived on August 17th 2022 at 11.00 AM UTC",
            stream_list=stream_list,
        )
    )
with open("./rendered/stream.html", mode="w+", encoding="utf-8") as f:
    f.write(
        topic_list_template.render(
            base_url=BASE_URL,
            page_title=f"# lorem ipsum | {INSTANCE_TITLE}",
            title=INSTANCE_TITLE,
            last_updated_str="Archived on August 17th 2022 at 11.00 AM UTC",
            topic_list=topic_list,
            stream_name="lorem ipsum",
            stream_url=f"{BASE_URL}/stream.html",
            rendered_description="""
For discussions of the API, integrations, and bots and in Zulip.
""",
        )
    )
with open("./rendered/topic.html", mode="w+", encoding="utf-8") as f:
    f.write(
        topic_chat_template.render(
            base_url=BASE_URL,
            page_title=f"Le fishe swimming in a bathtub - # lorem ipsum | {INSTANCE_TITLE}",
            title=INSTANCE_TITLE,
            last_updated_str="Archived on August 17th 2022 at 11.00 AM UTC",
            chat_list=chat_list,
            stream_name="lorem ipsum",
            stream_url=f"{BASE_URL}/stream.html",
            topic_name="Le fishe swimming in a bathtub",
            num_messages=3,
        )
    )

# Copy needed assets to /rendered
shutil.copytree("templates/assets", "rendered/assets", dirs_exist_ok=True)


import re

import discord
import asyncio
import random
from datetime import datetime, timedelta
from pytz import timezone
import pytz
import help_commands

from discord.ext import commands

class misc_commands(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.sent_message = False

    @commands.is_owner()
    @commands.command(aliases=["del"])
    async def delete_messages(self, ctx, amount=1):
        async for message in ctx.channel.history(limit = int(amount)+1):
            await message.delete()

    @commands.command()
    async def repeat(self, ctx, *, words):
        await ctx.send(words)

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.author == self.bot.user:
            return
        try:
            prefix = help_commands.get_prefix(message)
            if "prefix" in message.content and not message.content.startswith(
                    f"{prefix}prefix"):
                await message.channel.send(f"My prefix is \"{prefix}\"")
        except Exception as e:
            print("from on_message prefix func: error occured", e)

def setup(bot):
    bot.add_cog(misc_commands(bot))


#! /usr/bin/env python3

import rospy
import numpy as np
from nav_msgs.msg import OccupancyGrid
import math
from tf.transformations import quaternion_from_euler

def load_param(name, value=None):
    if value is None:
        assert rospy.has_param(name), f'Missing parameter "{name}"'
    return rospy.get_param(name, value)

class GridMapInterface(object):
    _gridmap_msg = None
    _gridmap_sub = None
    _map_topic = None
    _gridmap = None

    def __init__(self):
        self._map_topic = load_param('~map_topic', '/map')

    def init_ros_subscribers(self):
        self._gridmap_sub = rospy.Subscriber(self._map_topic, OccupancyGrid, self._gridmap_cb, queue_size=1)

    def _gridmap_cb(self, msg):
        self._gridmap_msg = OccupancyGrid(msg.header, msg.info, msg.data)

    def _get_delta(self):
        if self._gridmap_msg  is not None:
            return [self._gridmap_msg.info.resolution, self._gridmap_msg.info.resolution]

    def _get_limits(self):
        if self._gridmap_msg is not None:
            return [[0, self._gridmap_msg.info.width * self._gridmap_msg.info.resolution], [0, self._gridmap_msg.info.height * self._gridmap_msg.info.resolution]]

    def _get_obstacles(self):
        if self._gridmap_msg  is not None:
            gridmap = np.array(self._gridmap_msg.data).reshape((self._gridmap_msg.info.height, self._gridmap_msg.info.width)).T * 0.01
            # Cell values are changed to -0.01 (unknown), 0 (free), 1 (obstacle)
            obstacles = []
            for (x, y), cell in np.ndenumerate(gridmap):
                #!! Strong assumption: unknown cells are considered as obstacles
                if cell < 0 or cell == 1:
                    obstacles.append([x, y, self._gridmap_msg.info.resolution])
            return obstacles

    def get_planner_world(self):
        while self._gridmap_msg is None:
            continue
        return self._get_delta(), self._get_limits(), self._get_obstacles()

    def publish_map_internal_representation(self):
        obstacles = []
        delta, limits, obs = self.get_planner_world()

        rows_int = int(np.round(limits[0][1] / delta[0]))
        cols_int = int(np.round(limits[1][1] / delta[1]))
        data = np.zeros(rows_int * cols_int).reshape(rows_int, cols_int)
        [obstacles.append(tup[0:2]) for tup in obs]
        obs_np = np.asarray(obstacles)
        data[obs_np[:, 0], obs_np[:, 1]] = 100

        map_pub = rospy.Publisher('/map_from_grid', OccupancyGrid, latch=True, queue_size=1)
        map_msg = OccupancyGrid()
        map_msg.data = [item for sublist in np.array(data, dtype=int).tolist() for item in sublist]
        map_msg.header.frame_id = 'map'
        map_msg.header.stamp = rospy.Time.now()
        map_msg.info.resolution = delta[1]
        map_msg.info.width = cols_int
        map_msg.info.height = rows_int
        quat = quaternion_from_euler(0, math.pi , -math.pi / 2)
        map_msg.info.origin.orientation.x = quat[0]
        map_msg.info.origin.orientation.y = quat[1]
        map_msg.info.origin.orientation.z = quat[2]
        map_msg.info.origin.orientation.w = quat[3]

        print('Publishing map...')
        map_pub.publish(map_msg)


# B. Tech Project
# HANDWRITTEN FORMULAE DETECTION
# Semester 7
# December 2020
# Dr. Gaurav Harit
# Shashwat Kathuria - B17CS050
# Satya Prakash Sharma - B17CS048

# Importing required libraries
import os, random, time
from tkinter import *
from PIL import Image, ImageDraw, ImageTk
from collections import defaultdict

# Defining constants required
# Temp and output directories
TEMP_POSTSCRIPT_IMAGE_DIRECTORY = 'Modified_Text_PDF_Images/'
TEXT_ANNOTATIONS_DIRECTORY = 'Handwritten_Images_Text_Annotations/'
FORMULA_ANNOTATIONS_DIRECTORY = 'Handwritten_Images_Formula_Annotations/'
IMAGES_DIRECTORY = 'Handwritten_Images/'

# Input directories
FORMULAS_DIRECTORY = 'Handwritten_Formula_Images/'
TEXT_DIRECTORY = 'Handwritten_Sentences/'

# Some constants for output images
LEFT_MARGIN = 20
RIGHT_MARGIN = 20
BOTTOM_MARGIN = 40
PDF_HEIGHT = 1000
PDF_WIDTH = 700
PARA_GAP = 90
FORMULA_GAP = 45
LINE_GAP = 13

def main():
    '''Main function.'''

    # Calling function to create output and temp directories
    createDirectories()

    # Calling function to get input formula images
    formulasArray = getInputFormulaImages()

    # Calling function to get input text images
    textImagesDict = getInputTextImages()

    root = Tk()

    # Initializing empty white canvas with specififed width and height
    cv = Canvas(root, width = PDF_WIDTH, height = PDF_HEIGHT, bg = 'white')

    # Converting all formula images in list to tkinter PhotoImage object
    # Initializing temp list
    tempFormulasArray = []
    # Looping through array
    for formulaImage in formulasArray:
        # Converting to PhotoImage object
        tkImg = ImageTk.PhotoImage(formulaImage)
        # Appending PhotoImage object and image size to array
        tempFormulasArray.append([tkImg, formulaImage.size])
    formulasArray = tempFormulasArray

    # Generating synthetic pdf images with text and formula

    # Looping through keyed common handwritings
    for key in textImagesDict:
        # 50 images per handwriting
        for pageNo in range(50):
            # Random seed
            random.seed(time.time())

            # Initializing text and formula annotation file to write
            textAnnotationFile = open(TEXT_ANNOTATIONS_DIRECTORY + key + str(pageNo) + '.txt', 'w')
            formulaAnnotationFile = open(FORMULA_ANNOTATIONS_DIRECTORY + key + str(pageNo) + '.txt', 'w')

            # Converting all text images in list to tkinter PhotoImage object
            # Initializing temp list
            textImagesArray = []
            # Looping through array
            for image in textImagesDict[key]:
                # Converting to PhotoImage object
                tkImg = ImageTk.PhotoImage(image)
                # Appending PhotoImage object and image size to array
                textImagesArray.append([tkImg, image.size])

            # Shuffling array
            random.shuffle(textImagesArray)

            # Initializing variables required
            paraCount = 1
            numberOfParas = random.randint(4, 6)

            # Initial height, and x1 and y1(=height)
            height = 20
            x1 = LEFT_MARGIN
            y1 = height

            # Add text and formulas until the page is not completely filled
            while height < PDF_HEIGHT - BOTTOM_MARGIN:
                # Random seed
                random.seed(time.time())

                # Randomly shuffling arrays
                random.shuffle(textImagesArray)
                random.shuffle(formulasArray)

                # Initializing variables required
                # Sentence starts from LEFT_MARGIN
                width = LEFT_MARGIN
                # Variable for maxHeight of whole sentence
                maxHeight = textImagesArray[0][1][1]
                # Keeping track of number of images added
                counter = 0

                # Looping through textImagesArray to add text and formulas
                for element in textImagesArray:

                    # Randomly adding formula to sentence
                    if random.random() > 0.99:
                        isFormula = True
                        imageElement = random.sample(formulasArray, 1)[0]
                        imggg = imageElement[0]
                        imgggSize = imageElement[1]
                    # Else adding plain text
                    else:
                        isFormula = False
                        imggg = element[0]
                        imgggSize = element[1]

                    # If element goes out of page width, skip and go on to next one
                    if width + imgggSize[0] > PDF_WIDTH - RIGHT_MARGIN:
                        continue
                    # If element goes out of page height, skip and go on to next one
                    if height + imgggSize[1] > PDF_HEIGHT - BOTTOM_MARGIN:
                        continue
                    # Incrementing counter as now image will be added
                    counter += 1
                    # Adding image to canvas
                    cv.create_image(width, height, anchor = NW, image = imggg)

                    # If a formula, add annotation also
                    if isFormula:
                        # Formula bounding box annotation
                        formulaX1 = width
                        formulaX2 = width + imgggSize[0]
                        formulaY1 = height
                        formulaY2 = height + imgggSize[1]

                        # Adding annotation to file
                        formulaAnnotationFile.write(str(formulaX1) + ' ' + str(formulaY1) + ' ' + str(formulaX2) + ' ' + str(formulaY2) + '\n')

                        # Uncomment below line to see the annotations in action in tkinter canvas
                        # cv.create_line(formulaX1, formulaY1, formulaX2, formulaY2, fill="blue")

                    # Incrementing width and max height of sentence elements accordingly
                    width += imgggSize[0]
                    maxHeight = max(maxHeight, imgggSize[1])

                # If images added, add max height and line gap
                if counter > 0:
                    height += maxHeight + LINE_GAP
                # If no image added, add line gap
                else:
                    height += LINE_GAP

                # Randomly adding paragraph breaks in text with maximum as numberOfParas
                if random.random() > 0.8 and paraCount < numberOfParas:

                    # Adding text annotation as para ends here
                    x2 = PDF_WIDTH - RIGHT_MARGIN
                    y2 = height
                    # Adding annotation to file
                    textAnnotationFile.write(str(x1) + ' ' + str(y1) + ' ' + str(x2) + ' ' + str(y2) + '\n')
                    # Uncomment below line to see the annotations in action in tkinter canvas
                    # cv.create_line(x1, y1, x2, y2, fill = "red")

                    # Initializing variables required
                    height += FORMULA_GAP
                    numberOfFormulas = random.randint(1, 3)

                    # Add horizontal formula alignment randomly if even number of formulas
                    if random.random() > 0.3 and numberOfFormulas == 2:

                        # Initializing variable required
                        maxHeight = 0
                        factor = int((PDF_WIDTH - LEFT_MARGIN - RIGHT_MARGIN) / 4)
                        counter = 0

                        # Looping
                        for i in [1, 3]:
                            # Randomly chosse a formula from list
                            formula = random.sample(formulasArray, 1)[0]
                            formulaImage = formula[0]
                            formulaImageSize = formula[1]

                            # If element goes out of page width, skip and go on to next one
                            if LEFT_MARGIN + formulaImageSize[0] > PDF_WIDTH - RIGHT_MARGIN:
                                continue
                            # If element goes out of page height, skip and go on to next one
                            if height + formulaImageSize[1] > PDF_HEIGHT - BOTTOM_MARGIN:
                                continue

                            # Incrementing counter as now image will be added
                            counter += 1

                            # Adding bounding box coordinates accordingly
                            initialWidth = int( (factor * i) - (formulaImageSize[0] / 2) )
                            formulaX1 = initialWidth
                            formulaX2 = initialWidth + formulaImageSize[0]
                            formulaY1 = height
                            formulaY2 = height + formulaImageSize[1]
                            # Adding annotation to file
                            formulaAnnotationFile.write(str(formulaX1) + ' ' + str(formulaY1) + ' ' + str(formulaX2) + ' ' + str(formulaY2) + '\n')
                            # Adding image to canvas
                            cv.create_image(initialWidth, height, anchor = NW, image = formulaImage)

                            # Uncomment below line to see the annotations in action in tkinter canvas
                            # cv.create_line(formulaX1, formulaY1, formulaX2, formulaY2, fill="blue")

                            # Updating formula line max height
                            maxHeight = max(maxHeight, formulaImageSize[1])

                        # If images added, add max height and line gap
                        if counter > 0:
                            height += maxHeight + PARA_GAP
                        # If images added, add line gap
                        else:
                            height += PARA_GAP
                    # Vertical formula alignment
                    else:

                        # Looping through number of formulas to be added
                        for i in range(numberOfFormulas):
                            # Randomly chosse a formula from list
                            formula = random.sample(formulasArray, 1)[0]
                            formulaImage = formula[0]
                            formulaImageSize = formula[1]

                            # If element goes out of page width, skip and go on to next one
                            if LEFT_MARGIN + formulaImageSize[0] > PDF_WIDTH - RIGHT_MARGIN:
                                continue
                            # If element goes out of page height, skip and go on to next one
                            if height + formulaImageSize[1] > PDF_HEIGHT - BOTTOM_MARGIN:
                                continue

                            # Adding bounding box coordinates accordingly
                            initialWidth = int( (PDF_WIDTH - LEFT_MARGIN - RIGHT_MARGIN - formulaImageSize[0]) / 2)
                            formulaX1 = initialWidth
                            formulaX2 = initialWidth + formulaImageSize[0]
                            formulaY1 = height
                            formulaY2 = height + formulaImageSize[1]

                            # Adding annotation to file
                            formulaAnnotationFile.write(str(formulaX1) + ' ' + str(formulaY1) + ' ' + str(formulaX2) + ' ' + str(formulaY2) + '\n')

                            # Adding image to canvas
                            cv.create_image(initialWidth, height, anchor = NW, image = formulaImage)

                            # Uncomment below line to see the annotations in action in tkinter canvas
                            # cv.create_line(formulaX1, formulaY1, formulaX2, formulaY2, fill="blue")

                            # Updating height
                            height += formulaImageSize[1] + 20

                    # Uncomment below line to see the annotations in action in tkinter canvas
                    # cv.create_line(0,height,PDF_WIDTH,height, fill="blue")

                    # New para starts, updating values of x1 and y1
                    paraCount += 1
                    x1 = LEFT_MARGIN
                    y1 = height

            # End of text para, updating values
            x2 = PDF_WIDTH - RIGHT_MARGIN
            y2 = height
            # cv.create_line(x1, y1, x2, y2, fill="red")

            cv.pack()
            cv.update()
            # Adding postscript output to file
            cv.postscript(colormode = 'color', file = TEMP_POSTSCRIPT_IMAGE_DIRECTORY + key + str(pageNo) + '.eps', pagewidth=PDF_WIDTH -1, pageheight=PDF_HEIGHT-1)
            # Generating image object from above postscript output
            img = Image.open(TEMP_POSTSCRIPT_IMAGE_DIRECTORY + key + str(pageNo) + '.eps')
            # Saving generated image as png
            img.save(IMAGES_DIRECTORY + key + str(pageNo) + '.png', 'png')
            # Clearing canvas for next page generation
            cv.delete('all')

    # Root mainloop
    root.mainloop()

def getInputTextImages():
    '''Function to get processed text images dict keyed according to common handwritings.'''

    # Initializing dict (keyed according to common handwritings) and scaling factor
    # Default element in textImagesDict is an empty list
    textImagesDict = defaultdict(list)
    scalingFactor = 3.25

    # Looping through all the text images
    for index, filename in enumerate(sorted(os.listdir(TEXT_DIRECTORY))[:3000]):
        # Initializing image object
        img = Image.open(TEXT_DIRECTORY + filename)
        # Resizing according to scaling factor
        img = img.resize((int(img.size[0] / scalingFactor), int(img.size[1] / scalingFactor)), Image.ANTIALIAS)
        if filename[:3] not in ['b06', 'c03', 'c06', 'g06', 'd06']: # 'do6'
            # Appending to array of keyed element in dict
            textImagesDict[filename[:3]].append(img)

    # Returning dict
    return textImagesDict

def getInputFormulaImages():
    '''Function to get processed formula images array.'''

    # Initializing list and scaling factor
    formulasArray = []
    scalingFactor = 4.25

    # Looping through all the formulas images
    for index, filename in enumerate(sorted(os.listdir(FORMULAS_DIRECTORY))):
        # Initializing image object
        img = Image.open(FORMULAS_DIRECTORY + filename)
        if img.size[0] == 523:
            if img.size[1] > 120 and img.size[1] < 200:
                # Resizing according to scaling factor
                img = img.resize((int(img.size[0] / scalingFactor), int(img.size[1] / scalingFactor)), Image.ANTIALIAS)
                # Appending to array
                formulasArray.append(img)

    # Returning array
    return formulasArray

def createDirectories():
    '''Function to create directories required. Ignoring if already created.'''

    # Initializing directories to be created
    directoriesToCreate = [
        TEMP_POSTSCRIPT_IMAGE_DIRECTORY,
        IMAGES_DIRECTORY,
        TEXT_ANNOTATIONS_DIRECTORY,
        FORMULA_ANNOTATIONS_DIRECTORY
    ]

    # Looping through list
    for directoryName in directoriesToCreate:
        # Create directory
        try:
            os.mkdir(directoryName)
        # Ignore if already exists
        except FileExistsError:
            pass

# Calling main function
if __name__ == "__main__":
    main()


import matplotlib
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
from cherab.core.math import Slice3D, sample3d_points, samplevector2d_grid, samplevector3d_grid, samplevector3d_points, ConstantVector3D, sample2d_grid, sample3d_points, samplevector3d_grid
from cherab.core import Plasma
from cherab.core.atomic.elements import carbon, deuterium

def plot_contour(function3d):

    #Extracting the Distribution function strength frtom the plasam object
    X = [0]
    Y = np.linspace(0,1.75,100)
    Z = np.linspace(-1.5, 1.5 ,100)
    Dist = np.squeeze(sample2d_grid(Slice3D(function3d,'x',0),Y,Z))

    #plotting the Bfield
    fig, ax = plt.subplots()
    CS = ax.contour(Y, Z, np.transpose(Dist), levels = 20)
    fmt = ticker.ScalarFormatter()
    fmt.set_scientific(True)
    fmt.set_powerlimits((0,1))
    fmt.create_dummy_axis()
    ax.clabel(CS, inline = 1, fmt = fmt )
    ax.set_title('Density [per m^3]')
    ax.set(xlabel = '[m]', ylabel = '[m]')
    cbar = fig.colorbar(CS, cmap='plasma', extend='both')
    cbar.minorticks_on()
    plt.show()

    """
    #Extracting the Bfield strength frtom the plasam object
    X = [0]
    Y = np.linspace(0,2,100)
    Z = np.linspace(-2.2, 2.2 ,200)
    B_field3D = np.squeeze(samplevector3d_grid(plasma.b_field,X,Y,Z))
    B_field3DScalar = np.linalg.norm(B_field3D,axis = 2)
    """

def plot_contourSCP(function3d):

    plt.rc('font', size=18)
    plt.rc('axes', titlesize=18)
    plt.rc('axes', labelsize=18)
    plt.rc('xtick', labelsize=18)
    plt.rc('ytick', labelsize=18)
    plt.rc('legend', fontsize=18)
    plt.rc('figure', titlesize=20)

    #Extracting the Distribution function strength frtom the plasam object
    X = [0]
    Y = np.linspace(0,1.75,500)
    Z = np.linspace(-1.5, 1.5 ,500)
    Dist = np.squeeze(sample2d_grid(Slice3D(function3d,'x',0),Y,Z))

    Dist = np.ma.masked_where(Dist < 0.01,Dist)
    cmap = plt.cm.RdGy_r
    cmap.set_bad(color='red',alpha = 0)
    #plotting the Bfield
    fig, ax = plt.subplots(figsize = (6,7))
    ax.imshow(Dist.T,extent = [0,1.75,-1.5,1.5],cmap = cmap,origin = 'lower',alpha = 0.9)
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    ax.spines['bottom'].set_color('snow')
    ax.spines['left'].set_color('snow')
    ax.xaxis.label.set_color('snow')
    ax.yaxis.label.set_color('snow')
    ax.tick_params(axis='both', colors='snow')
    ax.set_xticks([0,0.5,1,1.5])
    # ax.yaxis.set_ticks_position('left')
    # ax.xaxis.set_ticks_position('bottom')

    plt.xlabel('R (m)')
    plt.ylabel('Z (m)')
    # plt.title('Sampled Balmer Series Spectrum')
    fig.savefig('SCP/TokDensDeu.png', transparent=True)
    plt.show()

def plot_velocity(function3Dvector):

    X = [0]
    Y = np.linspace(0, 1.75, 100)
    X2 = np.linspace(0, 1.75, 100)
    Y2 = [0]
    Z = np.linspace(-1.5, 1.5, 100)
    Z2 = np.zeros(100)
    midline = np.array([Z2,Y,Z2]).T
    print(midline.shape)
    values = np.linalg.norm(np.squeeze(samplevector3d_grid(function3Dvector,X,Y,Z)),axis=2).T
    valuesRot = np.linalg.norm(np.squeeze(samplevector3d_grid(function3Dvector, X2, Y2, Z)), axis=2).T
    ValuesMid = np.linalg.norm(np.squeeze(samplevector3d_points(function3Dvector, midline)), axis=1).T

    fig, [ax,ax3] = plt.subplots(2,1)
    im = ax.imshow(values, vmin = np.min(values), vmax = np.max(values))
    #im2 = ax2.imshow(valuesRot, vmin=np.min(values), vmax=np.max(values))
    ax.set_aspect('equal')
    ax.set(title = 'particle velocity')
    cbar = fig.colorbar(im, cmap = 'plasma' ,extend = 'both',label = 'velocity [m/s]')
    cbar.minorticks_on()
    #ax2.set_aspect('equal')
    #ax2.set(title='particle velocity')
    ax3.plot(Y,ValuesMid,marker = 'o')

    plt.show()
def plot_mag_field(function3Dvector):
    X = [0]
    Y = np.linspace(0.1, 1.5, 10)
    Z = np.linspace(-2, 2, 10)

    values = np.linalg.norm(np.squeeze(samplevector2d_grid(function3Dvector,Y,Z)),axis=2).T

    fig, [ax, ax1] = plt.subplots(2,1)
    im = ax.imshow(values, vmin = np.min(values), vmax = np.max(values))

    ax.set_aspect('equal')
    ax.set(title = 'Magnetic Field')
    cbar = fig.colorbar(im, cmap = 'plasma' ,extend = 'both',label = 'B-Field [T]')
    cbar.minorticks_on()

    plt.show()

def save_parameters(plasma,filename):
    vel = save_velocity(plasma.composition[carbon, 6].distribution.bulk_velocity)
    temp =save_temperature(plasma.composition[carbon, 6].distribution.effective_temperature)
    den =save_density(plasma.composition[carbon, 6].distribution.density)
    dden = save_edensity(plasma.composition[deuterium, 1].distribution.density)
    eden = save_edensity(plasma.electron_distribution.density)
    np.savez('Data/Inputs/InputData%s' %filename, velocity = vel, temperature = temp, density = den, edensity = eden, ddensity = dden, zeff = save_Zeff(plasma), b_field = save_Bfield(plasma)) #, edensity = eden
    return

def save_velocity(function3Dvector):
    Y = np.load('Data/Inputs/RtoFnumber.npy')
    Z2 = np.zeros(np.size(Y))
    midline = np.array([Z2,Y,Z2]).T
    ValuesMid = np.linalg.norm(np.squeeze(samplevector3d_points(function3Dvector, midline)), axis=1).T
    return np.stack([ValuesMid, Y])

def save_temperature(function3D):
    Y = np.load('Data/Inputs/RtoFnumber.npy')
    X = np.zeros(np.size(Y))
    Z = np.zeros(np.size(Y))
    midline = np.array([X, Y, Z]).T
    ValuesMid = sample3d_points(function3D,midline)
    return np.stack([ValuesMid, Y])

def save_density(function3D):
    Y = np.load('Data/Inputs/RtoFnumber.npy')
    X = np.zeros(np.size(Y))
    Z = np.zeros(np.size(Y))
    midline = np.array([X, Y, Z]).T
    ValuesMid = sample3d_points(function3D,midline)
    return np.stack([ValuesMid, Y])

def save_edensity(function3D):
    Fiber_to_R = np.load('Data/Inputs/RtoFnumber.npy')
    X = np.zeros(np.size(Fiber_to_R))
    Y = Fiber_to_R
    Z = np.zeros(np.size(Fiber_to_R))
    midline = np.array([X, Y, Z]).T
    ValuesMid = sample3d_points(function3D,midline)
    return  ValuesMid

def save_Zeff(plasma):
    Y = np.load('Data/Inputs/RtoFnumber.npy')
    ValuesMid = np.zeros(np.size(Y))
    for i, y in enumerate(Y[2:]):
        ValuesMid[i+2] = plasma.z_effective(0,y,0)
    print(ValuesMid)
    return ValuesMid

def save_Bfield(plasma):
    Y = np.load('Data/Inputs/RtoFnumber.npy')
    print(Y.shape)
    ValuesMid = np.zeros(np.size(Y))
    for i, y in enumerate(Y):
        ValuesMid[i] = plasma.b_field(0,y,0).length
    return ValuesMid


NOFIGKIND = ''
VIOLINCHART = 'violin'
SWARMCHART = 'swarm'
BARCHART = 'bar'
JOINTCHART = 'joint'
HEATMAP = 'heat'
PIECHART = 'pie'
WORDCLOUD = 'wcloud'

VALID_FIGURE_KINDS = [NOFIGKIND, VIOLINCHART, SWARMCHART, BARCHART, JOINTCHART, HEATMAP, PIECHART, WORDCLOUD]

YES = 'y'
NO = 'n'

YES_NO = [YES, NO]

OUTFOLDER_F = '-o'
GRAPHKIND_F = '-k'
FILENAME_F = '-q'
COLLIST_F = '-l'
SUPFILE_F = '-t'
STOPWORDS_F = '-s'
VIEWFIGURE_F = '-v'
INTERACTIVE_F = '-i'
HELP_F = '-h'

VALID_FLAGS = {
    OUTFOLDER_F: 'output folder',
    GRAPHKIND_F: 'kind of graph',
    FILENAME_F: 'filename for the output graph',
    COLLIST_F: 'file with list of column IDs to use',
    SUPFILE_F: 'filename for supporting text file (multiple uses)',
    STOPWORDS_F: 'file with custom stopwords for word cloud',
    VIEWFIGURE_F: 'flag to force viewing of the figure after saving',
    INTERACTIVE_F: 'flag to indicate interactive mode',
    HELP_F: 'show help'
}


# Find Minimum in Rotated Sorted Array
from typing import List

class Solution:
    def findMin(self, nums: List[int]) -> int:
        if len(nums) == 1: return nums[0]
        l, r = 0, len(nums) - 1
        if nums[l] < nums[r]: return nums[l]
        while l < r - 1:
            mid = (l + r) // 2
            if nums[mid] > nums[l]:
                l = mid
            else:
                r = mid
        return min(nums[l], nums[r])

s = Solution()
print(s.findMin([4,5,6,7,0,1,2]))


class StockProfitCalculator:

    def __init__(self):
        self.result = {
            "symbol": "",
            "proceeds": 0.0,
            "cost": 0,
            "totalPurchasePrice": 0,
            "buyCommission": 0,
            "sellCommission": 0,
            "capitalTaxGain": 0,
            "netProfit": 0,
            "roi": 0,
            "breakEven": 0
        }

    def calculateProfit(self, data):

        #getting data from the request form
        symbol = data.get('symbol')
        allotment = float(data.get('allotment'))
        finalSharePrice = float(data.get('finalSharePrice'))
        sellCommission = float(data.get('sellCommission'))
        initialSharePrice = float(data.get('initialSharePrice'))
        buyCommission = float(data.get('buyCommission'))
        capitalGainRate = float(data.get('capitalGainRate'))

        #calculating proceeds
        proceeds = allotment * finalSharePrice

        #calculating total purchare price
        totalPurchasePrice = allotment * initialSharePrice
        commissions = sellCommission + buyCommission

        grossProfit = totalPurchasePrice + commissions
        capitalGainTax = (capitalGainRate / 100) * (proceeds - grossProfit)

        #calculating net profit
        netProfit = (proceeds - grossProfit) - capitalGainTax

        #calculating cost
        cost = proceeds - netProfit

        #calculating rate of interest
        roi = round((netProfit / cost) * 100, 2)

        #calculating break even
        breakEven = (totalPurchasePrice + commissions) / 100

        #assigning the values back to class variables
        self.result["symbol"] = symbol
        self.result["proceeds"] = proceeds
        self.result["totalPurchasePrice"] = totalPurchasePrice
        self.result["cost"] = cost
        self.result["sellCommission"] = sellCommission
        self.result["buyCommission"] = buyCommission
        self.result["capitalTaxGain"] = capitalGainTax
        self.result["netProfit"] = netProfit
        self.result["roi"] = roi
        self.result["breakEven"] = breakEven

        return self.result


#!/usr/bin/env python
import tf.transformations as tf
import numpy as np
import rospy
import threading
from nav_msgs.msg import Odometry
from geometry_msgs.msg import PoseWithCovarianceStamped, Vector3, Pose

class ringTranslator():
    def __init__(self):
        rospy.init_node("ring_translator")

        self.pose_sub = rospy.Subscriber("/ground_truth/state", Odometry,
                                         self.simCallback, queue_size=1)

        self.rob_sub = rospy.Subscriber("robot_pos_ls", Pose, self.rob_callback, queue_size=1)

        self.ring_sub = rospy.Subscriber("ring_pos",
                                         Pose,
                                         self.pos_callback,
                                         queue_size=1)

        self.ring_pub = rospy.Publisher("ringWorld",
                                         Pose,
                                         queue_size=1)

        self.euler = np.zeros(3)
        self.pos = np.zeros(3)
        self.ring_abs = np.zeros(3)
        self.ring_rel = np.zeros(3)

    def simCallback(self, msg):
        orient = msg.pose.pose.orientation
        quat = np.array([orient.x, orient.y, orient.z, orient.w])
        self.euler = tf.euler_from_quaternion(quat, axes='sxyz')

    def rob_callback(self, msg):
        pos = msg.position
        self.pos = np.array([pos.x, pos.y, pos.z])

    def pos_callback(self, msg):
        pos = msg.position
        self.ring_rel = np.array([-pos.x, pos.y, -pos.z])-\
                        np.array([0.0, -0.1, -0.1])
        self.transform()

    def transform(self):
        # R = tf.euler_matrix(-self.euler[0], -self.euler[1], -self.euler[2], 'sxyz')
        # print(self.euler)
        yaw = -(self.euler[2]-np.pi/2)
        R = np.array([[np.cos(yaw), -np.sin(yaw), 0],
                      [np.sin(yaw),  np.cos(yaw), 0],
                      [0, 0, 1]])
        ring_rel_tank = np.matmul(R, self.ring_rel)
        self.ring_abs = ring_rel_tank + self.pos #- \
           # np.array([0.2, -0.25, 0.2])
        # print(self.ring_abs)
        # print(ring_rel_tank, self.ring_rel)
        self.publish()

    def publish(self):
        msg = Pose()
        msg.position.x = self.ring_abs[0]
        msg.position.y = self.ring_abs[1]
        msg.position.z = self.ring_abs[2]
        self.ring_pub.publish(msg)

    def run(self):
        rospy.spin()

def main():
    node = ringTranslator()
    node.run()

if __name__ == '__main__':
    main()


import gzip
import json
import re
import StringIO
import urllib2

from autopkglib import Processor, ProcessorError

__all__ = ["GoToMeetingURLProvider"]

BASE_URL = "https://p5.osdimg.com/g2mupdater/live/config.json"

class GoToMeetingURLProvider(Processor):

    """Provides a download URL for the latest GoToMeeting release."""
    input_variables = {
        "base_url": {
            "required": False,
            "description": "Default is %s" % BASE_URL
        }
    }
    output_variables = {
        "url": {
            "description": "URL to the latest GoToMeeting release."
        },
        "build": {
            "description": "Build number of the latest GoToMeeting release."
        }
    }
    description = __doc__

    def get_g2m_json(self, base_url):
        request = urllib2.Request(base_url)
        request.add_header("Accept-Encoding", "gzip")
        opener = urllib2.build_opener()
        response = opener.open(request)

        # Sometimes the base URL is compressed as gzip, sometimes it's not.
        if response.info().get("Content-Encoding") == "gzip":
            self.output("Encoding: gzip")
            gzipData = StringIO.StringIO(response.read())
            jsonData = json.loads(gzip.GzipFile(fileobj=gzipData).read())
        else:
            self.output("Encoding: plaintext")
            jsonData = json.loads(response.read())

        return jsonData

    def get_g2m_url(self, jsonData):
        return jsonData["activeBuilds"][
            len(jsonData["activeBuilds"]) - 1]["macDownloadUrl"]

    def get_g2m_build(self, jsonData):
        return str(jsonData["activeBuilds"][
            len(jsonData["activeBuilds"]) - 1]["buildNumber"])

    def main(self):
        """Find and return a download URL"""
        base_url = self.env.get("base_url", BASE_URL)
        jsonData = self.get_g2m_json(base_url)
        self.env["url"] = self.get_g2m_url(jsonData)
        self.output("Found URL: %s" % self.env["url"])
        self.env["build"] = self.get_g2m_build(jsonData)
        self.output("Build number: %s" % self.env["build"])

if __name__ == "__main__":
    processor = GoToMeetingURLProvider()
    processor.execute_shell()


import json
import subprocess
import sys
import time

from selenium import webdriver
from selenium.webdriver.common.by import By

def navigate_to_next_page(driver):
    """
    Navigate to the next wish page
    :param driver: the driver
    :rtype: str
    """
    selector = "to-next"
    element = driver.find_element(By.CLASS_NAME, selector)
    element.click()
    time.sleep(1.5)
    return get_current_page_number(driver)

def get_current_page_number(driver):
    navigation_buttons = driver.find_elements(By.CLASS_NAME, "page-item")
    assert len(navigation_buttons) == 3
    page_number = navigation_buttons[1].text
    return page_number

def get_table(driver):
    """
    Get wishes in the table
    :param Webdriver driver:
    :return:
    """
    selector = "log-item-row"
    wish_rows = driver.find_elements(By.CLASS_NAME, selector)

    res = []
    for row in wish_rows:
        res.append(
            {
                "item_type": row.find_element(By.CLASS_NAME, "type").text,
                "wish_item_name": row.find_element(By.CLASS_NAME, "name").text,
                "wish_type": row.find_element(By.CLASS_NAME, "wish").text,
                "time_receive": row.find_element(By.CLASS_NAME, "time").text
            },
        )
    return res

def switch_banner_page(driver, banner):
    options = {
        "event": 301,
        "weapon": 302
    }
    if banner not in options:
        raise Exception("Unrecognized banner")
    banner_id = options[banner]
    dropdown = driver.find_element(By.CLASS_NAME, "selected-val")
    dropdown.click()
    time.sleep(0.5)

    driver.find_element(By.CLASS_NAME, f"item[data-id='{banner_id}']").click()
    time.sleep(0.5)

def get_wishes(wish_url, banner="character"):
    options = webdriver.ChromeOptions()
    options.add_argument("--log-level=3")
    driver = webdriver.Chrome(options=options)
    driver.minimize_window()
    driver.get(wish_url)
    time.sleep(4)
    current_page_number = get_current_page_number(driver)
    last_page_number = ""

    if banner != "character":
        switch_banner_page(driver, banner)

    wish_list = []
    while current_page_number != last_page_number:
        if int(current_page_number) % 5 == 0:
            print("parsing page: " + current_page_number)
        page_wishes = get_table(driver)
        wish_list.extend(page_wishes)
        last_page_number, current_page_number = current_page_number, navigate_to_next_page(driver)
        time.sleep(1)
    driver.close()
    return wish_list

def get_five_star_weapon_list():
    driver = get_driver()
    URL = "https://genshin-impact.fandom.com/wiki/Category:5-Star_Weapons"
    driver.get(URL)

    elements = driver.find_elements(By.CLASS_NAME, "category-page__member")

    weapon_list = []
    for element in elements:
        weapon_name = element.text
        weapon_list.append(weapon_name)
    driver.close()
    return weapon_list

def parse_wish_json(json_data):
    FIVE_STAR_WEAPON_PREFIXES = get_five_star_weapon_list()
    total_rolls = 0
    five_star_count = 0
    for wish in reversed(json_data):
        five_star_count += 1
        total_rolls += 1
        item_type = wish['item_type']
        item_name = wish['wish_item_name'].split("(")[0].strip()
        if item_type == "Character":
            if "5" in item_name:
                print(item_name, ":", five_star_count, "rolls")
                five_star_count = 0
        elif item_type == "Weapon":
            if "5" in item_name or item_name in FIVE_STAR_WEAPON_PREFIXES:
                print(item_name, ":", five_star_count, "rolls")
                five_star_count = 0

    print("Pity count", ":", five_star_count)
    print("Total rolls in history", ":", total_rolls)

def get_driver():
    options = webdriver.ChromeOptions()
    options.headless = True
    options.add_argument("--log-level=3")
    driver = webdriver.Chrome(options=options)
    driver.minimize_window()

    return driver

if __name__ == '__main__':
    wish_json_data = ""

    if len(sys.argv) >= 2:
        command = sys.argv[1]
        if len(sys.argv) == 2:
            if command == "PARSE_JSON":
                with open("wish_data.json", 'r') as f:
                    data = json.load(f)
                    parse_wish_json(data)
        elif len(sys.argv) >= 3:
            arg = sys.argv[2]
            if command == "PARSE_URL":
                wish_json_data = get_wishes(arg)
                parse_wish_json(wish_json_data)
            elif command == "BANNER":
                raw_output = subprocess.check_output('powershell.exe -ExecutionPolicy Bypass -File ./get_wish_link.ps1')
                url = raw_output.decode()
                wish_json_data = get_wishes(url, banner=arg)
                parse_wish_json(wish_json_data)

    elif len(sys.argv) == 1:
        raw_output = subprocess.check_output('powershell.exe -ExecutionPolicy Bypass -File ./get_wish_link.ps1')
        url = raw_output.decode()
        wish_json_data = get_wishes(url)
        parse_wish_json(wish_json_data)

    if wish_json_data:
        with open("wish_data.json", "w") as f:
            json.dump(wish_json_data, f, indent=4)


import pandas as pd
import numpy as np
from sklearn.cluster import KMeans, SpectralClustering, DBSCAN
import matplotlib.pyplot as plt
import scanpy as sc
from sklearn.preprocessing import normalize
import anndata
import seaborn as sb
from sklearn.neighbors import kneighbors_graph, DistanceMetric
from sklearn.metrics import silhouette_score

def add_neighbors_and_umapCoords(adata, n_neighs, metric_name, min_d):
    ad1 = sc.AnnData(X=adata.X, var=adata.var, obs=adata.obs)

    sc.pp.neighbors(ad1, n_neighbors=n_neighs, use_rep="X", metric=metric_name)
    sc.tl.umap(ad1, min_dist=min_d, n_components=2)

    return ad1, metric_name

def cluster(ad, algorithm, n_cls, metricName):
    labels = []
    if algorithm.lower() == 'kmeans':
        clustering = KMeans(n_clusters=n_cls).fit(ad.X)
        labels = clustering.labels_
    elif algorithm.lower() == 'spectral':
        ds = ad.obsp["distances"]
        ds = pd.DataFrame.sparse.from_spmatrix(ds)
        ds_s = (ds + ds.T)/2
        clustering = SpectralClustering(n_clusters=n_cls, affinity='precomputed').fit(ds_s)
        labels = clustering.labels_
    y = pd.Series(labels)
    labeling(y, ad, metricName)

def labeling(y, ad, metricName):
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20,4))
    fig.suptitle(metricName)

    colors1 = []
    colors2 = []
    exacts = []
    expected = []

    for index, value in y.items():
        if value == 0:
            colors1.append('cl1')
        elif value == 1:
            colors1.append('cl2')
        elif value == 2:
            colors1.append('cl3')
        elif value == 3:
            colors1.append('cl4')
        elif value == 4:
            colors1.append('cl5')
        elif value == 5:
            colors1.append('cl6')
        elif value == 6:
            colors1.append('cl7')
        elif value == 7:
            colors1.append('cl8')
        elif value == 8:
            colors1.append('cl9')
        elif value == 9:
            colors1.append('cl10')
        elif value == 10:
            colors1.append('cl11')
        elif value == 11:
            colors1.append('cl12')
        elif value == 12:
            colors1.append('cl13')
        elif value == 13:
            colors1.append('cl14')
        elif value == 14:
            colors1.append('cl15')

    for i in range(1786):
        exacts.append('B')

    for i in range(2445):
        exacts.append('MDC')

    for i in range(856):
        exacts.append('MC')

    for i in range(309):
        exacts.append('NK')

    for i in range(325):
        exacts.append('iNKT')

    for i in range(382):
        exacts.append('MaiT')

    for i in range(4486):
        exacts.append('P5T')

    for i in range(1247):
        exacts.append('T4_1')

    for i in range(222):
        exacts.append('T4_2')

    for i in range(965):
        exacts.append('T4_3')

    for i in range(435):
        exacts.append('T4_4')

    for i in range(310):
        exacts.append('T8')

    for i in range(4753):
        exacts.append('T8_metha')

    for i in range(284):
        exacts.append('Vd1')

    for i in range(204):
        exacts.append('Vd2')

    exacts = pd.Series(exacts)

    names = pd.Series(ad1.obs_names)
    names_connect = pd.concat((names, y, exacts),axis=1)
    names_connect = names_connect.rename({0:'Cells', 1:'Cluster', 2:'Names'},axis=1)
    sort_cells = names_connect.sort_values(['Names'])

    for i, v in sort_cells.iterrows():
        if v['Names'] == 'B':
            colors2.append('B')
        elif v['Names'] == 'MDC':
            colors2.append('MDC')
        elif v['Names'] == 'MC':
            colors2.append('MC')
        elif v['Names'] == 'NK':
            colors2.append('NK')
        elif v['Names'] == 'iNKT':
            colors2.append('T1')
        elif v['Names'] == 'MaiT':
            colors2.append('T23')
        elif v['Names'] == 'P5T':
            colors2.append('T23')
        elif v['Names'] == 'T4_1':
            colors2.append('T4')
        elif v['Names'] == 'T4_2':
            colors2.append('T5678')
        elif v['Names'] == 'T4_3':
            colors2.append('T5678')
        elif v['Names'] == 'T4_4':
            colors2.append('T5678')
        elif v['Names'] == 'T8':
            colors2.append('T5678')
        elif v['Names'] == 'T8_metha':
            colors2.append('T9_10')
        elif v['Names'] == 'Vd1':
            colors2.append('T9_10')
        elif v['Names'] == 'Vd2':
            colors2.append('T11')

    s = silhouette_score(ad.X, y)
    print(s)

    ad.obs['ClassFound'] = colors1
    found = sc.pl.umap(ad, color="ClassFound", ax = ax1, show=False)

    ad.obs['ClassReal'] = colors2

    real = sc.pl.umap(ad, color="ClassReal", ax = ax2, show=False)

#specify the path
adata = sc.read_csv('C:\\Users\\User\Desktop\seminarski.ip2\GEO\\klaster\\Sve.csv')

#example
ad1, metric = add_neighbors_and_umapCoords(adata, 110, 'cosine', 0.1)
cluster(ad1, 'kmeans', 6, metric)


from flask import Blueprint,render_template, url_for,request, current_app, session
#import jinja2
# from code import InteractiveConsole
import subprocess

terminal=Blueprint("terminal",__name__,static_folder="static",template_folder="templates")
#my_loader=jinja2.ChoiceLoader([terminal.jinja_loader,jinja2.FileSystemLoader

# load an interactive console and a call stack
# note: this is currently not attached to user context but shared over global context
# interactive_terminal=InteractiveConsole()
call_stack=[]
out_stack=[""]

@terminal.route("/",methods=["GET","POST"])
@terminal.route("/home",methods=["GET","POST"])
def index():
    """Allows to execute terminal commands on the RPi

    Returns:
        rendered html: Containing Output of Terminal STDOut
    """
    global out_stack
    global call_stack
    if request.method=="POST":
        call_stack.append(str(request.form["terminal_input"]))
        # with Capturing(out_stack) as out_stack:
        #     interactive_terminal.runcode(str(request.form["terminal_input"]))
        try:
            out_stack.append(subprocess.getoutput(str(request.form["terminal_input"])))
        except Exception as e:
            out_stack.append(f"Error {e} occured in subprocess call")

    print(out_stack)

    return render_template("terminal.html",title="Terminal",terminal_output=out_stack[-1],bg_img_path=url_for('terminal.static',filename="backgroundimg.png"))

# class for capturing print statement
# from io import StringIO
# import sys
# class Capturing(list):
#     def __enter__(self):
#         self._stdout = sys.stdout
#         self._sterr = sys.stderr
#         sys.stderr = sys.stdout = self._stringio = StringIO()
#         return self
#     def __exit__(self, *args):
#         if not self._stringio.getvalue().splitlines():
#             self.extend(["Your input required no answer"])
#         else:
#             self.extend(self._stringio.getvalue().splitlines())
#         del self._stringio
#         sys.stdout = self._stdout
#         sys.stderr = self._sterr


import re
from urllib.parse import urljoin

from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd

driver = webdriver.Chrome("chromedriver.exe")

sno=[]
university_name=[]
city=[]
country=[]
ranking=[]
link=[]

count=1

url_list=["https://www.usnews.com/education/best-global-universities/search?country=australia&country=canada&country=denmark" \
    "&country=france&country=germany&country=greece&country=italy&country=netherlands&country=singapore&country=spain" \
    "&country=sweden&country=switzerland&country=united-kingdom&subject=computer-science",
          "https://www.usnews.com/education/best-global-universities/search?country=canada&subject=computer-science&name=",
          "https://www.usnews.com/education/best-global-universities/search?country=canada&subject=&name="]

filter_list=["UniversitiesAllCSE", "UniversitiesCanadaCSE", "UniversitiesCanadaGeneralRanking"]

filter=1

next_url=url_list[filter]
# next_url= "https://www.usnews.com/education/best-global-universities/search?country=australia&country=canada&country=denmark" \
#     "&country=france&country=germany&country=greece&country=italy&country=netherlands&country=singapore&country=spain" \
#     "&country=sweden&country=switzerland&country=united-kingdom&subject=computer-science"

base_uri="https://www.usnews.com"

while next_url != None:
    driver.get(next_url)

    content=driver.page_source
    soup=BeautifulSoup(content,features="html.parser")

    for a in soup.findAll('div', attrs={'class':'sep'}):
        name=a.find('h2', attrs={'class':'h-taut'})
        if name != None:
            sno.append(count)
            count += 1
            print(name.text)
            university_name.append(name.text.strip())
            _university_link = name.find('a', attrs={'href': re.compile("^https://")})
            if _university_link != None:
                sub_driver = webdriver.Chrome("chromedriver.exe")
                sub_driver.get(_university_link.get('href'))
                sub_content = sub_driver.page_source
                sub_soup = BeautifulSoup(sub_content, features="html.parser")
                _lint_divs = sub_soup.findAll('div', attrs={'class':'directory-data'})
                for l in _lint_divs:
                    # print(l)
                    _ulink = l.find('a', attrs={'href': re.compile("^https://")})
                    if _ulink != None:
                        # print(_ulink.get('href'))
                        link.append(_ulink.get('href'))
                        break
                    _ulink = l.find('a', attrs={'href': re.compile("^http://")})
                    if _ulink != None:
                        # print(_ulink.get('href'))
                        link.append(_ulink.get('href'))
                        break
                sub_driver.close()
                # link.append(_university_link.get('href'))

        _ranking=a.find('span', attrs={'class':'rankscore-bronze'})
        if _ranking != None:
            rank=_ranking.text.strip()
            if rank.__contains__("Tie"):
                rank = rank.split()[0].strip()
            ranking.append(rank)

        _country_div=a.find('div', attrs={'class':'t-taut'})
        if _country_div != None:
            _country = _country_div.find('span', attrs={'class': None}).text.strip()
            _city_soup = _country_div.find('span', attrs={'class': 't-dim t-small'})
            _city=" "
            if _city_soup != None and len(_city_soup.text.strip())>0:
                _city = _city_soup.text.strip()

            country.append(_country)
            city.append(_city)
            # print(_city)

    _pager_links = soup.findAll('a', attrs={'class':'pager_link'})
    if _pager_links != None :
        for _link in reversed(_pager_links):
            l=str(_link)
            if l.__contains__('Next'):
                next_url = urljoin(base_uri,_link.get('href'))
            else:
                next_url=None
            break

driver.close()
# print(country)
# df = pd.DataFrame({'SNo.':sno, 'University Name': university_name, 'Country': country, 'City': city, 'International Ranking': ranking, 'Link': link})
# df.to_csv( filter_list[filter]+'.csv', index=False, encoding='ISO-8859-1')


from common.templates import *
from widgets.homemap import HomeMap

# class WeatherWidgetTemplate(PanedTemplate, BoardLinkTemplate):
#
#     def __init__(self, parent, boardname, **kwargs):
#         PanedTemplate.__init__(self, parent, **kwargs)
#         BoardLinkTemplate.__init__(self, boardname)
#         self.labels = dict()
#
#     def on_update(self, *args, **kwargs):
#
#         if not self.exist():
#             return
#         #
#         #
#         #
#         # for dev in self.get_board().device.values():
#         #
#         #     for key, value in System.layout.weather.items():
#         #         if self.board == key[0] and dev.name == key[1]:
#         #             if not key in self.labels.keys():
#         #                 s = '{0:<16}'.format(dev.status.)
#
# class DataViewer(PanedTemplate):
#     def __init__(self, parent, **kwargs):
#         PanedTemplate.__init__(self, parent, **kwargs)

class UiWeather(PanedTemplate):

    class StationListEntry(PanedTemplate, BoardLinkTemplate):

        def __init__(self, parent, boardname, **kwargs):
            PanedTemplate.__init__(self, parent, **kwargs)
            BoardLinkTemplate.__init__(self, boardname)

            self.title  = LabelTemplate(self)
            self.icon   = PictureTemplate(self, Icons.BOARD_RED())
            self.status_widget=None

        def build(self, *args, **kwargs):
            super(UiWeather.StationListEntry, self).build()
            self.configure(relief=tk.RAISED)
            self.title.configure(
                font=Fonts.monobold(10),
                # anchor=tk.W,
                # padx=20,
                relief=tk.FLAT,
                text=self.board,
            )

            self.bind_mouse_buttons()

            self.title.bind("<ButtonPress-1>", self.on_press)
            self.title.bind("<ButtonRelease-1>", self.on_release)

            self.icon.bind("<ButtonPress-1>", self.on_press)
            self.icon.bind("<ButtonRelease-1>", self.on_release)

        def on_press(self, *event):
            super(UiWeather.StationListEntry, self).on_press(event)
            self.configure( bg=Palette.generic.WHITE )
            self.title.configure( bg=Palette.generic.WHITE, fg=Palette.generic.BLACK)
            self.icon.configure( bg=Palette.generic.WHITE )

        def on_release(self, *event):
            super(UiWeather.StationListEntry, self).on_release(event)
            self.configure( bg=Palette.generic.BG_DEFAULT )
            self.title.configure( bg=Palette.generic.BG_DEFAULT, fg=Palette.generic.WHITE)
            self.icon.configure( bg=Palette.generic.BG_DEFAULT )
            self.master.show(self.board)

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

            if self.exist():

                for dev in self.get_board().device.values():
                    for key, lyt in System.layout.weather.items():
                        if self.board == key[0] and dev.name == key[1]:
                            self.title.configure(
                                text='{} '.format(lyt.group.split('climate')[0]).rstrip(' ').upper(),
                                anchor=tk.CENTER
                            )

                            for entry in dev.status.dev.values():
                                # <entry> is output value of dev
                                pass

        def on_resize(self, *args, **kwargs):
            w,h = super(UiWeather.StationListEntry, self).on_resize()

            h_title = 25
            size=min(w, h - h_title)
            self.title.place(
                x=2,
                y=h - (h_title + 2),
                width=w - 4,
                heigh=h_title
            )
            self.icon.place(
                x=0.5 *  (w - size),
                y=2,
                width=size,
                heigh=size
            )
            self.icon.on_resize()

    class StationWidget(PanedTemplate, BoardLinkTemplate):

        class StationDataLine(PanedTemplate, BoardLinkTemplate):
            def __init__(self, parent, boardname, valuetype, **kwargs):
                PanedTemplate.__init__(self, parent, **kwargs)
                BoardLinkTemplate.__init__(self, boardname)
                self._type=valuetype
                self.labels=dict()
                self.buttons=dict()
                self.color=Palette.generic.BG_DEFAULT
                self.show=False

            def build(self, *args, **kwargs):
                super(UiWeather.StationWidget.StationDataLine, self).build()

                for key in ('label', 'value', 'unit'):
                    self.labels.update({
                        key : LabelTemplate(
                            self,
                            font=Fonts.monobold(12),
                            anchor=tk.W,
                            padx=10,
                            # relief=tk.RAISED,
                            # bg='snow',
                            # fg='black'
                        )
                    })

                for key in ('update', 'show', 'color'):
                    self.buttons.update({
                        key : ButtonTemplate(
                            self,
                            text=key.capitalize(),
                            font=Fonts.monobold(10),
                            command=lambda c=key : self.callback(c)
                        )
                    })

                self.labels['label'].configure(text=self._type)
                self.labels['value'].configure(font=Fonts.monobold(20), anchor=tk.SW)

                self.buttons['color'].configure(
                    text='',
                )

            def callback(self, command):

                if command == 'update':
                    print('REQUESTING UPDATE TO IMPLEMENT :(')
                elif command == 'show':
                    self.buttons['color'].configure(bg=self.color)
                    self.master.on_plot(self._type.split(' ')[1]) #### QUI!!! QUI deve combaciare la desc che board mette in probe con la description di Parameters
                    self.show = True
                    self.callback('color')
                elif command == 'color':
                    self.color = Palette.plot.new()
                    self.buttons['color'].configure(bg=self.color)
                    # self.master.plot.changecolrotoline()

            def on_update(self, *args, **kwargs):
                self.buttons['color'].configure(bg=self.color)

                if self.exist():

                    value = 0
                    count = 0
                    limits = list()
                    unit = str()

                    for dev in self.get_board().device.values():

                        if not (self.board, dev.name,) in System.layout.weather.keys():
                            # error_ui('{}:{} not in Layout!'.format(self.board, dev.name))
                            continue

                        for entry in [ item for item in dev.status.dev.values() if item.desc == self._type ]:

                            unit = entry.unit
                            limits = entry.limits
                            if dev.is_connected():
                                value += entry.data / Config.macros.FLOAT2INT
                                count += 1

                    self.labels['unit'].configure(text=unit)
                    if count > 0:
                        self.labels['value'].configure(text='{}'.format('%2.2f' % (value/count) ))
                    else:
                        self.labels['value'].configure(text='{}'.format('%2.2f' % value ))

                    if self.get_board().is_connected() and \
                            any([dev.is_connected() for dev in self.get_board().device.values()]):
                        if len(limits) > 1:
                            if limits[0] > value > limits[1]:
                                self.labels['value'].configure(bg=Palette.generic.WARNING)

                    else:
                        self.labels['label'].configure(fg=Palette.generic.DISABLED)
                        self.labels['value'].configure(fg=Palette.generic.DISABLED)
                        self.labels['unit'].configure(fg=Palette.generic.DISABLED)

            def on_resize(self, *args, **kwargs):
                w,h=super(UiWeather.StationWidget.StationDataLine, self).on_resize()

                split=0.5 * w
                h_label = min(30, 0.5 * h)
                off = 5
                w_butt = min(100, split/3 + off)

                self.labels['label'].place(
                    x=0,
                    y=h - h_label,
                    width=0.5 * split,
                    heigh=h_label
                )
                self.labels['value'].place(
                    x=0.5 * split,
                    y=0,
                    width=0.3 * split,
                    heigh=h
                )
                self.labels['unit'].place(
                    x=0.8 * split,
                    y=h - h_label,
                    width=0.2 * split,
                    heigh=h_label
                )

                for count, item in enumerate(self.buttons.values()):
                    item.place(
                    x=split + (off + w_butt) * count,
                    y=h - h_label,
                    width=w_butt,
                    heigh=h_label
                )
                self.buttons['color'].place(width=h_label)

        def __init__(self, parent, boardname, **kwargs):
            PanedTemplate.__init__(self, parent, **kwargs)
            BoardLinkTemplate.__init__(self, boardname)
            self.title  = LabelTemplate(self)
            self.plot   = PlotTemplate(self)
            self.labels = dict()

        def build(self, *args, **kwargs):
            super(UiWeather.StationWidget, self).build()
            self.plot.build()
            self.title.configure(
                font=Fonts.monobold(13),
                anchor=tk.W,
                # relief=tk.RAISED,
                # bg='blue',
                fg='snow'
            )

            # self.plot.plot([1,2,3,4,5],[5,2,3,8,4])

        def on_plot(self, probetype):
            if self.exist():
                for dev in self.get_board().device.values():
                    if not (self.board, dev.name,) in System.layout.weather.keys():
                        continue
                    if probetype in dev.probes().keys():
                        x, y = dev.probes(probetype)
                        self.plot.plot(x, y, label='{}:{}'.format(dev.name, probetype))
                self.plot.draw()
        def on_update(self, *args, **kwargs):

            if self.exist():

                for dev in self.get_board().device.values():
                    for key, lyt in System.layout.weather.items():
                        if self.board == key[0] and dev.name == key[1]:
                            # self.title.configure(text='{} {}:{}'.format(
                            #     lyt.area, lyt.location, lyt.group
                            # ).capitalize())
                            self.title.configure(text='{}'.format(lyt.group).capitalize())

                            # for pkey in dev.probes().keys():
                            #     x,y = dev.probes(pkey)
                            #     self.plot.plot(x, y, label='{}:{}'.format(dev.name, pkey))

                            for entry in dev.status.dev.values():

                                if 'system' in entry.desc:
                                    continue
                                if not entry.desc in self.labels.keys():
                                    self.labels.update({
                                        entry.desc:self.StationDataLine(
                                            self,
                                            self.board,
                                            entry.desc
                                        )
                                    })
                                    self.labels[entry.desc].build()

            for entry in self.labels.values():
                entry.on_update()

                                # s = '{0:<16}'.format(entry.desc)
                                # s += ': {} '.format(entry.value)
                                # s += entry.unit
                                #
                                # self.labels[entry.desc].configure(text=s)

        def on_resize(self, *args, **kwargs):
            w, h=super(UiWeather.StationWidget, self).on_resize()
            h_title = 30
            h_label = 50
            h_plot  = 400
            off=10
            self.title.place(
                x=off,
                y=off,
                width=w - 2 * off,
                heigh=h_title
            )
            for count, entry in enumerate(self.labels.values()):
                entry.place(
                    x=off,
                    y=2 * off + h_title + h_label * count,
                    width=w - 2 * off,
                    heigh=h_label
                )
                entry.on_resize()

            self.plot.place(
                x=off,
                y=h - h_plot,
                width=w - 2 * off,
                heigh=h_plot
            )
            self.plot.on_resize()

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

        PanedTemplate.__init__(self, parent, **kwargs)
        self.title=LabelTemplate(self)
        self.background=HomeMap(self)

        self.buttons        = dict()

        self.frames         = dict()
        self.list_indoor    = dict()
        self.list_outdoor   = dict()

        self._current   = ''
        # self._current   = 'KITCHEN.CLIMATE'

    def build(self, *args, **kwargs):
        self.background.build()

        self.title.configure(
            font=Fonts.monobold(16),
            text='WEATHER',
            anchor=tk.W,
            padx=30,
            fg=Palette.frames.WEATHER,
            bg=Palette.generic.BLACK
        )
        self.on_update()

    def loop(self):
        if Config.flags.update.DEVICES or Config.flags.update.NETWORK or Config.flags.update.SYSTEM:
            self.on_update()

    def show(self, name):
        if name in self.frames.keys():

            self.frames[name].on_update()
            if self._current == name:
                return

            if self._current in self.frames.keys():
                self.frames[self._current].place_forget()
            self._current=name
            self.on_resize()

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

        _flag=False
        # for key, lyt in System.layout.weather.items():
        #     if not key[0] in self.list_indoor.keys():
        #
        #         if not lyt.weathertype:
        #             self.list_indoor.update({
        #                 key[0]: UiWeather.StationListEntry(self, key[0])
        #             })
        #             self.list_indoor[key[0]].build()
        #         else:
        #             self.list_outdoor.update({
        #                 key[0]: UiWeather.StationListEntry(self, key[0])
        #             })
        #             self.list_outdoor[key[0]].build()
        #
        #         self.frames.update({
        #             key[0]:UiWeather.StationWidget(self, key[0])
        #         })
        #
        #         self.frames[key[0]].build()
        #
        #         _flag=True

        for item in self.list_indoor.values():
            item.on_update()
        for item in self.list_outdoor.values():
            item.on_update()

        if self._current in self.frames.keys():
            self.frames[self._current].on_update()

        if _flag:
            self.on_resize()

    def on_resize(self, *args, **kwargs):
        w,h = super(UiWeather, self).on_resize()

        w_list = max(0.2 * w, 450)
        w_entry = 150
        h_entry = 80
        h_title = 35
        off=10
        self.title.place(
            x=0,
            y=0,
            width=w,
            heigh=h_title,
        )
        self.background.place(
            x=0,
            y=h_title,
            width=w,
            heigh=(h - h_title)
        )

        row = 0
        ndx = 0
        for count, item in enumerate(self.list_indoor.values()):

            # if count > 3 and  count % 4 == 0:
            if off + (ndx + 1) * (w_entry + off) > w_list:
                row +=1
                ndx = 0

            item.place(
                x=off + ndx * (w_entry + off),
                y=h_title + off + row * (h_entry + off),
                width=w_entry,
                heigh=h_entry
            )
            item.on_resize()
            ndx += 1

        if self._current in self.frames.keys():
            self.frames[self._current].place(
                x=2 * off + w_list,
                y=off + h_title,
                width=w - (3 * off + w_list),
                heigh=h - (h_title + 2 * off),
            )
            self.frames[self._current].on_resize()

        return w,h

print('Loaded gui.frame.weather')