from django.db import connection
from django import forms
from django.contrib.auth.views import login_required
from django.shortcuts import redirect, render
from django.urls import reverse_lazy
from django.views.generic import CreateView, DetailView
from django.views.generic.list import ListView

from blog.models import Topic

from .models import Room, Message
from .forms import MessageForm, RoomForm

# Create your views here.
@login_required
def RoomListView(request):

    if request.method == 'POST':
        search_query = request.POST['search_query']
        room_list = Room.objects.filter(name__contains=search_query)
    else:
        room_list = Room.objects.all()

    context = {'room_list': room_list}
    return render(request, 'rooms/room_list.html', context)

class MyRoomsListView(ListView):

    model = Room

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super(MyRoomsListView, self).get_context_data()
        context['room_list'] = Room.objects.filter(host=self.request.user)
        return context

@login_required
def RoomCreate(request):

    form = RoomForm()

    form.fields['host'].widget = forms.TextInput(attrs={'type': 'hidden', 'value': request.user.id })
    form.fields['topic'] = forms.ModelChoiceField(queryset=Topic.objects.all())
    form.fields['name'].widget = forms.TextInput(attrs={'class': 'form-control mb-2', 'placeholder': 'Room name'})
    form.fields['description'].widget = forms.Textarea(attrs={'class': 'form-control'})

    if request.method == 'POST':
        form = RoomForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            desc = form.cleaned_data['description']
            topic = form['topic'].value()
            host = request.user.id
            with connection.cursor() as cursor:
                cursor.callproc('room_package.insert_room', [name, desc, host, topic])
            return redirect('my-rooms')

    context = {'form': form}
    return render(request, 'rooms/room_form.html', context)

def RoomDetailView(request, pk):
    form = MessageForm()
    form.fields['user'].widget = forms.TextInput(attrs={'type': 'hidden', 'value': request.user.id })
    form.fields['room'].widget = forms.TextInput(attrs={'type': 'hidden', 'value': pk })
    room = Room.objects.get(id=pk)
    messages = Message.objects.filter(room=pk)
    participants = room.users.all()
    if request.method == 'POST':
        form = MessageForm(request.POST)
        if form.is_valid():
            room.users.add(request.user)
            content = form.cleaned_data['content']
            room = pk
            user = request.user.id
            with connection.cursor() as cursor:
                cursor.callproc('message_package.insert_message', [content, room, user])
            return redirect(request.META['HTTP_REFERER'])

    context = {'form': form, 'room': room, 'messages': messages, 'participants': participants}
    return render(request, 'rooms/room_detail.html', context)

def MessageDelete(request, pk):
    message = Message.objects.get(id=pk)
    if request.user == message.user:
        message = pk
        with connection.cursor() as cursor:
            cursor.callproc('message_package.delete_message', [message])
        return redirect(request.META['HTTP_REFERER'])
    return redirect('all-rooms')

def RoomStatus(request):

    topic = popular_topics()
    room = most_populated_room()
    mensajes = most_messaged_room()

    context = {'topic': topic, 'room': room, 'mensajes': mensajes}

    return render(request,'rooms/room_status.html', context)

def popular_topics():
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM TopicsUsadosEnRooms')
        row = dictfetchall(cursor)
    return row

def most_populated_room():
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM RoomConMasUsuarios')
        row = dictfetchall(cursor)
    return row

def most_messaged_room():
    with connection.cursor() as cursor:
        cursor.execute('SELECT * FROM RoomConMasMensajes')
        row = dictfetchall(cursor)
    return row

def dictfetchall(cursor):
    """
    Return all rows from a cursor as a dict.
    Assume the column names are unique.
    """
    columns = [col[0] for col in cursor.description]
    return [dict(zip(columns, row)) for row in cursor.fetchall()]


from bs4 import BeautifulSoup
import requests

with open('simple.html') as html_file:
    soup = BeautifulSoup(html_file, 'lxml')

'''Prints html file in proper indentation'''
# print(soup.prettify())

'''Gets Title with header'''
# match = soup.title
'''Prints only text of the title'''
# match = soup.title.text

'''Gets first complete div tag'''
# match = soup.div

'''Gets the complete div where class is footer'''
# match = soup.find('div', class_='footer')

article = soup.find('div', class_='article')
print(article)
for article in soup.find_all('div', class_='article'):
    # print(article)

    '''Finds text of the anchor class of h2 inside article class'''
    headline = article.h2.a.text
    print(headline)

    summary = article.p.text
    print(summary)
    print()


DATA_PATH = './data/'

# Encoder settings
ENCODER_PATH = "../../models/mars/mars-small128.pb"
ENCODER_BATCH_SIZE = 32
ENCODER_INPUT_NAME = "images"
ENCODER_OUTPUT_NAME = "features"

# Object detection model
MODEL_PATH = '../../models/frcnn'


# -*- coding: utf-8 -*-
import subprocess

class RunCmd:
    @staticmethod
    def run_cmd(cmd):
        output, errors = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
        result = output.decode("utf-8")
        return result


import tensorflow as tf
import numpy as np

import time
import yaml

from tqdm import tqdm

from src.model import VAE, train_step, eval_step, preprocess_images

if __name__ == "__main__":

    tf.executing_eagerly()

    # load config file for training
    config = yaml.safe_load(open('config.yml'))

    # training params
    batch_size = config['batch_size']
    no_epochs = config['epochs']
    input_dims = eval(config['input_shape'])
    no_classes = config['num_classes']
    latent_dim = config['latent_dim']

    # initialize model
    model = VAE(input_dims=input_dims, latent_dim=latent_dim)

    # instantiate optimizer
    # optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.0, nesterov=False, name='SGD')
    optimizer = tf.keras.optimizers.Adam(1e-4)

    # log to tensorboard
    if config['tensorboard']:
        writer1 = tf.summary.create_file_writer('logs/train')
        writer2 = tf.summary.create_file_writer('logs/eval')

    # Load mnist fashion data (test data)
    (_, _), (x_test_orig, y_test_orig) = tf.keras.datasets.fashion_mnist.load_data()

    # perform a 7:3 split
    train_len = x_test_orig.shape[0]
    test_len = int(0.3 * train_len)
    x_train, y_train = x_test_orig[:-test_len:, :, :], y_test_orig[:-test_len]
    x_test, y_test = x_test_orig[-test_len:, :, :], y_test_orig[-test_len:]
    # preprocess images
    x_train = preprocess_images(x_train)
    x_test = preprocess_images(x_test)

    # instantiate data generators for train
    train_size = x_train.shape[0]
    dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    dataset = dataset.batch(config['batch_size'])
    # for test
    test_size = x_test.shape[0]
    test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
    test_dataset = test_dataset.batch(config['batch_size'])

    # start training
    loss_history = []
    best_val_acc = 0      # for classification
    best_loss = -np.inf   # autoencoder loss

    # define keras tensorboard callback
    tf.compat.v1.keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0, batch_size=batch_size, write_graph=True,
                                             write_grads=False, write_images=False, embeddings_freq=0,
                                             embeddings_layer_names=None, embeddings_metadata=None, embeddings_data=None,
                                             update_freq='epoch', profile_batch=2)

    for epoch in range(config['epochs']):
        # update learning rate
        if epoch in eval(config['learning_rate_steps']):
            optimizer.lr.assign(optimizer.lr.read_value() * config['learning_rate_decay'])

        epoch_loss_avg = tf.keras.metrics.Mean()
        epoch_val_loss_avg = tf.keras.metrics.Mean()
        print('Training...')
        # train epoch
        for batch, (images, _) in enumerate(tqdm(dataset, total=train_size // config['batch_size'])):
            train_step(images, model, optimizer, epoch_loss_avg)
        time.sleep(0.5)
        print('Evaluating...')
        # evaluate epoch
        for batch, (images, _) in enumerate(tqdm(test_dataset, total=test_size // config['batch_size'])):
            eval_step(images, model, epoch_val_loss_avg)
        time.sleep(0.5)
        # compute elbo (evidence lower bound loss)
        elbo_loss = -1 * epoch_loss_avg.result()
        elbo_val_loss = -1 * epoch_val_loss_avg.result()

        # store values on tensorboard
        with writer1.as_default():
            tf.summary.scalar('loss', epoch_loss_avg.result(), step=epoch)
        with writer2.as_default():
            tf.summary.scalar('loss', epoch_val_loss_avg.result(), step=epoch)

        # print epoch metrics
        print("Epoch {:03d} - loss: {:.3f} - val loss: {:.3f}".format(epoch,
                                                                        elbo_loss,
                                                                        elbo_val_loss))
        # save model
        if elbo_val_loss > best_loss:
            print('Saving better autoencoder model...')
            print()
            model.save_weights('checkpoint/model')
            best_loss = elbo_val_loss


from bs4 import BeautifulSoup
import requests

class Community(object):
    def __init__(self, url):
        self.url = url

    @classmethod
    def get_soup(cls, url):
        r = requests.get(url)
        url_contents = r.text
        url_soup = BeautifulSoup(url_contents, 'html.parser')
        return url_soup

    @classmethod
    def find_keyword(cls, url, keyword):
        """Returns True if the keyword is found within the post.

            :param url: Url of the post to be iterated
            :type url: str
            :param keyword: Word to look for in the post
            :type keyword: str
            :return: True
            """
        title = Community.get_title(url)
        body = Community.get_body(url)
        for word_t in title.split():
            if word_t.lower() == keyword.lower():
                return True
        for word_b in body.split():
            if word_b.lower() == keyword.lower():
                return True

    @classmethod
    def find_keywords(cls, url, keywords):
        """Returns True if all keywords are found within the post.

        :param url: Url of the post to be iterated
        :type url: str
        :param keywords: Words to look for in the post
        :type keywords: str
        :return: True
        """
        if type(keywords) is str:
            multi_keywords = keywords.split()
        else:
            multi_keywords = keywords
        match = []
        if len(multi_keywords) == 0:
            if False in match:
                return False
            else:
                return True
        else:
            first_keyword = Community.find_keyword(url, multi_keywords[0])
            match.append(first_keyword)
            smaller_list = multi_keywords[1:]
            return Community.find_keywords(url, smaller_list)

    @classmethod
    def get_posts(cls, url):
        """Returns a list of url of all the posts in a single page in forum.

        :return: A list of url of a single post in the page
        :rtype: list
        """
        return []

    @classmethod
    def get_next_page(cls, current_url, delimiter):
        """Returns url of the next page in forum.

        :param current_url: Url of the current page
        :type current_url: str
        :param delimiter: Delimiter to split up the url of the current page
        :type delimiter: str
        :return: Url of the next page
        :rtype: str
        """
        current_url = current_url.split(delimiter)
        current_url[-1] = str(int(current_url[-1]) + 1)
        current_url = delimiter.join(current_url)
        return current_url

    @classmethod
    def reach_last_page(cls, url):
        """Returns True if the last page in forum is reached

        :param url: Url of the current page
        :type url: str
        :return: True
        """
        return False

    @classmethod
    def get_title(cls, url):
        """Returns title of a post

        :param url: Url of the post
        :type url: str
        :return: Title of the post
        :rtype: str
        """
        return ''

    @classmethod
    def get_body(cls, url):
        """Returns body content of a post

        :param url: Url of the post
        :type url: str
        :return: Body content of the post
        :rtype: str
        """
        return ''

class BRCANowForum(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'https://forum.breastcancernow.org/t5/forums/recentpostspage/post-type/thread/page/1'

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all('', {'class', 'page-link lia-link-navigation lia-custom-event'})
        url_list = []
        for post in posts:
            post_url = 'http://forum.breastcancernow.org' + post['href']
            url_list.append(post_url)
        return url_list

    def reach_last_page(self, url):
        current = url[url.rfind('/') + 1:]
        if int(current) != 1:
            r = requests.get(url)
            url_contents = r.text
            url_soup = BeautifulSoup(url_contents, 'html.parser')
            next_page = url_soup.find('', {'class',
                                           'lia-link-navigation lia-js-data-pageNum-' + current + ' lia-link-disabled'})
            if next_page is None:
                return False
        else:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.title.string.replace('<title>', '').rsplit('-', 2)[0]

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        return str(url_soup.find('', {'class', 'lia-message-body-content'}))

class BRCAOrg(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'https://community.breastcancer.org/'

    def find_keyword(self, url, keyword):
        title = Community.get_title(url)
        body = Community.get_body(url)
        for word_t in title.split():
            if word_t.lower() == keyword.lower():
                return True
        for content in body:
            for word_b in content.text.split():
                if word_b.lower() == keyword.lower():
                    return True

    @classmethod
    def get_forums(cls, url):
        """Returns a list of url of forums

        :param url: Url of the index page
        :type url: str
        :return: A list of url of forums in the same category
        """
        url_soup = Community.get_soup(url)
        forums = url_soup.find_all('h3')[3:57]
        link_list = []
        for forum in forums:
            link = forum.find('a').get('href')
            link = 'https://community.breastcancer.org' + link
            link_list.append(link)
        return link_list

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all(title="View this Topic and its replies")
        url_list = []
        for post in posts:
            post_url = 'https://community.breastcancer.org' + post.get('href')
            url_list.append(post_url)
        return url_list

    def reach_last_page(self, url):
        url_soup = Community.get_soup(url)
        next_page = url_soup.find('', {'class', 'next_page disabled'})
        if next_page is None:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.h1.string[7:]

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.find('', {'class', "user-post"}).find_all('p')[1:]

class Macmillan(Community):
    def __init__(self):
        super().__init__(url)
        self.url = 'https://community.macmillan.org.uk/cancer_types/breast-cancer/discussions?pi5752=1'

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all('h4', {'class', 'post-name'})
        url_list = []
        for post in posts:
            if len(post.get('class')) != 1:
                posts.remove(post)
            else:
                post_url = 'https://community.macmillan.org.uk/' + post.find('a').get('href')
                url_list.append(post_url)
        return url_list

    def reach_last_page(self, url):
        url_soup = Community.get_soup(url)
        next_page = url_soup.find('a', {'class', 'next'})
        if next_page is not None:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.find('h4', {'class', 'post-name'}).string

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        tags = url_soup.find(lambda tag: tag.get('class') == ['content'])
        body = ''
        for tag in tags:
            if tag.string is not None:
                body = body + tag.string
        return body

class AUSBRCAForum(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'https://www.bcaus.org.au/phpBB3'

    @classmethod
    def get_forums(cls, url):
        """Returns a list of url of forums

        :param url: Url of the index page
        :type url: str
        :return: A list of url of forums in the same category
        """
        url_soup = Community.get_soup(url)
        forums = url_soup.find_all('a', {'class', 'forumtitle'})[1:6]
        del forums[3]
        link_list = []
        for forum in forums:
            link = forum.get('href')
            link = 'https://www.bcaus.org.au/phpBB3' + link[1:]
            link_list.append(link)
        return link_list

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all(class_='icon topic_read') + url_soup.find_all(class_='icon topic_read_hot')
        url_list = []
        for post in posts:
            if post.find(class_='pagination') is not None:
                print(post.find(class_='pagination').find_all('li')[-1])
                post_url = 'https://www.bcaus.org.au/phpBB3' + post.find(class_='pagination').find_all('li')[-1].find(
                    'a').get('href')[1:]
            else:
                post = post.find(class_='topictitle')
                post_url = 'https://www.bcaus.org.au/phpBB3' + post.get('href')[1:]
            url_list.append(post_url)
        return url_list

    def get_next_page(self, url, delimiter):
        delimiter = '='
        url = url.split(delimiter)
        if len(url) == 2:
            url = url[0] + '&start=50'
        else:
            url[-1] = str(int(url[-1]) + 50)
            url = delimiter.join(url)
        return url

    def reach_last_page(self, url):
        url_soup = Community.get_soup(url)
        next_page = url_soup.find(class_='next')
        if next_page is not None:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.find(class_='topic-title').string

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        return str(url_soup.find_all(lambda tag: tag.get('class') == ['content'])[-1])

class KoreaVenus(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'http://www.koreavenus.com/db/index.html?table=noh_qna'

class CancerSuvivorsNetwork(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'https://csn.cancer.org/forum/127'

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all('td', {'class', 'title'})
        url_list = []
        for post in posts:
            if post.div.a.string != '*Abbreviations* for all our Newbies':
                post_url = 'https://csn.cancer.org' + post.div.a.get('href')
                url_list.append(post_url)
        return url_list

    def get_next_page(self, url, delimiter):
        delimiter = '='
        url = url.split(delimiter)
        if len(url) == 1:
            url = url[0] + '?page=1'
        else:
            url[-1] = str(int(url[-1]) + 1)
            url = delimiter.join(url)
        return url

    def reach_last_page(self, url):
        url_soup = Community.get_soup(url)
        if url_soup.find(class_='pager-current last') is None:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        return url_soup.find(class_='with-tabs').string

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        return str(url_soup.find('p').contents)

class HealthBoards(Community):
    def __init__(self, url):
        super().__init__(url)
        self.url = 'https://www.healthboards.com/boards/cancer-breast/index1.html'

    def get_posts(self, url):
        url_soup = Community.get_soup(url)
        posts = url_soup.find_all(class_='alt1')
        url_list = []
        for post in posts:
            if post.find('div') is not None:
                if post.find('div').find('a') is not None:
                    post_url = post.div.a.get('href')
                    if 'cancer-breast' in post_url:
                        url_list.append(post_url)
        del url_list[-1]
        return url_list

    def get_next_page(self, url, delimiter):
        # no delimiter is needed
        url_soup = Community.get_soup(url)
        return url_soup.find(rel='next').get('href')

    def reach_last_page(self, url):
        url_soup = Community.get_soup(url)
        if url_soup.find(rel='next') is not None:
            return False

    def get_title(self, url):
        url_soup = Community.get_soup(url)
        tags = url_soup.find_all(style='display: inline-block;')
        for tag in tags:
            if tag.find('strong') is not None:
                return tag.find('strong').string

    def get_body(self, url):
        url_soup = Community.get_soup(url)
        return str(url_soup.find(class_='alt1'))


from cs1graphics import *
from time import sleep

class Bear(Layer):
    """A layer instance representing a Bear.

    The user can choose and alter the color, make the bear roar and walk """

    def __init__(self, bodyColor='brown', earColor='pink', eyeColor='black'):
        """Creates a new instance of the Bear class

        The reference point of the bear is the bottom middle of the Bear.

        bodyColor     the initial color of the body of the Bear
        earColor      the initial color of the ears of the Bear
        eyeColor      the initial color of the eyes of the Bear
        """
        Layer.__init__(self)

        self._leg1 = Rectangle(10,30,Point(-35,10))
        self._leg1.adjustReference(5,-15)
        self._leg1.setFillColor(bodyColor)
        self.add(self._leg1)

        self._leg2 = Rectangle(10,30,Point(35,10))
        self._leg2.adjustReference(5,-15)
        self._leg2.setFillColor(bodyColor)
        self.add(self._leg2)

        self._leg3 = Rectangle(10,30,Point(-37,10))
        self._leg3.adjustReference(-5,-15)
        self._leg3.setFillColor(bodyColor)
        self.add(self._leg3)

        self._leg4 = Rectangle(10,30,Point(37,10))
        self._leg4.adjustReference(-5,-15)
        self._leg4.setFillColor(bodyColor)
        self.add(self._leg4)

        self._face = Circle(30,Point(40,-30))
        self._face.setDepth(30)
        self._face.setFillColor(bodyColor)
        self.add(self._face)

        self._ear1 = Circle(12,Point(10,-50))
        self._ear1.setBorderWidth(2)
        self._ear1.setBorderColor(bodyColor)
        self._ear1.setFillColor(earColor)
        self.add(self._ear1)

        self._ear2 = Circle(12,Point(70,-50))
        self._ear2.setBorderWidth(2)
        self._ear2.setBorderColor(bodyColor)
        self._ear2.setFillColor(earColor)
        self.add(self._ear2)

        self._eye1 = Circle(3,Point(47,-38))
        self._eye1.setFillColor(eyeColor)
        self._eye1.setBorderColor(eyeColor)
        self._eye1.setDepth(30)
        self.add(self._eye1)

        self._eye2 = Circle(3,Point(33,-38))
        self._eye2.setFillColor(eyeColor)
        self._eye2.setBorderColor(eyeColor)
        self._eye2.setDepth(30)
        self.add(self._eye2)

        self._mouth=Spline(Point(33,-18),Point(40,-8),Point(47,-18))
        self._mouth.adjustReference(7,10)
        self._mouth.setBorderWidth(3)
        self._mouth.setDepth(0)
        self.add(self._mouth)

        self._roar = Circle(5,Point(40,-20))
        self._roar.setFillColor('black')
        self._roar.setDepth(0)
        self._roarOpen = False

        self._body=Rectangle(90,30,Point(0,-15))
        self._body.setFillColor(bodyColor)
        self.add(self._body)

    def roarIsOpen(self):
        """Returns True if roar is open; False otherwise"""
        return self._roarOpen

    def toggleRoar(self):
        """ Switches the state of the roar to the opposite

        That is, adds the roar if not active; removes if active.

        The default behavior is the roar is not active
        """
        increment=1
        if self._roarOpen==False:
            for i in range(80):
                sleep(0.01)
                self._mouth.scale(1-increment/100.0)
            self.remove(self._mouth)
            self.add(self._roar)
            for j in range(80):
                sleep(0.01)
                self._roar.scale(1+increment/100.0)
            self._roarOpen = not self._roarOpen

        else:
            for i in range(80):
                sleep(0.01)
                self._roar.scale(1-increment/100.0)
            self.remove(self._roar)
            self.add(self._mouth)
            for j in range(80):
                sleep(0.01)
                self._mouth.scale(1+increment/100.0)
            self._roarOpen = not self._roarOpen

    def walk(self):
        """Make the bear"""
        for i in range(45):
            sleep(0.01)
            self._leg1.rotate(1)
            self._leg2.rotate(1)
            self._leg3.rotate(-1)
            self._leg4.rotate(-1)
        for k in range(45):
            sleep(0.01)
            self._leg1.rotate(-1)
            self._leg2.rotate(-1)
            self._leg3.rotate(1)
            self._leg4.rotate(1)

    def setBodyColor(self,newColor):
        """Change the color of the body of the bear

        newColor     the color which the bear will become"""
        self._leg1.setFillColor(newColor)
        self._leg2.setFillColor(newColor)
        self._leg3.setFillColor(newColor)
        self._leg4.setFillColor(newColor)
        self._ear1.setBorderColor(newColor)
        self._ear2.setBorderColor(newColor)
        self._face.setFillColor(newColor)
        self._body.setFillColor(newColor)

    def setEarColor(self,newColor):
        """Change the ear color of the bear

        newColor     the color which the ears will become"""
        self._ear1.setFillColor(newColor)
        self._ear2.setFillColor(newColor)

    def setEyeColor(self,newColor):
        """Change the eye color of the bear

        newColor     the color which the eyes will become"""
        self._eye1.setFillColor(newColor)
        self._eye1.setBorderColor(newColor)
        self._eye2.setFillColor(newColor)
        self._eye2.setBorderColor(newColor)

if __name__ =='__main__':
    #normal behavior
    paper=Canvas(600,600)
    normal=Bear()
    normal.move(200,200)
    paper.add(normal)

    raw_input('Press enter to continue')
    #change the body color
    bodyChange= Bear()
    bodyChange.move(200,400)
    paper.add(bodyChange)
    bodyChange.setBodyColor('purple')

    raw_input('Press enter to continue')
    #change eye color
    eyeChange = Bear()
    eyeChange.move(400,400)
    paper.add(eyeChange)
    eyeChange.setEyeColor('yellow')

    raw_input('Press enter to continue')
    #change ear color
    earChange = Bear()
    earChange.move(400,200)
    earChange.setEarColor('purple')
    paper.add(earChange)

    raw_input('Press enter to continue')
    #toggleRoar
    roaring = Bear()
    roaring.move(200,500)
    paper.add(roaring)
    roaring.toggleRoar()


# ClimbingAnalysis application
# Written by Andrew Watkins
# watkins(dot)andrewb(at)gmail(dot)com
#
# This dash application gives a basic exploration
# of USA Climbings initial results for regional qualification
# for Virtual Qualifiers in the bouldering season of 2020

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
import plotly.express as px
import pandas as pd

from dash.dependencies import Input, Output

fname ='assets/current_results.csv'
df = pd.read_csv(fname)

app = dash.Dash(__name__)
app.index_string = '''
<!DOCTYPE html>
<html>
    <head>
        {%metas%}
        <title>USAC Virutal QE Climbing Analysis</title>
        {%favicon%}
        {%css%}
    </head>
    <body>
        {%app_entry%}
        <footer>
            {%config%}
            {%scripts%}
            {%renderer%}
        </footer>
    </body>
</html>
'''
rlist = [ x for x in range(10,100) if x%10==1 or x%10==2]
catList=['FJR', 'MJR', 'FYA', 'MYA', 'FYB', 'MYB', 'FYC', 'MYC', 'FYD', 'MYD']
catColors ={'FJR':"#ffa822", 'MJR':"#b36b00",
            'FYA':"#134e6f", 'MYA':"#071e2c",
            'FYB':"#ff6150", 'MYB':"#ff1a00",
            'FYC':"#1ac0c6", 'MYC': "#128387",
            'FYD':"#b6bbc8", 'MYD': "#8b93a7"}
bgcolor = '#f2f2f2'

def genericScatter(df, compScore=0, compCat=None):
    if compCat != None:
        df = df[df['Category'].isin(compCat)]
    fig = px.scatter(df, x="Region", y="Score", color="Category",
                hover_data=['Score'],
                color_discrete_map=catColors,
                category_orders ={'Region':rlist, 'Category':catList},
                title="Qualifying Event Scores by Region and Category",
                )
    if compScore>0:
        fig.add_hline(y=compScore, annotation_text = 'Your Climber\'s Score',annotation_position='top left',
                    line_dash='dash')
    fig.update_xaxes(type='category')
    fig.update_layout(paper_bgcolor=bgcolor,
                        #plot_bgcolor='#eff8fb',
                        font_family="Futura")
    return fig

def avgScatter(df, compScore =0, compCat = None):
    gf = df.groupby(['Region', 'Category'], as_index=False)['Score'].mean()
    fig = px.scatter(gf if compCat == None else gf[gf['Category'].isin(compCat)], x="Region", y="Score", color="Category",
                     hover_data=['Score'],
                     color_discrete_map=catColors,
                    category_orders ={'Region':rlist, 'Category':catList},
                    labels=dict(Score='Average Score'),
                    title='Average QE Score by Region and Category')
    fig.update_xaxes(type='category')
    if compScore>0:
        fig.add_hline(compScore, annotation_text = 'Your Climber\'s Score', annotation_position='top left',
                        line_dash='dash')
    fig.update_layout(paper_bgcolor=bgcolor,
                    font_family="Futura")
    return fig

def catHistogram(df, compScore = 0, compCat = None):
    fig = px.histogram(df if compCat == None else df[df['Category'].isin(compCat)], x="Score", color='Category',
                        color_discrete_map=catColors,
                       category_orders ={'Region':rlist, 'Category':catList},
                       title="Histogram of Scores by Climbing Category (200 point bins)")
    if compScore>0:
        fig.add_vline(compScore, annotation_text = 'Your Climber\'s Score',
                        annotation_position="top left",
                        line_dash='dash')
    fig.update_layout(paper_bgcolor=bgcolor,
                    font_family="Futura")
    return fig

def allHistogram(df, compScore = 0, compCat = None):
    fig=px.histogram(df,x='Score', title='Histogram of QE Scores (200 point bins)')
    if compScore>0:
        fig.add_vline(compScore, annotation_text = 'Your Climber\'s Score',
                        annotation_position="top left",
                        line_dash = 'dash')
    fig.update_layout(paper_bgcolor=bgcolor)
    return fig

def findPlace(df, testScore=0, testRegions=None, testCats = None):
    retdf = pd.DataFrame(columns=['Region','Category', 'Place', 'Number of Climbers'])
    if(testScore<=0):
        return retdf
    if testRegions==None:
        testRegions = [ x for x in range(10,100) if x%10==1 or x%10==2]
    if testCats == None:
        testCats = ['FJR', 'MJR', 'FYA', 'MYA', 'FYB', 'MYB', 'FYC', 'MYC', 'FYD', 'MYD']
    for reg in testRegions:
        for cat in testCats:
            tf = df[df['Region']==reg]
            tf = tf[tf['Category']==cat]
            totalClimbers = len(tf)
            tf = tf[tf['Score']>testScore]
            place = len(tf)+1
            if totalClimbers>0:
                row = [reg,cat,place,totalClimbers]
                retdf = retdf.append(pd.Series(row,index=retdf.columns), ignore_index = True)
    return retdf

# Not really using the region_drop down any more
region_drop = html.Div([
    dcc.Markdown('''**Choose one or more regions** (or leave blank for all) '''),
    dcc.Dropdown(
        id='dropdown-reg',
        options=[{'label':i,'value':i} for i in rlist],
        multi=True,
        placeholder='Select one or more regions',
        ),])

cat_drop = html.Div([
    dcc.Markdown('''**Choose your climber's category**'''),
    dcc.Dropdown(
        id='dropdown-cat',
        options =[{'label':i,'value':i} for i in catList],
        multi=True,
        #value=None,
        placeholder='Select one or more categories',
    ),], className='offset-by-two columns three columns')
score_input = html.Div([
    dcc.Markdown('''**Enter your climber's score**'''),
    dcc.Input(id='inputScore', type='number', min=0, step=50,
    placeholder='2000', value=2000,
    autoFocus = True),
], className = 'two columns')

table_results = html.Div([
    html.Div(id='score-output-container'),
    dcc.Markdown('''your climber would have placed as follows in the selected categories '''),
    dash_table.DataTable(id='compTable',
        style_cell={'font-family': 'Futura'},
        style_data_conditional=[
        {
            'if': {'row_index': 'odd'},
            'backgroundColor': bgcolor
            }
            ]
        )
    ], className ='four columns')

visuals = html.Div([
    html.Div([
    dcc.Markdown('''Hover over the graphs to see more information about each data point
    '''),
    dcc.Graph(
        id='genScat',
    ),
    dcc.Graph(
        id='avgScat',
    ),
    dcc.Graph(
        id='catHist',
    ),
#    dcc.Graph(
#        id='allHist',
#        figure=allHFig
#    )
    ],className='eight columns',),
])

app.layout = html.Div(children=[
    html.Div([
    html.H2(children='Virtual Bouldering Regional Qualifier Events Across USAC Regions', style={"text-align": "center"}),
    dcc.Markdown(children='''Based off of file: <http://www.usaclimbing.org/Assets/Regional+Ranking-Preliminary-201220d.pdf> (as of 1/5/2021)''', style={"text-align": "center"}),
    html.P(style={"text-align": "center"},children='Use this tool to compare a climber\'s score to others or to see general trends among climbers at QEs across the country'),
    html.Br(),
    ],),

    html.Div([
    score_input, cat_drop,], className='offset-by-one columns row'),
    html.Hr(), html.Hr(),
    html.Div([table_results
    , visuals,
        ],className="row"),
   html.Div([
    dcc.Markdown(children='''Source code can be found on github: <https://github.com/ABWatkins/USACVirtualQEClimbingAnalysis>''', style={"text-align": "center"}),
    dcc.Markdown(children='''Developed by Andrew Watkins: watkins dot andrewb at gmail dot com''', style={"text-align": "center"})]),
])

@app.callback(
    Output('compTable', 'data'),
    Output('compTable', 'columns'),
   Output('score-output-container', 'children'),
    Input('dropdown-cat', 'value'),
    Input('inputScore', 'value')
)
def getDataTable(compCat = None, compScore = 0):
    if compCat == []:
        compCat = None
    if compScore == None:
        compScore = 0
    compDF=findPlace(df, testScore= compScore, testRegions=None, testCats=compCat)
    data=compDF.to_dict('records')
    columns=[{'id': c, 'name': c} for c in compDF.columns]
    return data,columns, 'With a score of {}'.format(compScore)

@app.callback(
    Output('genScat', 'figure'),
    Input('dropdown-cat', 'value'),
    Input('inputScore', 'value'))
def getGenScat(compCat = None, compScore = 0):
    if compCat == []:
        compCat = None
    if compScore == None:
        compScore = 0
    return genericScatter(df, compScore,compCat)

@app.callback(
    Output('avgScat', 'figure'),
    Input('dropdown-cat', 'value'),
    Input('inputScore', 'value'))
def getAvgScat(compCat = None, compScore = 0):
    if compCat == []:
        compCat = None
    if compScore == None:
        compScore = 0
    return avgScatter(df, compScore,compCat)

@app.callback(
    Output('catHist', 'figure'),
    Input('dropdown-cat', 'value'),
    Input('inputScore', 'value'))
def getCatHist(compCat = None, compScore = 0):
    if compCat == []:
        compCat = None
    if compScore == None:
        compScore = 0
    return catHistogram(df, compScore,compCat)

# @app.callback(
#     Output('allHist', 'figure'),
#     #Input('dropdown-reg', 'value'),
#     Input('dropdown-cat', 'value'),
#     Input('inputScore', 'value'))
# def getAllHist(compCat = None, compScore = 0):
#     if compCat == []:
#         compCat = None
#     if compScore == None:
#         compScore = 0
#     return allHistogram(df, compScore,compCat)

if __name__ == '__main__':
    app.run_server(debug=True,host='127.0.0.1')


import re
import tornado.web
import sqlalchemy
import os
import json

import tensorflow as tf

from .query_handlers import QueryHandler, TokenizeHandler
from .learn_handler import LearnHandler
from .admin_handlers import ReloadHandler, ExactMatcherReload
from .exact import ExactMatcher
from .tokenizer import Tokenizer
from .predictor import Predictor

class LanguageContext(object):
    def __init__(self, tag, language_tag, model_tag, tokenizer, predictor):
        self.tag = tag
        self.language_tag = language_tag
        self.model_tag = model_tag
        self.tokenizer = tokenizer
        self.predictor = predictor

class Application(tornado.web.Application):
    def __init__(self, config, thread_pool, tokenizer_service):
        super().__init__([
            (r"/query", QueryHandler),
            (r"/learn", LearnHandler),
            (r"/(?P<locale>[a-zA-Z-]+)/tokenize", TokenizeHandler),
            (r"/(?P<locale>[a-zA-Z-]+)/query", QueryHandler),
            (r"/(?P<locale>[a-zA-Z-]+)/learn", LearnHandler),
            (r"/(?P<locale>[a-zA-Z-]+)/admin/reload", ReloadHandler),
            (r"/(?P<locale>[a-zA-Z-]+)/admin/exact/reload", ExactMatcherReload),
            (r"/@(?P<model_tag>[a-zA-Z0-9_\.-]+)/(?P<locale>[a-zA-Z-]+)/tokenize", TokenizeHandler),
            (r"/@(?P<model_tag>[a-zA-Z0-9_\.-]+)/(?P<locale>[a-zA-Z-]+)/query", QueryHandler),
            (r"/@(?P<model_tag>[a-zA-Z0-9_\.-]+)/(?P<locale>[a-zA-Z-]+)/learn", LearnHandler),
            (r"/@(?P<model_tag>[a-zA-Z0-9_\.-]+)/(?P<locale>[a-zA-Z-]+)/admin/reload", ReloadHandler),
            (r"/@(?P<model_tag>[a-zA-Z0-9_\.-]+)/(?P<locale>[a-zA-Z-]+)/admin/exact/reload", ExactMatcherReload),
        ])

        if config.db_url:
            self.database = sqlalchemy.create_engine(config.db_url, pool_recycle=600)
        else:
            self.database = None
        self.config = config
        self._languages = dict()
        self.thread_pool = thread_pool
        self._tokenizer = tokenizer_service

    def _load_language(self, language_tag, model_tag, model_dir):
        with tf.gfile.Open(os.path.join(model_dir, "model.json")) as fp:
            config = json.load(fp)

        tokenizer = Tokenizer(self._tokenizer, language_tag)
        predictor = Predictor(model_dir, config)

        if model_tag is not None:
            tag = '@%s/%s' % (model_tag, language_tag)
        else:
            tag = language_tag

        language = LanguageContext(tag, language_tag, model_tag, tokenizer, predictor)
        self._languages[tag] = language
        if self.database:
            language.exact = ExactMatcher(self.database, language_tag, model_tag)
            language.exact.load()
        else:
            language.exact = None
        if model_tag is not None:
            tf.logging.info('Loaded model @%s/%s', model_tag, language_tag)
        else:
            tf.logging.info('Loaded model @default/%s', language_tag)

    def load_all_languages(self):
        for tag in self.config.languages:
            if tag.startswith('@'):
                model_tag, language_tag = tag.split('/')
                model_tag = model_tag[1:]
            else:
                language_tag = tag
                model_tag = None
            self._load_language(language_tag, model_tag, self.config.get_model_directory(tag))

    def reload_language(self, language_tag, model_tag=None):
        if model_tag is not None:
            tag = '@%s/%s' % (model_tag, language_tag)
            tf.logging.info('Reloading model @%s/%s', model_tag, language_tag)
        else:
            tag = language_tag
            tf.logging.info('Reloading model @default/%s', language_tag)
        self._load_language(language_tag, model_tag, self.config.get_model_directory(tag))

    def get_language(self, locale, model_tag=None):
        '''
        Convert a locale tag into a preloaded language
        '''

        if model_tag == 'default':
            model_tag = None

        split_tag = re.split("[_\\.\\-]", locale)

        # try with language and country
        language = None
        if len(split_tag) >= 2:
            key = split_tag[0] + "-" + split_tag[1]
            if model_tag is not None:
                key = '@' + model_tag + '/' + key
            language = self._languages.get(key, None)
        if language is None and len(split_tag) >= 1:
            key = split_tag[0]
            if model_tag is not None:
                key = '@' + model_tag + '/' + key
            language = self._languages.get(key, None)

        # fallback to english if the language is not recognized or
        # locale was not specified
        if language:
            return language
        else:
            if model_tag is not None:
                key = '@' + model_tag + '/' + self.config.default_language
                language = self._languages.get(key, None)
                if language is not None:
                    return language
                else:
                    tf.logging.warning("Ignored model tag " + model_tag)

            return self._languages[self.config.default_language]


from .settings_common import *  # noqa
from .settings import *  # noqa

WSGI_APPLICATION = 'nap_meetbouten.wsgi'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,

    'formatters': {
        'slack': {
            'format': '%(message)s',
        },
        'console': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        },
    },

    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'console',
        },
    },

    'root': {
        'level': 'INFO',
        'handlers': ['console'],
    },

    'loggers': {
        # Debug all batch jobs
        'batch': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },

        'search': {
            'handlers': ['console'],
            'level': 'ERROR',
            'propagate': False,
        },

        'elasticsearch': {
            'handlers': ['console'],
            'level': 'ERROR',
            'propagate': False,
        },

        'urllib3.connectionpool': {
            'handlers': ['console'],
            'level': 'ERROR',
            'propagate': False,
        },

        # Log all unhandled exceptions
        'django.request': {
            'handlers': ['console'],
            'level': 'ERROR',
            'propagate': False,
        },
    },
}

# DEBUG=False
STATIC_ROOT = '/static/'
STATIC_URL = '/nap/static/'

DIVA_DIR = '/app/data/'

# Generate https links
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')


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

import os
import sys
import re
from setuptools import setup, find_packages

if sys.argv[-1] == 'publish':
    os.system('python3 setup.py sdist')
    os.system('twine upload dist/*')
    sys.exit()

def readme():
    with open('README.rst') as readme_file:
        return readme_file.read()

def find_version():
    with open('ctfile/__init__.py', 'r') as fd:
        version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
                            fd.read(), re.MULTILINE).group(1)
    if not version:
        raise RuntimeError('Cannot find version information')
    return version

REQUIRES = [
    'docopt >= 0.6.2',
    'filehandles >= 0.3.1',
    'more_itertools >= 4.1.0'
]

setup(
    name='ctfile',
    version=find_version(),
    author='Andrey Smelter, Huan Jin',
    author_email='andrey.smelter@gmail.com, jinhuan0905@gmail.com',
    description='Parser for chemical table file (CTfile) a family of text-based chemical file formats '
                '(e.g. Molfile, SDfile) that describe molecules and chemical reactions.',
    keywords='CTfile SDfile Molfile Ctab',
    license='BSD',
    url='https://github.com/MoseleyBioinformaticsLab/ctfile',
    packages=find_packages(),
    package_data={'ctfile': ['config_files/*.json']},
    platforms='any',
    long_description=readme(),
    install_requires=REQUIRES,
    classifiers=[
        'Development Status :: 4 - Beta',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: BSD License',
        'Operating System :: OS Independent',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Topic :: Scientific/Engineering :: Bio-Informatics',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
)


from setuptools import setup, find_packages
import codecs
import os

here = os.path.abspath(os.path.dirname(__file__))

with codecs.open(os.path.join(here, "README.md"), encoding="utf-8") as fh:
    long_description = "\n" + fh.read()

VERSION = '0.0.2'
DESCRIPTION = 'Solver para sistema linear de equações algébricas'
LONG_DESCRIPTION = 'Use "from Solveq import *" para importar a biblioteca e "exemplo1()" para ver um exemplo de uso'

# Setting up
setup(
    name="Solveq",
    version=VERSION,
    author=["Rogério","Amanda"],
    author_email="<pazetto1998@gmail.com>",
    description=DESCRIPTION,
    long_description_content_type="text/markdown",
    long_description=long_description,
    packages=find_packages(),
    install_requires=[],
    keywords=['python', 'equação', 'sistema', 'solver', 'linear'],
    classifiers=[
        "Development Status :: 1 - Planning",
        "Intended Audience :: Developers",
        "Programming Language :: Python :: 3",
        "Operating System :: Unix",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
    ]
)


from collections import defaultdict
import json
import numpy as np
try:
    from tqdm import tqdm
except ImportError:
    tqdm = lambda x, *args, **kwargs: x

from utils import check_dir_or_create, word_clean, get_clean_words

class ErrorModel:

    def __init__(self):
        self.stat = defaultdict(lambda: defaultdict(int))
        # {'orig' : {'fix' : P(orig|fix)}}
        self._stat_size = 0

    @staticmethod
    def make_bigrams(word):
        word = '^' + word + '_'
        bigrams = []
        for i in range(len(word) - 1):
            bigrams.append(word[i:i + 2])
        return bigrams

    @staticmethod
    def _levenshtein_matrix(a, b):
        n, m = len(a), len(b)
        need_transpose = False
        if n > m:
            a, b = b, a
            n, m = m, n
            need_transpose = True

        current = list(range(n + 1))
        previous = current
        lv_matrix = np.array([current])
        for i in range(1, m + 1):
            prev_previous, previous, current = previous, current, [i] + [0] * n
            for j in range(1, n + 1):
                a_ne_b = int(a[j - 1] != b[i - 1])
                add    = previous[j] + 1
                delete = current[j - 1] + 1
                change = previous[j - 1] + a_ne_b

                # transpose = change
                # if j > 1 and i > 1 and a[j - 2] == b[i - 1] and a[j - 1] == b[j - 2]:
                #     transpose = prev_previous[j - 2] + a_ne_b

                current[j] = min(add, delete, change)#, transpose)
            lv_matrix = np.vstack((lv_matrix, [current]))
        return lv_matrix.T if need_transpose else lv_matrix

    def _add_stats(self, orig, fix):
        self.stat[orig][fix] += 1
        self._stat_size += 1

    def _get_stats(self, orig, fix):
        if orig in self.stat and fit in self.stat[orig]:
            return self.stat[orig][fit]
        return 1.0 / self._stat_size

    def _fill_stats(self, a, b, lv_matrix):
        i, j = len(a), len(b)
        cur_distance = lv_matrix[len(b), len(a)]

        while cur_distance != 0:
            add = lv_matrix[j - 1, i] if j > 0 else np.inf
            delete = lv_matrix[j, i - 1] if i > 0 else np.inf
            change = lv_matrix[j - 1, i - 1] if j > 0 and i > 0 else np.inf

            operation = np.argmin([change, add, delete]).item()

            if operation == 0:
                i -= 1
                j -= 1
                if cur_distance != change:
                    cur_distance = change
                    self._add_stats(a[i], b[j])

            elif operation == 1:
                j -= 1
                if cur_distance != add:
                    cur_distance = add
                    self._add_stats(a[i - 1][1] + '~', b[j])
            else:
                i -= 1
                if cur_distance != delete:
                    cur_distance = delete
                    self._add_stats(a[i], b[j - 1][1] + '~')

    def normalize_stat(self):
        for orig in self.stat:
            for fix in self.stat[orig]:
                self.stat[orig][fix] /= self._stat_size

    def make_model(self, filename="queries_all.txt"):
        self.stat = defaultdict(lambda: defaultdict(int))
        self._stat_size = 0
        with open(filename, 'r') as f:
            if filename == 'queries_all.txt':
                tqdm_cur = lambda x: tqdm(x, total=2000000)
            else:
                tqdm_cur = tqdm
            for line in tqdm_cur(f):
                if '\t' not in line:
                    continue
                wrong, right = line.lower().split('\t')
                wrong = get_clean_words(wrong)
                right = get_clean_words(right)

                if len(wrong) != len(right):  # join or split
                    continue

                for wrong_word, right_word in zip(wrong, right):
                    wrong_bigrams = self.make_bigrams(wrong_word)
                    right_bigrams = self.make_bigrams(right_word)
                    lv_matrix = self._levenshtein_matrix(wrong_bigrams, right_bigrams)
                    self._fill_stats(wrong_bigrams, right_bigrams, lv_matrix)

        self.normalize_stat()

    def save_model(self, filename='stats.json', directory='prepared_data'):
        check_dir_or_create(directory)
        with open(directory + '/' + filename, 'w') as f:
            f.write(json.dumps((self._stat_size, self.stat)))

    def load_model(self, filename='stats.json', directory='prepared_data'):
        check_dir_or_create(directory)
        with open(directory + '/' + filename, 'r') as f:
            self._stat_size, self.stat = json.loads(f.read())


def words_sorting(*args):
    word_dic = {}
    for word in args:
        ascii_value = 0
        for letter in word:
            ascii_value += ord(letter)
        word_dic[word] = ascii_value
    if sum(word_dic.values()) % 2 == 0:
        word_dic = sorted(word_dic.items(), key=lambda x: x[0])
    else:
        word_dic = sorted(word_dic.items(), key=lambda x: -x[1] )
    print_list = []

    for el in word_dic:
        print_list.append(f'{el[0]} - {el[1]}\n')
    return ''.join(print_list)
print(
    words_sorting(
        'escape',
        'charm',
        'mythology'
  ))

print(
    words_sorting(
        'escape',
        'charm',
        'eye'
  ))

print(
    words_sorting(
        'cacophony',
        'accolade'
  ))


import datetime
import sys
import os
import psutil

current = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.abspath(os.path.join(current, "../../../../pylibs/snake")))
from snake import SnakeGame

class Statistics:
    def __init__(self, game:SnakeGame):
        self.process = psutil.Process()
        self.game = game
        self.max_reward = 0.0
        self.sum_rewards = 0.0
        self.max_moves = 0
        self.sum_moves = 0
        self.max_apples = 0
        self.sum_apples = 0
        self.games = 0

    def collect(self):
        if self.game.game_over:
            self.games += 1

        if self.game.reward > self.max_reward:
            self.max_reward = self.game.reward
        if self.max_moves < self.game.moves_made:
            self.max_moves = self.game.moves_made
        if self.max_apples < self.game.consumed_apples:
            self.max_apples = self.game.consumed_apples

        self.sum_rewards += self.game.reward
        self.sum_moves += self.game.moves_made
        self.sum_apples += self.game.consumed_apples

    def print_progress(self, epoch:int, num_epochs:int, interval_epochs:int, epsilon:float):
        if epoch > 0 and epoch % interval_epochs == 0:
            percent_complete = (epoch / num_epochs) * 100
            ct = datetime.datetime.now().strftime("%H:%M:%S")
            print(f"{ct}==> Processing {percent_complete:.0f}% complete. {epoch} of {num_epochs} games.")
            self._print(epsilon)

    def _print(self, epsilon:float):
        avgReward = self.sum_rewards / self.games
        avgMoves = self.sum_moves / self.games
        avgApples = self.sum_apples / self.games

        exp = epsilon*100
        if exp < 0: # It may be less than 0 - depends of epsilon_decay
            exp = 0.0

        print(f"->apples(max:{self.max_apples}, avg:{avgApples:.3f})"
            f" moves(max:{self.max_moves}, avg:{avgMoves:.3f})"
            f" reward(max:{self.max_reward}, avg:{avgReward:.3f})."
            f" Exploration: {exp:.0f}%  MemUsage: {self.get_memory_usage_mb():.2f} MB")
        self.games = 0
        self.max_reward = 0.0
        self.sum_rewards = 0.0
        self.max_moves = 0
        self.sum_moves = 0
        self.max_apples = 0
        self.sum_apples = 0

    def get_memory_usage_mb(self):
        mem_info = self.process.memory_info()
        mem_usage_mb = mem_info.rss / (1024 * 1024)
        return mem_usage_mb


import sys

sys.path.append('../detector')
import detect_video as detect_video

class Detector:
    def __init__(self):
        pass

    def detect(self, img, roi=None):
        '''

        :param img:
        :param roi: [left, top, right, bottom]
        :return:  [[left, top, right, bottom], ...]
        '''
        detect_img = img
        if roi is not None:
            image_h, image_w, _ = detect_img.shape
            l, t, r, b = detect_video.double_rect(roi)
            l = max(0, l)
            t = max(0, t)
            r = min(r, image_w)
            b = min(b, image_h)
            detect_img = detect_img[t:b, l:r, ...]
            bboxs = detect_video.predict(detect_img)
            for box in bboxs:
                box[0] = box[0] + l
                box[2] = box[2] + l
                box[1] = box[1] + t
                box[3] = box[3] + t
        else:
            bboxs = detect_video.predict(detect_img)
        if len(bboxs) > 0:
            bboxs = [box[:4] for box in bboxs]
        return bboxs


import sys
import json
from kapacitor.udf.agent import Agent, Handler, Server
from kapacitor.udf import udf_pb2
import signal
import logging
import re

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(name)s: %(message)s')
logger = logging.getLogger()

# Mirrors all points it receives back to Kapacitor
class Handler(Handler):
    def __init__(self, agent):
        self._agent = agent
        self._path = 'file:///data/.kapacitor/load/sideloadFiles'
        self._source = None
        self._formula = None
        self._eval = ''
        self._levels = []
        self._messages = []
        self._vars = []

    def parse_formula(self):
        _var = list(filter(None, re.split('[()+/\-* ]', self._formula)))
        _op = re.findall('[()+\-/* ]+', self._formula)

        for i in range(len(_var)):
            if re.fullmatch('\d+', _var[i]) is None:
                _var[i] = 'point.fieldsDouble[\'{}\']'.format(_var[i])

        if _op[0] == '(':
            for i in range(len(_var)):
                self._eval = '{}{}{}'.format(self._eval, _op[i], _var[i])
        else:
            for i in range(len(_var) - 1):
                self._eval = '{}{}{}'.format(self._eval, _var[i], _op[i])
            self._eval = '{}{}'.format(self._eval, _var[len(_var) - 1])

        if _op[len(_op) - 1] == ')':
            self._eval = '{})'.format(self._eval)

        self._vars = _var

    def parse_file(self):
        self._levels = []
        self._messages = []
        data = open("/data/.kapacitor/load/sideloadFiles/{}".format(self._source), 'r')
        for line in data:
            level, message = line.split('\t')
            self._levels.append(int(level))
            self._messages.append(message)

        data.close()

    def info(self):
        response = udf_pb2.Response()
        response.info.wants = udf_pb2.STREAM
        response.info.provides = udf_pb2.STREAM
        response.info.options['source'].valueTypes.append(udf_pb2.STRING)
        response.info.options['formula'].valueTypes.append(udf_pb2.STRING)
        return response

    def init(self, init_req):                   #init response
#logger.info("Init Response")
        response = udf_pb2.Response()
        success = True
        msg = ''

        for opt in init_req.options:
            if opt.name == 'source':
                self._source = opt.values[0].stringValue
            elif opt.name == 'formula':
                self._formula = opt.values[0].stringValue

        if self._source is None:
            success = False
            msg += ' must supply source'
            logger.info('No ok')
        if self._formula is None:
            success = False
            msg += ' must supply formula'
            logger.info('No ok')

        response = udf_pb2.Response()
        response.init.success = success
        response.init.error = msg[1:]

        if success:
            self.parse_formula()
            self.parse_file()

        return response

    def snapshot(self):                         #snapshor state
#logger.info("Snapshot Response")
        response = udf_pb2.Response()
        return response

    def restore(self, restore_req):             #restore ?
#logger.info("Restore Response")
        return response

    def begin_batch(self, begin_req):           #batch?
#logger.info("BBatch Response")
        raise Exception("not supported")

    def point(self, point):                     #single row
#logger.info("Point Response")
        response = udf_pb2.Response()
        response.point.CopyFrom(point)

        point.fieldsDouble.update(point.fieldsInt)

        response.point.fieldsDouble['formula result'] = eval(self._eval)
#logger.info(response.point.fieldsDouble['formula result'])

        for i in range(len(self._levels)):
            response.point.fieldsDouble['critical_level'] = self._levels[i]
            response.point.fieldsString['message'] = self._messages[i]
            self._agent.write_response(response, True) #response / flush

    def end_batch(self, end_req):               #batch end?
#logger.info("EBatch Response")
        raise Exception("not supported")

class accepter(object):                     #class for server config
    _count = 0
    def accept(self, conn, addr):           #new connection
        self._count += 1                    #count of connection
        a = Agent(conn, conn)               #create agent (communicate with kapacitor) in/out
        h = Handler(a)                      #create handler
        a.handler = h                       #save handler to agent

        logger.info("Starting Agent for connection %d", self._count) #start log
        a.start()                           #start agent
        a.wait()                            #wait request
        logger.info("Agent finished connection %d",self._count)      #end log

if __name__ == '__main__':
    path = "/tmp/alert.sock"           #path to socket
    if len(sys.argv) == 2:              #or we use argv for path
        path = sys.argv[1]
    server = Server(path, accepter())   #create server
    logger.info("Started server")       #log the start
    server.serve()                      #run server


from datetime import date
import datetime

def dia_da_semana(date = date.today()):
    dias = {0:'segunda', 1:'terça', 2:'quarta', 3:'quinta', 4:'sexta', 5:'sábado', 6:'domingo'}
    return (dias[date.weekday()])

def aniverssauro(anos, niver):
    today = datetime.datetime.today()
    diferenca = today - niver
    idade = anos + diferenca.days // 365
    print(idade, end=' Próximo niver daqui a: ')

    niver_atual = niver.replace(today.year)
    if niver_atual > today:
        print((niver_atual - today))
    else:
        print(niver_atual.replace(today.year + 1) - today)

def dia_duplo(idade1, birthday1, idade2, birthday2, n=2):
    today = datetime.datetime.today()
    vida1 = today - birthday1.replace(today.year-idade1)
    vida2 = today - birthday2.replace(today.year - idade2)
    x = abs(vida1 - vida2)
    y = x/(n-1)
    print(y, x + y)

print(dia_da_semana())
niver = datetime.datetime(2017, 6, 27)
niver2 = datetime.datetime(2018, 11, 19)
aniverssauro(15, niver)
print(niver.time())

dia_duplo(18, niver, 19, niver2, 5)


from pyspark.sql import SparkSession
import pandas as pd
from pyspark.ml.feature import VectorAssembler
from pyspark.ml.feature import StringIndexer
from pyspark.ml.classification import RandomForestClassifier
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
import time
start1 = time.process_time()
spark = SparkSession.builder.appName('rf').getOrCreate()
df = spark.read.csv('abalone.csv', header=True, inferSchema=True)
print("Read Time: ",time.process_time() - start1)
pd.DataFrame(df.take(5), columns=df.columns).transpose()
numeric_features = [t[0] for t in df.dtypes if t[1] == 'double']
df.select(numeric_features).describe().toPandas().transpose()

numericCols = ['Length', 'Diameter', 'Height', 'WholeWeight', 'ShuckedWeight', 'VisceraWeight', 'ShellWeight', 'Rings']
assembler = VectorAssembler(inputCols=numericCols, outputCol="features")
df = assembler.transform(df)

label_stringIdx = StringIndexer(inputCol='Sex', outputCol='labelIndex')
df = label_stringIdx.fit(df).transform(df)
pd.DataFrame(df.take(110), columns=df.columns).transpose()
train, test = df.randomSplit([0.7, 0.3], seed=42)

start2 = time.process_time()
rf = RandomForestClassifier(featuresCol='features', labelCol='labelIndex')
rfModel = rf.fit(train)
print("Model Time: ",time.process_time() - start2)

start3 = time.process_time()
predictions = rfModel.transform(test)
predictions.select('Sex', 'Length', 'Diameter', 'Height', 'WholeWeight', 'ShuckedWeight', 'VisceraWeight',
                   'ShellWeight', 'Rings', 'labelIndex', 'rawPrediction', 'prediction', 'probability').show(25)
predictions.select("labelIndex", "prediction").show(10)

evaluator = MulticlassClassificationEvaluator(labelCol="labelIndex", predictionCol="prediction")
accuracy = evaluator.evaluate(predictions)
print("Accuracy = %s" % accuracy)
print("Test Error = %s" % (1.0 - accuracy))
print("Predict Time: ",time.process_time() - start3)


from ursina.prefabs.trail_renderer import TrailRenderer

from .class_.player import *

class ROOM(Entity):
    def __init__(self,ch=None,room=None,server = None):
        super().__init__(
            enabled=False
        )
        self.change = ch
        self.pool_obj = server
        self.room = room
        self.pool = []

    def Start(self) -> None:
        self.enabled = True

        # self.room = load_blender_scene('room1', load=False,reload=True,)
        self.room = Entity(model='cube',scale=(30,.1,30),color=color.gray)
        trail_renderer = TrailRenderer(parent=self.room)
        self.pool.append(self.room)
        # for e in self.room.children:
        #     e.collider = 'mesh'

        self.player = Player(scn=self, name="IAM",)
        self.pool.append(self.player)
        self.am_l = AmbientLight(color=color.rgba(100, 100, 100, 0.2))
        self.pool.append(self.am_l)

    def Stop(self):
        for i in self.pool:
            destroy(i,delay=0)
        self.enabled = False
        self.visible = False
        mouse.locked = False

    def input(self, key):
        if key == 'space':
            self.change.Change('MM')

if __name__ == '__main__':
    app = Room()
    app.run()


# Script to find the next shiny radar patch by reading tinymt from ram
import sys
sys.path.append('../')

from time import sleep
from ntrreader import G6Reader
from rng import RadarTinyMTGenerator
from rng import TinyMT
from ip import IP_ADDR

chain_length = 1
party_count = 1
boost = 0

reader = G6Reader(IP_ADDR)
last_tiny_seeds = []
tiny_seeds = []
initial_seeds = []
ind = 0
for index in range(3,-1,-1):
    initial_seeds.append(reader.readU32(reader.tinyStart+(index*4)))
go = TinyMT(state=initial_seeds)
while True:
    for index in range(3,-1,-1):
        tiny_seeds.append(reader.readU32(reader.tinyStart+(index*4)))
    if tiny_seeds != last_tiny_seeds:
        b = False
        pre = ind
        prestate = go.state.copy()
        rev = go.state.copy()
        rev.reverse()
        add = 0
        while str(rev) != str(tiny_seeds):
            go.next()
            rev = go.state.copy()
            rev.reverse()
            add += 1
            if add > 10000:
                add = 0
                go.state = prestate
                b = True
                break
        ind += add
        if not b:
            print(f"Index: {ind}")
            print("Current Seeds:")
            print(go.display_state())
            gen = RadarTinyMTGenerator(tiny_seeds, party_count, chain_length, boost, True)
            shiny_found = False
            index_advanced = 0
            while not shiny_found:
                index_advanced, _, shiny_found = gen.generate()
            print(f"Shiny Index: {index_advanced+ind}")

        last_tiny_seeds = tiny_seeds
    tiny_seeds = []

    sleep(1/60)


import sys

go = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]]
# 좌표에서 모든방향으로 인접한 좌표 위치

def dfs(x, y):
    global isPeak
    for g in go:  # 모든 방향 탐색
        nx, ny = x + g[0], y + g[1]
        if nx < 0 or nx >= N or ny < 0 or ny >= M:  # 인덱스 범위를 벗어날 경우 pass
            continue
        if mount[x][y] < mount[nx][ny]:
            isPeak = False
        # 이미 방문한거면 탐색을 넘어가고, 방문은 하지 않았지만
        if visited[nx][ny] == True or mount[x][y] != mount[nx][ny]:
            continue

        visited[nx][ny] = True
        dfs(nx, ny)

    return

N, M = map(int, sys.stdin.readline().split())  # 행(x증가)/열(y증가)

mount = []  # 각 좌표의 높이
for _ in range(N):
    mount.append(list(map(int, sys.stdin.readline().rstrip().split())))

isPeak = True  # 해당 좌표가 봉우리일 경우
countPeak = 0  # 총 봉우리 개수
visited = [[False] * M for _ in range(N)]  # DFS 탐색을 위한 방문확인

for i in range(N):
    for j in range(M):
        if visited[i][j] == False:
            isPeak = True
            dfs(i, j)
            if isPeak:
                countPeak += 1

print(countPeak)


nums = [1, -4, 6, 5, 4, -10]
plus = filter(lambda n: n>0, nums) # filterオブジェクトとして格納
print(plus)

plus = list(plus) # リストに変換
print(plus)

nums2 = map(lambda n: n*2, nums)
print(nums2)

nums2 = list(nums2)
print(nums2)

people = ["abe,11", "baba,37", "caty,51", "daigo,23", "eibon,44"]
ages = list(map(lambda p: int(p.split(",")[1]), people))
ages.sort()
print(ages)


import numpy as np
import datetime as dt
class Sjf:
    # initialize some needed variable
    delivered_processes = []
    ended_processes = []
    current_process = []
    processes = []
    finished_processes = 0

# init object, copy the table, estimate needed time to run
    def __init__(self, table_of_processes):
        self.processes = table_of_processes

# check if at the current time any process arrived
    def check_for_processes(self, time):
        for el in range(len(self.processes)):
            if int(self.processes[el][2]) == time:
                self.delivered_processes.append(self.processes[el])

# update waiting time for all processes that has come, and are not currently running
    def update_waiting_time(self):
        for i in range(len(self.delivered_processes)-1):
            if i != 0:
                self.delivered_processes[i][3] = int(self.delivered_processes[i][3]) + 1

# update current process run time, by decreasing it by 1, and check if it has finished
    def current_process_update(self):
        self.delivered_processes.sort(key=lambda x: x[1])
        if len(self.delivered_processes) != 0:
            self.current_process = self.delivered_processes[0]
            x = int(self.current_process[1])
            if x == 0:
                self.ended_processes.append(self.delivered_processes[0])
                del self.delivered_processes[0]
                self.finished_processes += 1
                Sjf.current_process_update(self)
            else:
                self.current_process[1] = str(x - 1)
                Sjf.update_waiting_time(self)

# sum waiting time for all processes at the end
    def count_wait_time(self):
        overall_waiting_time = 0
        for i in range(len(self.ended_processes)):
            overall_waiting_time += int(self.ended_processes[i][3])
        return overall_waiting_time

# using all above functions in correct order to get the finall result
    def main_loop(self):
        czas_s = dt.datetime.now()
        x, overall, avr = 0, 0, 0
        while len(self.processes) != self.finished_processes:
            Sjf.check_for_processes(self, x)
            Sjf.current_process_update(self)
            x += 1
        print(f"SJF\teverything finished\n\toverall time used: {x}")
        print("SJF\t", len(self.ended_processes))
        overall = Sjf.count_wait_time(self)
        avr = round(overall / len(self.ended_processes), 2)
        print(f"SJF\tOverall waiting time: {overall}s")
        print(f"SJF\tAverage waiting time: {avr}s")
        print("\tSFJ:\t",dt.datetime.now() - czas_s, "\n")


from rsf.proj import *

# definitions
a=1.
b=15.
amp=3.5

def DSR(name,zgrid,xgrid,extra=''):
    dz=0.5/(zgrid-1)
    dx=1./(xgrid-1)

    Flow(name,None,
         '''
         math n1=%d n2=%d d1=%g d2=%g o1=0. o2=0. output="%g+%g*x1" |
         math output="input+%g*exp(-((x1-0.2)*(x1-0.2)+(x2-0.5)*(x2-0.5))/(0.1*0.1))" |
         put label1=z unit1=km label2=x unit2=km |
         dsreiko %s | window n3=1 | window n1=1 |
         spline o1=0. d1=0.001 n1=1001
         ''' % (zgrid,xgrid,dz,dx,a,b,amp,extra))

    Flow(name+'_ex',None,
         '''
         math n1=%d n2=%d d1=%g d2=%g o1=0. o2=0. output="%g+%g*x1" |
         math output="input+%g*exp(-((x1-0.2)*(x1-0.2)+(x2-0.5)*(x2-0.5))/(0.1*0.1))" |
         put label1=z unit1=km label2=x unit2=km |
         dsreiko0 %s | window n3=1 | window n1=1 |
         spline o1=0. d1=0.001 n1=1001
         ''' % (zgrid,xgrid,dz,dx,a,b,amp,extra))

def Curve(input,extra=''):
    Plot(input,
         '''
         graph plotfat=8 label1= unit1= label2= unit2= wantaxis=n
         max2=0.42 dash=1 screenratio=0.4 screenht=10 labelsz=10 titlesz=12 labelfat=6.5 titlefat=6.5
         %s
         ''' % extra)

    Plot(input+'_ex',
         '''
         graph plotfat=8 label1= unit1= label2= unit2= wantaxis=n
         max2=0.42 dash=1 screenratio=0.4 screenht=10 labelsz=10 titlesz=12 labelfat=6.5 titlefat=6.5
         %s
         ''' % extra)

Flow('modl',None,
     '''
     math n1=501 n2=1001 d1=0.001 d2=0.001 o1=0. o2=0. output="%g+%g*x1" |
     math output="input+%g*exp(-((x1-0.2)*(x1-0.2)+(x2-0.5)*(x2-0.5))/(0.1*0.1))" |
     put label1=z unit1=km label2=x unit2=km
     ''' % (a,b,amp))
Plot('modl',
     '''
     grey color=j allpos=y scalebar=y barreverse=y barunit=km/s barlabel=Velocity pclip=100
     title="Anomaly Model" screenratio=0.4 screenht=5 labelsz=6 titlesz=8 labelfat=3 titlefat=3
     ''')

Plot('rays','modl',
     '''
     rays2 yshot=0 nr=21 a0=150 amax=172.25 nt=1000 dt=0.001 |
     graph yreverse=y transp=y wantaxis=n wanttitle=n scalebar=y
     min1=0 max1=0.5 min2=0 max2=1 plotcol=7 plotfat=3
     screenratio=0.4 screenht=5
     ''')

Flow('truth','modl','eikonal zshot=0. yshot=0. xshot=0. | window n1=1')

Plot('truth',
     '''
     graph plotfat=8 label1= unit1= label2= unit2= wantaxis=n
     max2=0.42 dash=1 screenratio=0.4 screenht=10 labelsz=10 titlesz=12 labelfat=6.5 titlefat=6.5
     wantaxis=y label1=x unit1=km label2=Traveltime unit2=s dash=0 wanttitle=n
     ''')

Result('modl','modl rays','Overlay')

# zx refine
###########

# scale 0.05 (red)
DSR('zx1',11,21)
Curve('zx1','plotcol=2 wanttitle=n')

# scale 0.01 (green)
DSR('zx2',51,101)
Curve('zx2','plotcol=4 wanttitle=n')

# scale 0.005 (white)
DSR('zx3',101,201)
Curve('zx3','plotcol=7 title="Grid Refinement in z and x"')

# compare
Plot('zx','truth zx1 zx2 zx3','Overlay')
Plot('zx_ex','truth zx1_ex zx2_ex zx3_ex','Overlay')

# z refine
##########

# scale 0.05 (red)
DSR('z1',11,101)
Curve('z1','plotcol=2 wanttitle=n')

# scale 0.01 (green)
DSR('z2',51,101)
Curve('z2','plotcol=4 wanttitle=n')

# scale 0.005 (white)
DSR('z3',101,101)
Curve('z3','plotcol=7 title="Grid Refinement in z"')

# compare
Plot('z','truth z1 z2 z3','Overlay')
Plot('z_ex','truth z1_ex z2_ex z3_ex','Overlay')

# x refine
##########

# scale 0.05 (red)
DSR('x1',51,21)
Curve('x1','plotcol=2 wanttitle=n')

# scale 0.01 (green)
DSR('x2',51,101)
Curve('x2','plotcol=4 wanttitle=n')

# scale 0.005 (white)
DSR('x3',51,201)
Curve('x3','plotcol=7 title="Grid Refinement in x"')

# compare
Plot('x','truth x1 x2 x3','Overlay')
Plot('x_ex','truth x1_ex x2_ex x3_ex','Overlay')

Result('imp','z x','OverUnderIso')
Result('exp','z_ex x_ex','OverUnderIso')

End()


import os
import csv

#Define Path
pybank = os.path.join('..', 'Resources', 'budget_data.csv')
with open('budget_data.csv','r') as csvfile:
    csvreader = csv.reader(csvfile, delimiter = ',')
    header = next(csvreader)

    #Set Empty Lists for Variables
    months_total = []
    profit_total = []
    profit_change = []

    #Loop through Data
    for row in csvreader:
        months_total.append(row[0])
        profit_total.append(int(row[1]))
    for i in range(len(profit_total)-1):
        profit_change.append(profit_total[i+1]-profit_total[i])

#Find Increases and Decreases in Profit
increase = max(profit_change)
decrease = min(profit_change)

month_increase = profit_change.index(max(profit_change))+1
month_decrease = profit_change.index(min(profit_change))+1

#Print Results
print("Financial Analysis")
print("------------------------")
print(f"Total Months: {len(months_total)}")
print(f"Total: ${sum(profit_total)}")
print(f"Average Change: {round(sum(profit_change)/len(profit_change),2)}")
print(f"Greatest Increase in Profits: {months_total[month_increase]} (${(str(increase))})")
print(f"Greatest Decrease in Profits: {months_total[month_decrease]} (${(str(decrease))})")

#Create text File (Financial Analysis)
output = os.path.join('..', 'Analysis', 'Financial_Analysis.txt')
with open(output, 'w') as text_file:
    text_file.write("Financial Analysis")
    text_file.write("\n")
    text_file.write("------------------------")
    text_file.write("\n")
    text_file.write(f"Total Months: {len(months_total)}")
    text_file.write("\n")
    text_file.write(f"Total: ${sum(profit_total)}")
    text_file.write("\n")
    text_file.write(f"Average Change: {round(sum(profit_change)/len(profit_change),2)}")
    text_file.write("\n")
    text_file.write(f"Greatest Increase in Profits: {months_total[month_increase]} (${(str(increase))})")
    text_file.write("\n")
    text_file.write(f"Greatest Decrease in Profits: {months_total[month_decrease]} (${(str(decrease))})")