#  Copyright (c) 2018 R. Tohid
#
#  Distributed under the Boost Software License, Version 1.0. (See accompanying
#  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import re
import ast
import inspect
import numpy as np
from string import Template
from itertools import chain

from .templates import *
from .utils import dump_ast

class OpenSCoP:
    def __init__(self, root, kwargs):
        print(dump_ast(root))

        self.domain_stack = []
        self.params_stack = []
        self.memory_stack = []
        self.scatter_info = {}
        self.domain_set = set()
        self.params_set = set()
        self.memory_set = set()

        self.__src__ = ''
        self.access = ''
        self.statements = []
        self.statement_idx = 0
        self.oscop_global = empty_oscop_global()

        kernel = root.body[0]
        for node in kernel.body:
            self.function[node.__class__.__name__](self, node)

        self.oscop_global['num_statements'] = self.statement_idx
        self.template = Template(oscop_global)
        self.__src__ = self.template.substitute(
            self.oscop_global) + '\n' + self.__src__

    def _Add(self, node, expr={}, coef=1):
        left = node.left
        right = node.right
        self.function[left.__class__.__name__](self, left, expr, coef)
        if isinstance(left, ast.Subscript):
            self.memory_stack.append(expr)
            self.fill_access(self.statements[-1], 'READ', expr)

        if isinstance(right, ast.Subscript):
            expr = {}
        self.function[right.__class__.__name__](self, right, expr, coef)
        if isinstance(right, ast.Subscript):
            self.memory_stack.append(expr)
            self.fill_access(self.statements[-1], 'READ', expr)

        return

    def _Assign(self, node, expr={}, coef=1):
        self.statements.append(empty_oscop_statment())
        statement = self.statements[-1]
        self.statement_idx += 1
        statement['statement_num'] = self.statement_idx
        self.fill_domain(statement)
        expr = {}
        rhs = node.value
        self.function[rhs.__class__.__name__](self, rhs, expr, coef)
        if isinstance(rhs, ast.Subscript):
            self.memory_stack.append(expr)
            self.fill_access(self.statements[-1], 'READ', expr)
        expr = {}
        lhs = node.targets
        if len(lhs) != 1:
            raise Exception("Assignments may only have one target.")
        lhs = lhs[0]
        self.function[lhs.__class__.__name__](self, lhs, expr, coef)
        self.memory_stack.append(expr)
        self.fill_access(self.statements[-1], 'WRITE', expr)
        self.fill_scatter(statement)
        self.template = Template(oscop_statment)
        self.__src__ += self.template.substitute(statement)
        self.access = ''
        self.memory_stack = []

        return

    def _BinOp(self, node, expr={}, coef=1):
        op = node.op.__class__.__name__
        self.function[op](self, node, expr, coef)
        return

    def _Call(self, node, expr={}, coef=1):
        for arg in node.args:
            self.function[arg.__class__.__name__](self, arg, expr, coef)
        return

    def _Compare(self, node, expr={}, coef=1):
        left = node.left
        right = node.comparators[0]
        ineq = node.ops[0].__class__.__name__
        lhs_sign, expr['literals'] = self.equalities[ineq]
        rhs_sign = -lhs_sign
        self.function[left.__class__.__name__](self, left, expr, lhs_sign)
        self.function[right.__class__.__name__](self, right, expr, rhs_sign)
        return

    def _Expr(self, node, expr={}, coef=1):
        self.function[node.value.__class__.__name__](self, node.value, expr,
                                                     coef)
        return

    def _For(self, node, expr={}, coef=1):
        # iteration domain
        iters = []
        iterator = node.target.id
        self.scatter_info[iterator] = 0
        self.domain_set.add(iterator)
        if len(node.iter.args) == 1:
            # lower
            expr = {}
            lower = 0
            expr[iterator] = 1
            expr['literals'] = 0
            iters.append(expr)
            # upper
            expr = {}
            upper = node.iter.args[0]
            expr[iterator] = -1
            expr['literals'] = -1
            self.function[upper.__class__.__name__](self, upper, expr, 1)
            iters.append(expr)
            for key in expr.keys():
                if key not in self.domain_set and key != 'literals':
                    self.params_set.add(key)
        else:
            # lower
            expr = {}
            lower = node.iter.args[0]
            expr[iterator] = 1
            expr['literals'] = 0
            self.function[lower.__class__.__name__](self, lower, expr, 1)
            iters.append(expr)
            # upper
            expr = {}
            upper = node.iter.args[1]
            expr[iterator] = -1
            expr['literals'] = -1
            self.function[upper.__class__.__name__](self, upper, expr, 1)
            iters.append(expr)
            for key in expr.keys():
                if key not in self.domain_set and key != 'literals':
                    self.params_set.add(key)
        # Body
        self.domain_stack.append(iters)
        expr = {}
        for n in node.body:
            if isinstance(n, ast.Pass):
                return
            node_name = n.__class__.__name__
            if node_name in self.function:
                self.function[node_name](self, n, expr, coef)
            else:
                raise NotImplementedError
        self.domain_stack.pop()
        self.scatter_info.pop(iterator, None)
        return

    def _If(self, node, expr={}, coef=1):
        condition = []
        # If the `if` statement includes more than one comparison.
        if isinstance(node.test, ast.BoolOp):
            raise NotImplementedError(
                "`if` statements may only include one "
                "`ast.Compare` expression. You may want to break down this "
                "statement into multiple `if` statements.")
        elif isinstance(node.test, ast.Num):
            if node.test.n:
                self.function[node.body.__class__.__name__](self, node.body)
            else:
                return
        # If the condition is just a variable.
        elif isinstance(node.test, ast.Name):
            _id = node.test.id
            if _id not in self.iters:
                self.params_set.add(_id)
            subexpr = {}
            subexpr[_id] = 1
            subexpr['literals'] = -1
            condition.append(subexpr)
            subexpr = {}
            subexpr[_id] = -1
            subexpr['literals'] = 1
            condition.append(subexpr)
        elif isinstance(node.test, ast.Compare):
            self._Compare(node.test, expr, coef)
            condition.append(expr)
        else:
            raise NotImplementedError

        self.fill_global(expr)

        for n in node.body:
            expr = {}
            if isinstance(n, ast.Pass):
                return
            node_name = n.__class__.__name__
            if node_name in self.function:
                self.function[node_name](self, n, expr, coef)
            else:
                raise NotImplementedError
        self.params_stack.pop()
        return

    def _Index(self, node, expr={}, coef=1):
        self.function[node.value.__class__.__name__](self, node.value, expr,
                                                     coef)
        return

    def _Mult(self, node, expr={}, coef=1):
        left_operand = node.left
        right_operand = node.right
        if isinstance(left_operand, ast.Num):
            coef = coef * left_operand.n
            operand = right_operand
            self.function[operand.__class__.__name__](self, operand, expr,
                                                      coef)
            return
        elif isinstance(right_operand, ast.Num):
            coef = coef * right_operand.n
            operand = left_operand
            self.function[operand.__class__.__name__](self, operand, expr,
                                                      coef)
            return
        else:
            self.function[left_operand.__class__.__name__](self, left_operand,
                                                           expr, coef)
            self.function[right_operand.__class__.__name__](
                self, right_operand, expr, coef)

        return

    def _Name(self, node, expr={}, coef=1):
        if node.id in expr:
            expr[node.id] += coef
        else:
            expr[node.id] = coef
        return

    def _Num(self, node, expr={}, coef=1):
        if 'literals' in expr:
            expr['literals'] += coef * node.n
        else:
            expr['literals'] = coef * node.n
        return

    def _Sub(self, node, expr={}, coef=1):
        left = node.left
        right = node.right
        self.function[left.__class__.__name__](self, left, expr, coef)
        if isinstance(left, ast.Subscript):
            self.memory_stack.append(expr)
            self.fill_access(self.statements[-1], 'READ', expr)

        if isinstance(right, ast.Subscript):
            expr = {}
        self.function[right.__class__.__name__](self, right, expr, -coef)
        if isinstance(right, ast.Subscript):
            self.memory_stack.append(expr)
            self.fill_access(self.statements[-1], 'READ', expr)
        return

    def _Subscript(self, node, expr={}, coef=1):
        if isinstance(node.value, ast.Name):
            self.memory_set.add(node.value.id)
        self.function[node.value.__class__.__name__](self, node.value, expr,
                                                     coef)
        self.function[node.slice.__class__.__name__](self, node.slice, expr,
                                                     coef)
        if isinstance(node.slice.value, ast.Name):
            _idx = node.slice.value.id
            if _idx not in self.scatter_info.keys():
                raise Exception(
                    "Index %s is not define in this scope.'" % _idx)
            self.scatter_info[_idx] += 1

        return

    def _UnaryOp(self, node, expr={}, coef=1):
        if isinstance(node.op, ast.USub):
            coef = -coef
            operand = node.operand
            self.function[operand.__class__.__name__](self, operand, expr,
                                                      coef)
        else:
            raise NotImplementedError
        return

    # source: http://bit.ly/2FFcHxj
    def list_len(self, nested_list):
        if type(nested_list) == list:
            return sum(self.list_len(sub_list) for sub_list in nested_list)
        else:
            return 1

    def fill_global(self, expr):
        self.params_stack.append([expr])
        self.oscop_global['domain_t'] = 'CONTEXT'
        self.oscop_global['params_exist'] = 1
        self.oscop_global['context'] += '## ' + str(expr) + '\n'
        for param in expr.keys():
            if param != 'literals':
                if param not in self.oscop_global['params_names']:
                    self.oscop_global['params_names'] += param + ' '
                    self.oscop_global['nrows'] += 1
                self.params_set.add(param)
        self.oscop_global['ncols'] = len(self.params_set) + 2

    def fill_domain(self, statement):
        offset = 1
        domain = list(self.domain_set)
        params = list(self.params_set)
        keys = domain + params
        idx_table = {'e/i': 0}
        for k in keys:
            idx_table[k] = offset
            offset += 1
        idx_table['literals'] = offset
        statement['domain_t'] = "DOMAIN"
        nrows = self.list_len(self.domain_stack)
        statement['num_relations'] = nrows
        ncols = len(self.domain_set) + len(self.params_set) + 2
        domain = np.zeros((nrows, ncols))
        domain[:, 0] = 1
        row = 0
        for d in self.domain_stack:
            for entry in d:
                for k in entry.keys():
                    domain[row][idx_table[k]] = entry[k]
                row += 1
        domain_string = ''
        flatten_domain = list(chain.from_iterable(self.domain_stack))
        for i, r in enumerate(domain):
            domain_string += ' '.join(str(int(e))
                                      for e in r) + "    ## " + str(
                                          flatten_domain[i]) + '\n'
        statement['domain'] = domain_string

    def fill_scatter(self, statement):
        statement['scattering'] = "SCATTERING\n"
        nscatterings = len(self.memory_stack)
        offset = 1 + nscatterings
        domain = list(self.domain_set)
        params = list(self.params_set)
        keys = domain + params
        idx_table = {'e/i': 0}
        for k in keys:
            idx_table[k] = offset
            offset += 1
        idx_table['literals'] = offset
        nrows = nscatterings
        ncols = len(keys) + nscatterings + 2
        domain = np.zeros((nrows, ncols))
        for i in range(nrows):
            domain[i][i + 1] = -1
        row = 0
        for m in self.memory_stack:
            for k in m.keys():
                if k in idx_table:
                    domain[row][idx_table[k]] = m[k]
            row += 1

        mem_string = ''
        for i, r in enumerate(domain):
            mem_string += ' '.join(str(int(e)) for e in r) + '\n'
        statement['scattering'] += mem_string

    def fill_access(self, statement, r_w, expr):
        self.access += '\n' + r_w + '\n'
        nrows = len(expr)
        offset = 1 + nrows
        domain = list(self.domain_set)
        params = list(self.params_set)
        keys = domain + params
        idx_table = {'e/i': 0}
        for k in keys:
            idx_table[k] = offset
            offset += 1
        idx_table['literals'] = offset
        ncols = len(keys) + nrows + 2
        domain = np.zeros((nrows, ncols))
        for i in range(nrows):
            domain[i][i + 1] = -1
        mems = list(self.memory_set)
        for k in expr.keys():
            if k in mems:
                domain[0][-1] = mems.index(k) + 1

        row = 1
        for k in expr.keys():
            if k not in mems:
                domain[row][idx_table[k]] = expr[k]
                row += 1

        mem_string = ''
        for i, r in enumerate(domain):
            mem_string += ' '.join(str(int(e)) for e in r) + '\n'
        self.access += mem_string
        statement['access'] = self.access

    # (sign, adjustment)
    equalities = {'Gt': (1, -1), 'GtE': (1, 0), 'Lt': (-1, 1), 'LtE': (-1, 0)}
    operators = {'USub': -1, 'Add': 1, 'Mult': 1, 'Sub': -1}
    function = {
        "Num": _Num,
        "Name": _Name,
        "Expr": _Expr,
        "Subscript": _Subscript,
        "BinOp": _BinOp,
        "Call": _Call,
        "Assign": _Assign,
        "Add": _Add,
        "Sub": _Sub,
        "Mult": _Mult,
        "If": _If,
        "Index": _Index,
        "Compare": _Compare,
        "UnaryOp": _UnaryOp,
        "For": _For
    }


import requests

class RandomUserAPI ():
    def __init__ (self):
        self.base_url = "https://randomuser.me/api/?results=10"
        self.base_payload = {

        }

    def get_payload(self, **kwargs):
        payload = {}

        for key, value in self.base_payload.items():
            payload[key] = value

        for key, value in kwargs.items():
            payload[key] = value

        return payload

    def get_user_info(self):
        q = ""

        payload = self.get_payload(q=q)
        url = "{}{}".format(self.base_url, "")
        r = requests.get(url, params = payload)
        result = r.json()

        user_list = []

        for item in result["results"]:

            user_list.append( UserInfo(
                    gender = item["gender"],
                    first_name = item["name"]["first"],
                    last_name = item["name"]["last"],
                    ))

        return user_list

class UserInfo():

    def __init__ (self,
        gender = None,
        first_name = None,
        last_name= None
        ):

        self.gender = gender
        self.first_name = first_name
        self.last_name = last_name

    # def __str__(self):
    #     return "Blah"


"""
DPO Deskew
Uses a single 0V-1V rising edge source split into
two scope channels to deskew those channels
Edited: 9/17
Windows 7 64-bit
Python 3.6.1 64-bit (Anaconda 4.4.0)
PyVISA 1.8
Get Anaconda: http://continuum.io/downloads
Anaconda includes NumPy
Get PyVISA: pip install pyvisa
"""

import visa

print('PyVISA Version:', visa.__version__)

# Set up VISA instrument object
rm = visa.ResourceManager()
dpo = rm.open_resource('TCPIP::192.168.1.12::INSTR')
dpo.timeout = 5000
dpo.encoding = 'latin_1'
dpo.write_termination = None
dpo.read_termination = '\n'
print('Connected to ', dpo.query('*idn?'))
dpo.write('header off')
dpo.write('*rst')
dpo.write('*cls')

channels = [1, 3]
vertScale = 250e-3
horizScale = 1e-9

for c in channels:
    dpo.write('select:ch{} on'.format(c))
    dpo.write('ch{}:scale {}'.format(c, vertScale))

dpo.write('horiz:mode:scale {}'.format(horizScale))
dpo.write('trigger:a setlevel')
dpo.write('acquire:mode average')

dpo.write('acquire:stopafter sequence')
dpo.query('*opc?')

dpo.write('measurement:immed:type delay')
dpo.write('measurement:immed:source1 ch1')
dpo.write('measurement:immed:source2 ch3')
dpo.write('measurement:immed:delay:edge1 rise')
dpo.write('measurement:immed:delay:edge2 rise')
dpo.write('measurement:immed:delay:direction forwards')

print(dpo.query('measurement:immed?'))
deskew = dpo.query('measurement:immed:value?')
print(deskew)

# dpo.write('acquire:stopafter runstop')
dpo.write('acquire:state on')

dpo.write('ch3:deskew ', deskew)

# Check for errors
dpo.query('*esr?')
error = dpo.query('system:error:all?')
print('Status: {}'.format(error))

dpo.close()


# Code to format our imput data, outputting a clean restaurant list, dictionary and corpus with foodwords also removed.
# Authors Robert Walport and Rashmi Raman

import csv, sys, re
from gensim import corpora, models, similarities

with open(sys.argv[1], "rb") as csvFile:
    rawlist = []
    cleanlist = []
    finallist = []
    reader = csv.reader(csvFile, delimiter=',')
    for row in reader:
        rawlist.append(row)
    rawlist.pop(0)
    for entry in rawlist:
        cleanlist.append([entry[0], ''])
    for entry in cleanlist:
        if entry not in finallist:
            finallist.append(entry)
    for entry in finallist:
        for rest in rawlist:
            if entry[0] == rest[0]:
                try:
                    entry[1] = entry[1] + " " + rest[3]
                except IndexError:
                    entry[1] = entry[1]
    restaurants = open('restaurants.txt', 'w+')
    ratings = open('reviews.txt', 'w+')
    for entry in finallist:
        restaurants.write(entry[0].lower() + "\n")
        ratings.write(entry[1].lower() + '\n')
    restaurants.close()
    ratings.close()

stopwords = open('stopwords.txt', 'r').read().split()
foodwords = open('foodwords.txt', 'r').read().split()

class MyCorpus(object):
    def __iter__(self):
        for line in open('reviews.txt'):
            line = line.lower()
            scrubwords = re.findall(r'\w+', line)
            yield dictionary.doc2bow(scrubwords)

# collect statistics about all tokens
dictionary = corpora.Dictionary(line.lower().split() for line in open('reviews.txt'))
# remove stop words and words that appear only once
stop_ids = [dictionary.token2id[stopword] for stopword in stopwords if stopword in dictionary.token2id]
food_ids = [dictionary.token2id[foodword] for foodword in foodwords if foodword in dictionary.token2id]
once_ids = [tokenid for tokenid, docfreq in dictionary.dfs.iteritems() if docfreq == 1]
dictionary.filter_tokens(stop_ids + food_ids + once_ids) # remove stop words and words that appear only once
dictionary.compactify() # remove gaps in id sequence after words that were removed
dictionary.save('restaurantreviews.dict')

corpus_memory_friendly = MyCorpus() # doesn't load the corpus into memory!

corpora.MmCorpus.serialize('reviewscorpus.mm', corpus_memory_friendly)


from django.conf import settings
from django.contrib import admin
from django.contrib.admin.util import unquote
from django.contrib.admin.views.main import ChangeList
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from functools import update_wrapper
from django.utils.html import strip_spaces_between_tags as short
from django.utils.translation import ugettext_lazy as _

class OrderedModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        from django.conf.urls import patterns, url

        def wrap(view):
            def wrapper(*args, **kwargs):
                return self.admin_site.admin_view(view)(*args, **kwargs)
            return update_wrapper(wrapper, view)
        info = self.model._meta.app_label, self.model._meta.module_name
        return patterns('',
            url(r'^(.+)/move-(up)/$',
                wrap(self.move_view),
                name='%s_%s_move_up' % info),
            url(r'^(.+)/move-(down)/$',
                wrap(self.move_view),
                name='%s_%s_move_down' % info),
        ) + super(OrderedModelAdmin, self).get_urls()

    def _get_changelist(self, request):
        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)

        cl = ChangeList(request, self.model, list_display,
            list_display_links, self.list_filter, self.date_hierarchy,
            self.search_fields, self.list_select_related,
            self.list_per_page, self.list_max_show_all, self.list_editable,
            self)

        return cl

    request_query_string = ''

    def changelist_view(self, request, extra_context=None):
        cl = self._get_changelist(request)
        self.request_query_string = cl.get_query_string()
        return super(OrderedModelAdmin, self).changelist_view(request, extra_context)

    def move_view(self, request, object_id, direction):
        cl = self._get_changelist(request)
        qs = cl.get_query_set(request)

        obj = get_object_or_404(self.model, pk=unquote(object_id))
        obj.move(direction, qs)

        return HttpResponseRedirect('../../%s' % self.request_query_string)

    def move_up_down_links(self, obj):
        link_html = short("""

            """)

        return link_html % {
            'app_label': self.model._meta.app_label,
            'module_name': self.model._meta.module_name,
            'object_id': obj.id,
            'STATIC_URL': settings.STATIC_URL,
            'query_string': self.request_query_string
        }
    move_up_down_links.allow_tags = True
    move_up_down_links.short_description = _(u'Move')


from fairseq.models.roberta import RobertaModel

roberta = RobertaModel.from_pretrained(
    'checkpoints_QQP/',
    checkpoint_file='checkpoint_best.pt',
    data_name_or_path='QQP-bin'
)

import torch
label_fn = lambda label: roberta.task.label_dictionary.string(
    torch.LongTensor([label + roberta.task.label_dictionary.nspecial])
)
ncorrect, nsamples = 0, 0
roberta.cuda()
roberta.eval()
evaluatedSoFar = set()
lineNumbers = 0
with open('/u/scr/mhahn/PRETRAINED/GLUE/glue_data/QQP/dev_alternatives_c.tsv') as fin:
  with open('/u/scr/mhahn/PRETRAINED/GLUE/glue_data/QQP/dev_datapoints_predictions_fairseq.tsv', "w") as outFile:
    while True:
        lineNumbers += 1
        try:
           line = next(fin).strip()
        except UnicodeDecodeError:
           print("UnicodeDecodeError", lineNumbers)
           continue
        except StopIteration:
           break
        if line == "#####":
           originalSentences = next(fin).strip() # the original
           separation = [int(x) for x in next(fin).strip().split(" ")][0]+1 # position of separation
           sentences = next(fin).strip().split(" ")
        else:
            continue
        print(sentences, separation)
        sentences = [sentences[:separation], sentences[separation:]]
        assert len(sentences[1]) > 3, (line, separation, sentences)
        for i in range(2):
          sentences[i] = ("".join(sentences[i])).replace("▁", " ").replace("</s>", "").strip()
        assert len(sentences[1]) > 0, (line, separation, sentences)
#        print(sentences)
        if tuple(sentences) in evaluatedSoFar:
           continue
        evaluatedSoFar.add(tuple(sentences))
        if len(evaluatedSoFar) % 100 == 0:
           print(len(evaluatedSoFar), sentences)
        tokens = roberta.encode(sentences[0], sentences[1])
        prediction = roberta.predict('sentence_classification_head', tokens)
        prediction_label = label_fn(prediction.argmax().item())
        prediction = [float(x) for x in prediction.view(-1)]
        print("\t".join([sentences[0], sentences[1], str(prediction[1]), prediction_label]), file=outFile)


from django.conf.urls import url

from apps.hygiene import views

app_name = 'hygiene'

urlpatterns = [
    url('^check/$', views.check, name='check'),
    url('^check/(?P<pk>[0-9]+)/$', views.check, name='check_day'),

    url('^plan/$', views.plan, name='plan'),
    url('^plan/(?P<year>[0-9]+)/(?P<month>[0-9]+)/$', views.plan, name='plan_month'),

    url('^calendar/(?P<pk>[0-9]+).ics', views.ical, name='ical'),
]


"""Unit tests for tech_support_show.py."""

import pytest

from photon.backend.cisco import tech_support_show
from photon.lib import cisco_utils
from photon.lib import test_utils

#pylint: disable=redefined-outer-name,protected-access

@pytest.fixture(scope='module')
def support_show_parser():
    """Return a switch object fixture."""
    logfile = test_utils.get_files_of_type('cisco_test_log')[0]
    return tech_support_show.SupportShowParser(logfile)

def test_all_parsers(support_show_parser):
    """Test that every getter has a test."""
    test_utils.all_parsers_have_test(support_show_parser, __file__)

def test__get_first_field_val(support_show_parser):
    """Test that we get the first field successfully from show_switchname."""
    result = support_show_parser._get_first_field_val('show_switchname')
    expected = 'MFXRFPEMC9513-A'
    assert result == expected

def test__get_regex_from_output(support_show_parser):
    """Test that we get a regex dict from an output."""
    result = support_show_parser._get_regex_from_output('show_version', 'BIOS:\s+version\s+(?P<bios>.*)')
    assert result == [{'bios': '1.0.10'}]

def test_get_all_fields(support_show_parser):
    """Test that we get all fields successfully."""
    result = set(support_show_parser.get_all_fields().keys())
    assert result == set(list(support_show_parser.fields) + ['Timestamp'])

def test_get_bios(support_show_parser):
    """Test that we get a bios version from a log."""
    result = support_show_parser.get_bios()
    assert result == '1.0.10'

def test_get_fields(support_show_parser):
    """Test that we get some fields properly."""
    result = support_show_parser.get_fields(['show_clock', 'show_switchname'])
    expected = {
        'show_clock': ['16:04:11.752 UTC Thu Jun 14 2018\n', 'Time source is NTP\n'],
        'show_switchname': ['MFXRFPEMC9513-A\n'],
        'Timestamp': '16:04:11.752 UTC Thu Jun 14 2018'
    }
    assert result == expected

def test_get_alias_dict(support_show_parser):
    """Test that we get an alias dict from a log."""
    result = support_show_parser.get_alias_dict()
    assert len(result.keys()) == 136
    assert result['cvrpuxsqp01a_ql'] == '21:01:00:1b:32:3a:f0:a2'
    assert result['21:01:00:1b:32:3a:f0:a2'] == 'cvrpuxsqp01a_ql'

def test_get_flogi_dict(support_show_parser):
    """Test that we get a flogi dict from a log."""
    result = support_show_parser.get_flogi_dict()
    assert result['fc1/18'] == [
        cisco_utils.FlogiEntry(interface='fc1/18', vsan='50', fcid='0x3202a0', port_name='10:00:00:90:fa:1b:32:38', node_name='20:00:00:90:fa:1b:32:38', alias=None)
    ]
    assert result['port-channel1'][0:2] == [
        cisco_utils.FlogiEntry(interface='port-channel1', vsan='50', fcid='0x3200a1', port_name='20:01:00:25:b5:a0:a1:2f', node_name='20:00:00:25:b5:a0:01:2f', alias=None),
        cisco_utils.FlogiEntry(interface='port-channel1', vsan='50', fcid='0x3200a2', port_name='20:01:00:25:b5:a0:a1:3f', node_name='20:00:00:25:b5:a0:01:3f', alias=None)
    ]

def test_get_hardware(support_show_parser):
    """Test that we get hardware model from a log."""
    result = support_show_parser.get_hardware()
    assert result == 'cisco MDS 9513 (13 Slot) Chassis ("Supervisor/Fabric-2a")'

def test_get_interface_dict(support_show_parser):
    """Test that we get interface dicts from the log."""
    result = support_show_parser.get_interface_dict()
    expected = {
        '5_minutes_input_bits_sec': '115810464',
        '5_minutes_output_bits_sec': '195751936',
        'admin_fec_state': 'down',
        'admin_port_mode': 'auto',
        'connected_wwpns': ['20:01:00:25:b5:a0:a1:2f',
        '20:01:00:25:b5:a0:a1:3f',
        '20:01:00:25:b5:a0:a1:0f',
        '20:01:00:25:b5:a0:a1:1f',
        '20:01:00:25:b5:a0:a1:2e',
        '20:01:00:25:b5:a0:a1:3e',
        '20:01:00:25:b5:a0:a1:1e',
        '20:01:00:25:b5:a0:a1:0e',
        '24:01:00:05:73:d2:59:c0'],
        'error': 'port not present',
        'hardware': 'Fibre Channel',
        'input_bytes': '293149753678128',
        'input_discards': '0',
        'input_errors': '0',
        'input_frames_input': '181200169488',
        'input_input_ols': '0',
        'input_invalid_crc/fcs': '0',
        'input_loop_inits': '0',
        'input_lrr': '0',
        'input_nos': '0',
        'input_too_long': '0',
        'input_too_short': '0',
        'input_unknown_class': '0',
        'interface_last_changed': 'Sun Jan 26 18:23:15 2014',
        'interface_name': 'port-channel1',
        'member_1': 'fc1/14',
        'member_2': 'fc1/15',
        'member_3': 'fc1/32',
        'member_4': 'fc1/33',
        'oper_fec_state': 'down',
        'output_bytes': '501873283644288',
        'output_discards': '28755',
        'output_errors': '0',
        'output_frames_output': '302772057121',
        'output_loop_inits': '0',
        'output_lrr': '0',
        'output_nos': '0',
        'output_output_ols': '0',
        'port_mode': 'F',
        'port_vsan': '50',
        'port_wwn': '24:01:00:0d:ec:3c:06:00',
        'snmp_link_state_traps': 'enabled',
        'speed': '32 Gbps',
        'state': 'up',
        'trunk_mode': 'off'
    }
    assert result['port-channel1'] == expected

def test_get_show_clock(support_show_parser):
    """Test that we get show clock output from a log."""
    support_show_parser.get_fields(['show_clock'])
    result = support_show_parser.get_fields(['show_clock'])
    expected = ['16:04:11.752 UTC Thu Jun 14 2018\n', 'Time source is NTP\n']
    assert expected == result['show_clock']
    assert len(result['show_clock']) == 2

def test_get_show_device_alias_database(support_show_parser):
    """Test that we get show device alias database output from a log."""
    result = support_show_parser.get_fields(['show_device_alias_database'])
    expected_start = [
        'device-alias name PURE_CT0_FC0 pwwn 52:4a:93:77:59:62:b2:00\n',
        'device-alias name PURE_CT0_FC2 pwwn 52:4a:93:77:59:62:b2:02\n',
        'device-alias name PURE_CT1_FC2 pwwn 52:4a:93:77:59:62:b2:12\n',
        'device-alias name Pure_CT1_FC0 pwwn 52:4a:93:77:59:62:b2:10\n',
        'device-alias name CVRPUXSQP01a_QL pwwn 21:01:00:1b:32:3a:f0:a2\n',
        'device-alias name CX480_0303_SPA2 pwwn 50:06:01:62:44:60:27:6f\n',
        'device-alias name CX480_0303_SPA4 pwwn 50:06:01:64:44:60:27:6f\n',
        'device-alias name CX480_0303_SPA6 pwwn 50:06:01:66:44:60:27:6f\n',
        'device-alias name CX480_0303_SPB2 pwwn 50:06:01:6a:44:60:27:6f\n',
        'device-alias name CX480_0303_SPB4 pwwn 50:06:01:6c:44:60:27:6f\n'
    ]
    expected_end = [
        'device-alias name MFXRFPVDIESX01_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:1f\n',
        'device-alias name MFXRFPVDIESX02_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:0f\n',
        'device-alias name MFXRFPVDIESX03_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:3f\n',
        'device-alias name MFXRFPVDIESX04_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:2f\n',
        'device-alias name MFXRFPVDIESX05_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:5f\n',
        'device-alias name MFXRFPVDIESX06_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:4f\n',
        'device-alias name MFXRFPVDIESX07_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:7f\n',
        'device-alias name MFXRFPVDIESX08_Virtual_HBA0 pwwn 20:00:00:25:b5:01:a0:6f\n',
        '\n',
        'Total number of entries = 68\n'
    ]
    assert expected_start == result['show_device_alias_database'][:10]
    assert expected_end == result['show_device_alias_database'][-10:]
    assert len(result['show_device_alias_database']) == 70

def test_get_show_flogi_database(support_show_parser):
    """Test that we get show flogi database output from a log."""
    result = support_show_parser.get_fields(['show_flogi_database'])
    expected_start = [
        '--------------------------------------------------------------------------------\n',
        'INTERFACE        VSAN    FCID           PORT NAME               NODE NAME       \n',
        '--------------------------------------------------------------------------------\n',
        'fc1/2            50    0x320300  10:00:00:00:c9:fc:15:c6 20:00:00:00:c9:fc:15:c6\n',
        '                           [MFRPNTPSSSPAPP1_ELX_HBA1]\n',
        'fc1/3            50    0x3202c0  21:00:00:24:ff:53:02:51 20:00:00:24:ff:53:02:51\n',
        '                           [MFRPESXPSS07_QL_HBA0]\n',
        'fc1/4            50    0x320280  21:00:00:24:ff:53:02:05 20:00:00:24:ff:53:02:05\n',
        '                           [MFRPESXPSS06_QL_HBA0]\n',
        'fc1/5            50    0x320220  21:00:00:24:ff:53:01:dd 20:00:00:24:ff:53:01:dd\n'
    ]
    expected_end = [
        'port-channel1    50    0x3200a6  20:01:00:25:b5:a0:a1:3e 20:00:00:25:b5:a0:01:3e\n',
        '                           [MFXRFUCSESX06_Virtual_HBA1]\n',
        'port-channel1    50    0x3200a7  20:01:00:25:b5:a0:a1:1e 20:00:00:25:b5:a0:01:1e\n',
        '                           [MFXRFUCSESX08_Virtual_HBA1]\n',
        'port-channel1    50    0x3200a8  20:01:00:25:b5:a0:a1:0e 20:00:00:25:b5:a0:01:0e\n',
        '                           [MFXRFUCSESX07_Virtual_HBA1]\n',
        'port-channel1    50    0x3200c0  24:01:00:05:73:d2:59:c0 20:32:00:05:73:d2:59:c1\n',
        '\n',
        'Total number of flogi = 38.\n',
        '\n'
    ]
    assert expected_start == result['show_flogi_database'][:10]
    assert expected_end == result['show_flogi_database'][-10:]
    assert len(result['show_flogi_database']) == 80

def test_get_show_interface(support_show_parser):
    """Test that we get show interface information from a log."""
    result = support_show_parser.get_fields(['show_interface'])
    expected_start = [
        'fc1/1 is down (Link failure or not-connected)\n',
        '    Hardware is Fibre Channel, SFP is short wave laser w/o OFC (SN)\n',
        '    Port WWN is 20:01:00:0d:ec:3c:06:00\n',
        '    Admin port mode is F, trunk mode is off\n',
        '    snmp link state traps are enabled\n',
        '    Port vsan is 50\n',
        '    Receive data field Size is 2112\n',
        '    Beacon is turned off\n',
        '    5 minutes input rate 0 bits/sec,0 bytes/sec, 0 frames/sec\n',
        '    5 minutes output rate 0 bits/sec,0 bytes/sec, 0 frames/sec\n'
    ]
    expected_end = [
        '    0 Rx pause\n',
        '  TX\n',
        '    0 unicast packets  0 multicast packets  0 broadcast packets\n',
        '    0 output packets  0 bytes\n',
        '    0 jumbo packets\n',
        '    0 output error  0 collision  0 deferred  0 late collision\n',
        '    0 lost carrier  0 no carrier  0 babble  0 output discard\n',
        '    0 Tx pause\n',
        '\n',
        '\n'
    ]
    assert expected_start == result['show_interface'][:10]
    assert expected_end == result['show_interface'][-10:]
    assert len(result['show_interface']) == 2524

def test_get_show_switchname(support_show_parser):
    """Test that we get show switchname command output from a log."""
    result = support_show_parser.get_fields(['show_switchname'])
    expected = ['MFXRFPEMC9513-A\n']
    assert expected == result['show_switchname']
    assert len(result['show_switchname']) == 1

def test_get_show_zoneset_active(support_show_parser):
    """Test that we get show zoneset active output from a log."""
    result = support_show_parser.get_fields(['show_zoneset_active'])
    expected_start = [
        'zoneset name EVEN_RFP vsan 50\n',
        '  zone name CVRPUXSQQ01a_CT0_FC0 vsan 50\n',
        '  * fcid 0x321800 [pwwn 21:00:00:e0:8b:92:ce:84] [CRPUXSQQ01a_Qlogic_HBA2]\n',
        '  * fcid 0x3201a2 [pwwn 52:4a:93:77:59:62:b2:00] [PURE_CT0_FC0]\n',
        '  \n',
        '  zone name CVRPUXSQQ01a_CT0_FC2 vsan 50\n',
        '  * fcid 0x321800 [pwwn 21:00:00:e0:8b:92:ce:84] [CRPUXSQQ01a_Qlogic_HBA2]\n',
        '  * fcid 0x320202 [pwwn 52:4a:93:77:59:62:b2:02] [PURE_CT0_FC2]\n',
        '  \n',
        '  zone name CVRPUXSQQ01a_CT1_FC0 vsan 50\n'
    ]
    expected_end = [
        '  zone name MFRPNTPSSSPSQP1_CT1_FC0 vsan 50\n',
        '  * fcid 0x320320 [pwwn 10:00:00:00:c9:fc:13:3a] [MFRPNTPSSSPSQP1_ELX_HBA1]\n',
        '  * fcid 0x320701 [pwwn 52:4a:93:77:59:62:b2:10] [Pure_CT1_FC0]\n',
        '  \n',
        '  zone name MFRPNTPSSSPSQP1_CT1_FC2 vsan 50\n',
        '  * fcid 0x320320 [pwwn 10:00:00:00:c9:fc:13:3a] [MFRPNTPSSSPSQP1_ELX_HBA1]\n',
        '  * fcid 0x320721 [pwwn 52:4a:93:77:59:62:b2:12] [PURE_CT1_FC2]\n',
        '  \n',
        '  zone name $default_zone$ vsan 50\n',
        '  * fcid 0x3200c0\n'
    ]
    assert expected_start == result['show_zoneset_active'][:10]
    assert expected_end == result['show_zoneset_active'][-10:]
    assert len(result['show_zoneset_active']) == 563

def test_get_show_version(support_show_parser):
    """Test that we get show version output from a log."""
    result = support_show_parser.get_show_version()
    expected = [
        'Cisco Nexus Operating System (NX-OS) Software\n',
        'TAC support: http://www.cisco.com/tac\n',
        'Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html\n',
        'Copyright (c) 2002-2014, Cisco Systems, Inc. All rights reserved.\n',
        'The copyrights to certain works contained herein are owned by\n',
        'other third parties and are used and distributed under license.\n',
        'Some parts of this software are covered under the GNU Public\n',
        'License. A copy of the license is available at\n',
        'http://www.gnu.org/licenses/gpl.html.\n',
        '\n',
        'Software\n',
        '  BIOS:      version 1.0.10\n',
        '  loader:    version N/A\n',
        '  kickstart: version 6.2(9a)\n',
        '  system:    version 6.2(9a)\n',
        '  BIOS compile time:       01/08/09\n',
        '  kickstart image file is: bootflash:///m9500-sf2ek9-kickstart-mz.6.2.9a.bin\n',
        '  kickstart compile time:  8/20/2014 11:00:00 [10/14/2014 06:54:36]\n',
        '  system image file is:    bootflash:///m9500-sf2ek9-mz.6.2.9a.bin\n',
        '  system compile time:     8/20/2014 11:00:00 [10/14/2014 08:24:00]\n',
        '\n',
        '\n',
        'Hardware\n',
        '  cisco MDS 9513 (13 Slot) Chassis ("Supervisor/Fabric-2a")\n',
        '  Motorola, 7447A, altivec  with 2071288 kB of memory.\n',
        '  Processor Board ID JAF1647ATGK\n',
        '\n',
        '  Device name: MFXRFPEMC9513-A\n',
        '  bootflash:    1000944 kB\n',
        '  slot0:              0 kB (expansion flash)\n',
        '\n',
        'Kernel uptime is 688 day(s), 15 hour(s), 15 minute(s), 1 second(s)\n',
        '\n',
        'Last reset \n',
        '  Reason: Unknown\n',
        '  System version: 6.2(3)\n',
        '  Service: \n',
        '\n',
        'plugin\n',
        '  Core Plugin\n'
    ]
    assert result == expected

def test_get_switchname(support_show_parser):
    """Test that we get the switchname properly."""
    expected = 'MFXRFPEMC9513-A'
    assert expected == support_show_parser.get_switchname()

def test_get_uptime(support_show_parser):
    """Test that we get uptime from a log."""
    result = support_show_parser.get_uptime()
    assert result == '688 day(s), 15 hour(s), 15 minute(s), 1 second(s)'

def test_get_version(support_show_parser):
    """Test that we get version from a log."""
    result = support_show_parser.get_version()
    assert result == '6.2(3)'

def test_get_zonesets(support_show_parser):
    """Test that we get zonesets from a log."""
    result = support_show_parser.get_zonesets()
    assert result['EVEN_RFP'].name == 'EVEN_RFP'
    assert len(result['EVEN_RFP'].zones['CVRPUXSQP01a_CT1_FC2'].members) == 2


from nanpy import (ArduinoApi, SerialManager)
from nanpy import DHT

connection = SerialManager(device='/dev/ttyACM0')
a = ArduinoApi(connection=connection)

dhts = [
    DHT(10, DHT.DHT11)
]

for i, dht in enumerate(dhts):
    print("DHT %d" % i)
    print("Temperature is %.2f degrees Celcius" % dht.readTemperature(False))
    print("Temperature is %.2f degrees Fahrenheit" % dht.readTemperature(True))
    print("Humidity is %.2f %%" % dht.readHumidity())


#!/usr/bin/env python

import sys
from queue import Queue
from collections import namedtuple

# Struct for edges.
Edge = namedtuple('Edge', ['src', 'dest'])

# https://docs.python.org/2/library/userdict.html
class Graph(object):

    def __init__(self, number=4):
        self.adj = {}
        print ("Inside graph creation...")
        for i in range (1,number+1):
            self.adj[i] = []
        print("Graph: ", self.adj)

    def build_graph(self, M):
        while (M > 0):
            x, y = read_ints()
            edge = Edge(x,y)
            self.adj[edge.src].append(edge.dest)  # node_edges[x].append(y)
            self.adj[edge.dest].append(edge.src)  # node_edges[y].append(x)
            M -= 1
        print ("Built graph: ", self.adj)

    def compute_distances(self, S):
        distances = {S: 0}  # distance to itself is obviously zero!
        queue = myQueue()
        queue.put (S)   #  queue.put(S)
        while (not queue.empty()):
            print ("Queue: ", queue)
            element = queue.get()
            distance = distances[element] + 6    # varies based on levels, 1st level = 0 + 6
            for neighbor in self.adj[element]:   # iterate through the neighbours
                if (neighbor in distances):
                    continue                     # ignore nodes in a cycles?
                distances[neighbor] = distance   # update distance to starting node
                print ("Distances: ", distances)
                queue.put(neighbor)              # so its neighbours get traversed in the while loop
        print ("Distances: ", distances)
        return distances

def read_ints():
    return [int(x) for x in sys.stdin.readline().split(" ")]

class myQueue(Queue):
    def __str__(self):
        return self.queue.__str__()

def print_distances(S, N, distances):
    for i in range(1, N + 1):
        if (i == S):
            continue  # to mute the printing of distance (aka 0) to itself
        if i in distances:
            print(distances[i], end=" "),
        else:
            print(-1, end=" "),
    print()

def test_case():
    (N, M) = read_ints()
    graph = Graph(N)               # with placeholders for N vertices
    graph.build_graph(M)           # process M edges as (src, dest)
    S = int(sys.stdin.readline())  # Get the Starting node for which distances will be calculated
    distances = graph.compute_distances(S)
    print_distances(S, N, distances)

def main():
    T = int(sys.stdin.readline())
    while (T > 0):
        test_case()
        T -= 1

if __name__ == '__main__':
    main()


from requests import Session
from weixin.config import *
from weixin.db import RedisQueue
from weixin.mysql import MySQL
from weixin.request import WeixinRequest
from urllib.parse import urlencode
import requests
from pyquery import PyQuery as pq
from requests import ReadTimeout,ConnectionError

class Spider():
    base_url='http://weixin.sogou.com/weixin'
    keyword='Python'
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2,mt;q=0.2',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Cookie': 'sw_uuid=3609245170; ssuid=6984416384; IPLOC=CN3205; SUID=42E4F03A2208990A000000005CAACCB1; '
                  'SUV=0077C7C03AF0E4425CAACCBA3EAA1002; sg_uuid=4552023396; pgv_pvi=2560417792; '
                  'ld=5kllllllll2t$7hflllllVhmZ1GlllllnsR6yklllx6llllljZlll5@@@@@@@@@@; LSTMV=1233%2C730; LCLKINT=3357;'
                  ' ABTEST=7|1555656250|v1; SNUID=07A2B57C4540C099347CF15446DF5250; weixinIndexVisited=1; sct=28; '
                  'JSESSIONID=aaaEN5dN5s469asWKmQOw; '
                  'ppinf=5|1555657086|1556866686|dHJ1c3Q6MToxfGNsaWVudGlkOjQ6MjAxN3x1bmlxbmFtZTo3MjolRTQlQjglODAlRTQlQj'
                  'glQUElRTQlQjglOEQlRTQlQkYlOTclRTYlQjAlOTQlRTclOUElODQlRTYlOTglQjUlRTclQTclQjB8Y3J0OjEwOjE1NTU2NTcwODZ'
                  '8cmVmbmljazo3MjolRTQlQjglODAlRTQlQjglQUElRTQlQjglOEQlRTQlQkYlOTclRTYlQjAlOTQlRTclOUElODQlRTYlOTglQjUlR'
                  'TclQTclQjB8dXNlcmlkOjQ0Om85dDJsdU1uRGNFMkVZQ2FMdElITGU2MlZiOXdAd2VpeGluLnNvaHUuY29tfA; '
                  'pprdig=C9hb1VEIXL_gj8VuGmwYAWeDaqQwG5sz6aifKnY1z61mCwAiAliOr_i0ttUjeP0YQy4u24ea3W4YlciR_pOkna68yh'
                  'R-uVUZqG41lBUan5t34Qtq8InIhLWmrnR_HOhTNbvKWFtpS86DEg2E6CZO2zrf-6Sivzeu3l9ZDsRMV7M; '
                  'sgid=00-45162031-AVy5cX5f8XYsibaupx6TZIiak; ppmdig=1555663237000000b769348c00cc240f380a45206d091d03',
        'Host': 'weixin.sogou.com',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
    }
    session=Session()
    queue=RedisQueue()
    mysql=MySQL()

    def get_proxy(self):
        """
        从代理池获取代理
        :return:
        """
        try:
            response=requests.get(PROXY_POOL_URL)
            if response.status_code==200:
                print('Get Proxy',response.text)
                return response.text
        except requests.ConnectionError:
            return None

    def start(self):
        """
        初始化工作
        :return:
        """
        # 全局更新Headers
        self.session.headers.update(self.headers)
        start_url=self.base_url+'?'+urlencode({'query':self.keyword,'type':2})
        weixin_request=WeixinRequest(url=start_url,callback=self.parse_index,need_proxy=True)

        # 调度第一个请求
        self.queue.add(weixin_request)

    def parse_index(self,response):
        """
        解析索引页
        :param response: 响应
        :return: 新的响应
        """
        doc=pq(response.text)
        items=doc('.news-box .news-list li .txt-box h3 a').items()
        for item in items:
            url=item.attr('href')
            weixin_request=WeixinRequest(url=url,callback=self.parse_detail)
            yield weixin_request
        next=doc('#sogou_next').attr('href')
        if next:
            url=self.base_url+str(next)
            weixin_request=WeixinRequest(url=url,callback=self.parse_index,need_proxy=True)
            yield weixin_request

    def parse_detail(self,response):
        """
        解析详情页
        :param response:
        :return:
        """
        doc=pq(response.text)
        data = {
            'title': doc('.rich_media_title').text(),
            'content': doc('.rich_media_content').text(),
            'date': doc('#post-date').text(),
            'nickname': doc('#js_profile_qrcode > div > strong').text(),
            'wechat': doc('#js_profile_qrcode > div > p:nth-child(3) > span').text()
        }
        yield data

    def request(self,weixin_request):
        """
        执行请求
        :param weixin_request: 请求
        :return: 响应
        """
        try:
            if weixin_request.need_proxy:
                proxy=self.get_proxy()
                if proxy:
                    proxies={
                        'http':'http://'+proxy,
                        'https':'https://'+proxy
                    }
                    return  self.session.send(weixin_request.prepare())
        except:
            pass


#!/usr/bin/env python
from contextlib import contextmanager
import os
from sh import cmake, make, mv
import sys

@contextmanager
def cd(newdir):
    prevdir = os.getcwd()
    os.chdir(os.path.expanduser(newdir))
    try:
        yield
    finally:
        os.chdir(prevdir)

if __name__ == "__main__":
    # git clone
    with cd("tool"):
        print(cmake('.', _out=sys.stdout))
        print(make(_out=sys.stdout))
        mv("src/sigrefmc", "..")
        mv("src/sigrefmc_ht", "..")


import os
import pandas as pd

files = os.listdir('./excelfiles')
print(files)

for excel in files:
    filename = 'excelfiles/' + excel
    dates = '日期'
    file = pd.read_excel(filename)
    date = [rows.split(" ")[0] for rows in file[dates]][0]
    os.rename(filename, '{}.xls'.format(date))


#Librerias helpers
import numpy as np
from pandas import DataFrame
from PIL import Image

#Clases necesarias
from matplotlib.animation import FuncAnimation
from threading import Thread
from matplotlib import dates as mpl_dates
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable
import matplotlib.font_manager as fm
from matplotlib.collections import QuadMesh

#Librerias Graficadoras
from matplotlib import pyplot as ppl
import seaborn as sn

class Graficador:
    """
    Clase que tiene el objetivo de funcionar como API para realizar graficos de to.do tipo, haciendo uso de librerias
    graficadores entre las que se encuentre matplotlib y seaborn.
    """
    def __init__(self,proporciones,filas=1,col=1,estilo=["default"]):
        """
        Metodo incializador de la figura que contendra los graficos, como a su vez de un mp_manager en caso de requerir subplots
        :param filas: Cantidad de filas de graficos que contendra nuestra figura
        :param col: Cantidad de columnas de graficos que contendra nuestra figura
        :param estilo: Una lista con los estilos que tendra el grafico.
        :param proporciones: Define el lugar y el espacio que va a ocupar cada subplot.Se espera
                             recibir una lista de strings.
        Ejemplo: 3 graficos, 2 filas  y 2 columnas.
        Queremos 1 grafico chico arriba en [0,0], otro chico abajo en [1,0] y el otro largo
        que ocupe [0,1] y [1,1], entonces mandarias por parametro. ['0,0',':,1','1,0']

        Para mas informacion sobre grids = https://matplotlib.org/tutorials/intermediate/gridspec.html#sphx-glr-tutorials-intermediate-gridspec-py
        Para mas informacion sobre estilos: https://tonysyu.github.io/raw_content/matplotlib-style-gallery/gallery.html
        """

        ppl.style.use(estilo)
        self.figura = ppl.figure(constrained_layout=True)
        self.grid_spec = self.figura.add_gridspec(filas,col)
        self.axes = self.__instanciar_axes__(proporciones)

    def __instanciar_axes__(self,proporciones):
        """
        Agrega todas las axis que se indico que se iba a utilizar. Dicha cantidad de axis esta representada
        por la longitud del vector contenido en la variable proporciones

        :param proporciones: Lista de string que representa la proporcion que va a ocupar cada subplot
        """
        def definir_gridspec(proporcion):
            """
            Traduce el significado de la proporcion a una de las siguientes keywords

            num_: = En caso de que haya un numero seguido de el caracter :
            :_num = En caso de que este el caracter : seguido de un numero

            num_num = En caso que tengamos dos numeros

            num1:_num2 = Todas las filas desde el num1 para abajo en la columna num2
            num1_num2: = Todas las columnas desde el num2 para la derecha en la fila num1

            :num1_num2 = Todas las filas hasta el num1 para abajo en la columna num2
            num1_:num2: = Todas las columnas hasta el num2 en la fila num1

            num1:_:num2 = Todas las filas desde el num1 para abajo hasta la columna num2
            :num1_:num2 = Todas las filas hasta el num1, desde la columna 0 a la num2

            num1:_num2: = Desde la fila num1 en adelante desde la columna dos en adelante
            :num1_num2: = Todas las filas hasta la num1, desde la columna num2 en adelante

            num1:num2,num3  = Desde la fila num1 hasta el num2(sin incluir) en la columna num3
            num1:num2,num3: = Desde la fila num1 hasta el num2(sin incluir) de la columna num3 en adelante
            num1:num2,:num3 = Desde la fila num1 hasta el num2(sin incluir) hasta la columna num3

            num1,num2:num3 = Desde la columna num2 hasta la num3(sin incluir) en la fila num3
            num1:,num2:num3 = Desde la columna num2 hasta la num3(sin incluir) de la fila num3 en adelante
            :num1,num2:num3 = Desde la columna num2 hasta la num3(sin incluir) hasta la fila num3

            num1:num2,num3:num4 = Desde la fila num1 hasta el num2(sin incluir),
                                  Desde la columna num3 hasta la num4(sin incluir)

            :param proporcion: String que representa una proporcion a cubrir del grafico
            :return: El rango de grid que se va a utilizar en dicho subplot
            """
            prop = proporcion.strip()
            if(len(prop) == 3 and prop[0].isdigit() and prop[2].isdigit()):
                n1 = int(prop[0])
                n2 = int(prop[2])
                return self.grid_spec[n1,n2]
            if(len(prop) == 3 and prop[0].isdigit()):
                n1 = int(prop[0])
                return self.grid_spec[n1, :]
            if(len(prop) == 3 and prop[2].isdigit()):
                n2 = int(prop[2])
                return self.grid_spec[:, n2]

            if(len(prop) == 4 and prop[0] == ":"):
                n1 = int(prop[1])
                n2 = int(prop[3])
                return self.grid_spec[:n1, n2]
            if(len(prop) == 4 and prop[1] == ":"):
                n1 = int(prop[0])
                n2 = int(prop[3])
                return self.grid_spec[n1:, n2]
            if(len(prop) == 4 and prop[2] == ":"):
                n1 = int(prop[0])
                n2 = int(prop[3])
                return self.grid_spec[n1, :n2]
            if (len(prop) == 4 and prop[3] == ":"):
                n1 = int(prop[0])
                n2 = int(prop[2])
                return self.grid_spec[n1, n2:]

            if(len(prop) == 5 and prop[0] == ":" and prop[3]== ":"):
                n1 = int(prop[1])
                n2 = int(prop[4])
                return self.grid_spec[:n1, :n2]
            if(len(prop) == 5 and prop[1] == ":" and prop[4]== ":"):
                n1 = int(prop[0])
                n2 = int(prop[3])
                return self.grid_spec[n1:, n2:]
            if(len(prop) == 5 and prop[1] == ":" and prop[3] == ":"):
                n1 = int(prop[0])
                n2 = int(prop[4])
                return self.grid_spec[n1:, :n2]
            if (len(prop) == 5 and prop[0] == ":" and prop[4] == ":"):
                n1 = int(prop[1])
                n2 = int(prop[3])
                return self.grid_spec[:n1, n2:]
            if (len(prop) == 5 and prop[1] == ":" and prop[4].isdigit()):
                n1 = int(prop[0])
                n2 = int(prop[2])
                n3 = int(prop[4])
                return self.grid_spec[n1:n2,n3]
            if (len(prop) == 5 and prop[0].isdigit() and prop[3] == ":"):
                n1 = int(prop[0])
                n2 = int(prop[2])
                n3 = int(prop[4])
                return self.grid_spec[n1,n2:n3]

            if (len(prop)== 6 and prop[0].isdigit() and prop[2].isdigit() and prop[4]==":"):
                n1 = int(prop[0])
                n2 = int(prop[2])
                n3 = int(prop[5])
                return self.grid_spec[n1:n2,:n3]
            if (len(prop)== 6 and prop[0].isdigit() and prop[2].isdigit() and prop[5]==":"):
                n1 = int(prop[0])
                n2 = int(prop[2])
                n3 = int(prop[4])
                return self.grid_spec[n1:n2,n3:]
            if (len(prop)== 6 and prop[0] == ":"):
                n1 = int(prop[1])
                n2 = int(prop[3])
                n3 = int(prop[5])
                return self.grid_spec[:n1,n2:n3]
            if (len(prop)== 6 and prop[0]==":" and prop[3].isdigit() and prop[5].isdigit()):
                n1 = int(prop[0])
                n2 = int(prop[3])
                n3 = int(prop[5])
                return self.grid_spec[n1:,n2:n3]

            if (len(prop)==7):
                n1 = int(prop[0])
                n2 = int(prop[2])
                n3 = int(prop[4])
                n4 = int(prop[6])
                return self.grid_spec[n1:n2, n3:n4]

        axes = []
        for i in range(len(proporciones)):
            axes.append(self.figura.add_subplot(definir_gridspec(proporciones[i])))
        return axes

    def set_real_time_on(self,animate_func,intervalo, fargs=None):
        """
        Comienza un thread que se usara en paralelo al thread original para que tu funcion
        reciba los datos correspondientes y los grafique a tiempo real pero que al mismo tiempo
        puedas generar otros graficos en el thread propio del main

        :param animate_func: Funcion que se usara para recibir datos a tiempo real y generar el grafico
        :param intervalo: Intervalo de tiempo que se usara para llamar nuevamente a animate_func
        :param fargs: Tupla que representa los argumentos extra(ademas del intervalo) que nececita
        tu funcion animate_func
        """
        def comenzar_intervalo():
            ani = FuncAnimation(self.figura,animate_func,fargs=fargs, interval=intervalo)
            self.display_graficos()

        rt_thread = Thread(target=comenzar_intervalo)
        rt_thread.start()
        rt_thread.join()

    def g2d_graficar(self,i_axis,x,y,marker=".",c_linea="black",estilo_linea="solid",ancho_linea=1,opaquez=1,
                     c_marker="black",ec_marker="black",tam_marker=1,label=None,posLegend="upper right"):
        """
        Genera un grafico con los puntos {(Xi,Yi)....(Xn,Yn)}

        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x: Vector que representa los puntos en el eje horizontal
        :param y: Vector que representa los puntos en el eje vertical
        :param marker: Estilo del punto. ., o, |,  _,
        :param c_linea: Color de la linea
        :param estilo_linea: Estilo de la linea. solid, dashed, dashdot, dotted
        :param ancho_linea: Ancho de la linea.
        :param opaquez: Opaquez de la linea
        :param c_marker: Color del marcador de los puntos
        :param ec_marker: Color deel contorno del marcador para los puntos
        :param tam_marker: Tamaño del marcador de los puntos
        :param label: Un string que represente el label del grafico
        :param posLegend: upper/lower/center + left/right todas las combinaciones
        :param title: Titulo del grafico
        """
        def is_sorted(x):
            """
            Devuelve True si el array esta ordenado. Si no esta ordenado vamos a tener que
            arreglarlo porque matplotlib lo grafica mal si las coordendas x no estan ordenadas
            :param x: Coordenadas x
            :return: True si esta ordenado, False de caso contrario
            """
            return all(x[i] <= x[i + 1] for i in range(len(x) - 1))

        def sort_and_align(x,y):
            """
            Devuelve la coordenada x ordenada y ajusta los valores de y para que se encuentren
            en la posicion a la coordenada x a la que hacen referencia
            :param x: Coordenada X
            :param y: Coordenada Y
            :return: (x,y) con x ordenado y Y alineado para que los valores de las coordenadas
            x esten asociados al mismo valor de y que estaban asaociados anteriormente
            """
            arg_sort = np.argsort(x)
            sorted_x_y = np.array([[x[i],y[i]] for i in arg_sort])
            x = sorted_x_y[:,0].reshape(-1)
            y = sorted_x_y[:,1].reshape(-1)
            return x,y

        if(not is_sorted(x)):
            x,y = sort_and_align(x,y)
        ax = self.axes[i_axis]
        ax.plot(x,y,color=c_linea,marker=marker, linestyle=estilo_linea,alpha=opaquez,
                mfc=c_marker,ms=tam_marker,mec=ec_marker,label=label,
                lw=ancho_linea)
        if label:
            ax.legend(loc=posLegend)

    def histograma(self,i_axis,x,bins=None,tam_barra=None,color_barra="#5d82c9",color_borde="black",
                   orientacion="vertical",label=None,posLegend="upper right", display_bins_ranges=False):
        """
        Realiza el grafico de un histograma en la axis correspondiente con la informacion que se
        le otorgo por parametro.

        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x: Vector de valores observados
        :param bins: Una lista con bins custom
        :param tam_barra: Tamaño relativo de la barra
        :param color_barra: Color de la barra
        :param color_borde: El color del borde de las barras del histograma
        :param orientacion: vertical por default, horizontal si lo queres al revez
        :param label: Un string que represente el label del grafico
        :param posLegend: upper/lower/center + left/right todas las combinaciones
        :param title: Titulo del grafico
        :param display_bins_ranges: True si queres que se muestren todos los rangos que determinan cada bien
                                    ya sea en el eje X o en el eje Y
        """
        ax = self.axes[i_axis]
        (_,bins,_) = ax.hist(x,bins=bins,rwidth=tam_barra,orientation=orientacion,fc=color_barra,ec=color_borde)
        indices = bins[[i%2 == 0 for i in range(len(bins))]] if not display_bins_ranges else bins
        ppl.sca(ax)
        ppl.xticks(indices) if orientacion=="vertical" else ppl.yticks(indices)
        if label:
            ax.legend(loc=posLegend)

    def histograma_conjunto(self,i_axis,x1,x2,bins1=None,bins2=None,cbarrras=["#fcb27c","#5d82c9"],cbordes=["black","black"],display_bins_ranges=False,
                  orientacion="vertical",label=[None,None],posLegend="upper right"):
        """
        Grafica dos histogramas uno arriba del otro con objetivos de comparar resultados

        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x1: Set de datos 1
        :param x2: Set de datos 2
        :param bins1: Bins custom para set de datos numero 1
        :param bins2: Bins custom para set de datos numero 2
        :param cbarrras: Lista que se usara para darle el color a las barras de los histogramas
        :param cbordes:  Lista que se usara para darle el color al contorno de las barras de los histogramas
        :param display_bins_ranges: True en caso que quieras ver todos los rangos de los dos histogramas
        :param orientacion: Vertical/Horizontal
        :param label: Lista de dos elementos que se usara para agregarle los labels a los histogramas
        :param posLegend: Posicion en donde queres que se encuentre la leyenda
        :param titulo: Titulo del grafico
        """
        ax = self.axes[i_axis]
        (_,bins1,_) = ax.hist(x1,bins=bins1,alpha=0.8,rwidth=0.97,orientation=orientacion,fc=cbarrras[0],ec=cbordes[0],label=label[0])
        (_,bins2,_) = ax.hist(x2,bins=bins2,alpha=0.5,orientation=orientacion,fc=cbarrras[1],ec=cbordes[1],label=label[1])
        conc_bins = np.sort(np.concatenate((bins1,bins2),axis=None))
        indices = conc_bins[[i%2 == 0 for i in range(len(conc_bins))]] if not display_bins_ranges else conc_bins
        ppl.sca(ax)
        ppl.xticks(indices) if orientacion=="vertical" else ppl.yticks(indices)
        if label:
            ax.legend(loc=posLegend)

    def grafico_tarta(self,i_axis,data,labels,colores=None,s_destacar=None,sombra=False,d_valores=False,
                      angulo_inicio=0,anchoLinea=1,opaquedad=1,posLegend="upper right"):
        """
        Realiza un grafico de tarta
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param data: Valores por categoria
        :param colores: Categoria respectiva a los valores
        :param s_destacar: Variable que se utiliza para destacar uno de los slices de la torta.
        Las opciones disponibles son {'max','min','#insertLabelName',None}
        :param sombra: True si queres que la tarta tenga sombreado
        :param d_valores: True si queres que se haga un display de los valores al lado de su porcentaje
        :param angulo_inicio: Angulo en el cual queres que empieze la tarta
        :param anchoLinea: Ancho de la linea que separa los slices
        :param c_linea: Color de la linea que separa los slices
        :param opaquedad: Opaquedad de la linea que separa los slices
        :param titulo: Titulo del grafico
        :param posLegend: Posicion donde se encontrara la leyenda
        """
        def make_autopct(values):
            """
                Define el display que se realiza en cada slice
            """
            def my_autopct(pct):
                total = sum(values)
                val = int(round(pct * total / 100.0))
                return '{p:.2f}%  ({v:d})'.format(p=pct, v=val)
            return my_autopct
        def get_explode_list(data,labels,s_destacar):
            """
            Devuelve una lista que representa el factor por el cual hay que levantar a cada
            slice
            """
            estandar = np.arange(len(labels),dtype=np.float64)
            estandar.fill(0.0)
            if(s_destacar == "max"):
                i_max = np.argmax(np.array(data))
                estandar[i_max] = 0.1
            elif(s_destacar == "min"):
                i_min = np.argmin(np.array(data))
                estandar[i_min] = 0.1
            else:
                pos_label = np.where(np.array(labels) == s_destacar)
                if(pos_label[0]):#Si devolvio una lista que no esta vacia
                    estandar[pos_label[0][0]] = 0.1
            return estandar

        ax = self.axes[i_axis]
        explode_list = get_explode_list(data,labels,s_destacar) if s_destacar else None
        auto_pct = make_autopct(data) if d_valores else "%1.1f%%"
        ax.pie(data,labels=labels,explode=explode_list,autopct=auto_pct,colors=colores, startangle=angulo_inicio,
               shadow=sombra,wedgeprops={'alpha':opaquedad,'lw':anchoLinea})
        ax.legend(loc=posLegend)

    def g2d_dispersion(self,i_axis,x,y,c="#552df4f7",s=None,marker="o",ec="face",label=None,posLegend="upper right",
                       opaquedad=1):
        """
        Grafica un grafico de dispersion
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x: Coordenadas X
        :param y: Coordenadas Y
        :param c: color de los puntos
        :param s: tamaño de los puntos
        :param marker: Tipo de punto
        :param ec: color del contorno de los puntos
        :param label: label del grafico
        :param posLegend: Posicion donde se encontrara la legenda
        :param titulo: titulo del grafico
        """
        ax = self.axes[i_axis]
        ax.scatter(x,y,c=c,s=s,marker=marker,edgecolor=ec,alpha=opaquedad,label=label)
        if label:
            ax.legend(loc=posLegend)

    def g2d_barras(self,i_axis,x,altura,pos_barras="vertical",c="#6369b3",ec="black",ancho_barra=0.8,opaquez=1,label=None,
                   posLegend="upper right"):
        """
        Grafica un grafico de barras vertical
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x: Coordenadas en el eje X
        :param altura: Altura de la barra
        :param pos_barras: vertical o horizontal
        :param c: Color de la barra
        :param ec: Color del contorno de la barra
        :param ancho_barra: Ancho de la barra
        :param opaquez: Opaquez de la barra
        :param label: Label del grafico
        :param posLegend: Posicion donde se encontrara la leyenda
        """
        ax = self.axes[i_axis]
        if(pos_barras == "vertical"):
            ax.bar(x,altura,color=c,width=ancho_barra,edgecolor=ec,alpha=opaquez,label=label)
        else:
            ax.barh(x,altura,color=c,height=ancho_barra,edgecolor=ec,alpha=opaquez,label=label)
        if label:
            ax.legend(loc=posLegend)

    def g2d_grafico_discreto(self,i_axis,x,y,estilo_linea="-",c_linea="#83b0f2",ancho_linea=1,marker="o",baseline=True,c_baseline="#d16f6f",
                             c_marker="#83b0f2",ec_marker="white",tam_marker=8,label=None,posLegend="upper right"):
        """
        Grafica un grafico discreto
        :param i_axis: Axis donde realizar el grafico
        :param x: COordenadas x
        :param y: Coordenadas Y
        :param estilo_linea: Estlo de la linea "-","--",...
        :param c_linea: Color de la linea
        :param ancho_linea: Ancho de la linea
        :param marker: Tipo de marcador
        :param baseline: True si se quiere una baseline, False en caso contrario
        :param c_baseline: Color de la baseline
        :param c_marker: Color del marcador
        :param ec_marker: Color del contorno del marcador
        :param tam_marker: Tamaño del marcador
        :param label: Label asociado
        :param posLegend: Posicion en donde queres que se encuentre la leyenda
        """
        ax = self.axes[i_axis]
        (markerline, stemlines, basel) = ax.stem(x,y,linefmt=estilo_linea,markerfmt=marker,label=label)
        stemlines.set_color(c_linea)
        stemlines.set_linewidth(ancho_linea)
        markerline.set_color(c_marker)
        markerline.set_markeredgecolor(ec_marker)
        markerline.set_markersize(tam_marker)
        if(baseline):
            basel.set_color(c_baseline)
        else:
            basel.set_linewidth(0)
        if label:
            ax.legend(loc=posLegend)

    def g2d_contour(self,i_axis,coord_x,coord_y,matriz_alturas,display_level=True,cmap="Greys",
                    niveles=None,colorbar=True,fcontour=False,label=None,posLegend="upper right"):
        """
        Grafica un contour plot, que basicamente es una representacion 2D de un grafico 3D
        si lo cortamos con un plano en #niveles capas. La idea es tener una coordenada X,Y
        que la transformamos en un meshgrid para poder tener todos los puntos que forman
        esos dos vectores, junto a una matriz Z de shape [x.shape[0],y.shape[0]] que te dice
        la altura que tiene cada uno de esos puntos.

        :param i_axis: Eje sobre el cual vamos a graficar
        :param coord_x: Puntos X a utilizar
        :param coord_y: Puntos Y a utilizar
        :param matriz_alturas: matriz Z de shape [coord_x.shape[0],coord_y.shape[0]] que representa
        la altura de cada uno de los puntos que surgen como combinacion de ambos vectores
        :param display_level: En caso que se quiera hacer un display textual del nivel en donde
        corta cada plano
        :param cmap: String que represente un colormap valido en pyplot
        :param niveles: Cantidad de niveles en los que deseamos hacer un corte
        :param colorbar: True por default, para mostrar el color asociado a cada nivel.
        :param fcontour: True en caso que se quiera realizar un contourf plot
        :param label: Label asociado al grafico
        :param posLegend: Posicion en donde queremos que se encuentre la leyenda

        """
        def realizar_grafico(vmin,vmax):
            """
            Realiza el grafico contour correspondiente y devuelve el resultado
            :return: instancia de QuadContourSet
            """
            X, Y = np.meshgrid(coord_x, coord_y)
            if not fcontour:
                return ax.contour(X, Y, matriz_alturas, cmap=cmap, levels=niveles, norm=Normalize(vmin=vmin, vmax=vmax))
            else:
                return ax.contourf(X, Y, matriz_alturas, cmap=cmap, levels=niveles, norm=Normalize(vmin=vmin,vmax=vmax))
        ax = self.axes[i_axis]
        vmin, vmax = np.amin(matriz_alturas), np.amax(matriz_alturas)
        ct = realizar_grafico(vmin,vmax)
        if colorbar:
            cbar = ppl.colorbar(ScalarMappable(norm=Normalize(vmin=vmin, vmax=vmax), cmap=cmap), ax=ax,aspect=45)
            cbar.solids.set_rasterized(True)
            cbar.solids.set_edgecolor("face")
        if display_level:
            ax.clabel(ct,inline=1,fontsize=8)
        if label:
            ax.legend(loc=posLegend)

    def boxplot(self,i_axis,data,labels=None,c_box="black",lw_box=1.2,lw_median=1.5,c_median="#2e3fff",c_outliers="red",
                m_outliers="o",ms_outliers=5,posLegend="upper right"):
        """
        Grafica un box and whiskers plot
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param data: Vector o vectores(en caso de nececiitar mas de un plot) a graficar
        :param labels: Labels para cada vector
        :param c_box: Color de la caja
        :param lw_box: Ancho de la linea de la caja
        :param lw_median: Ancho de la linea del 50th quartile
        :param c_median: Color de la linea del 50th quartile
        :param c_outliers: Color de los outliers
        :param m_outliers: Marker a utilizar para los outliers
        :param ms_outliers: El tammaño del marker a utilizar para los outliers
        :param posLegend: Posicion en la que se encontrara la leyenda
        """
        ax = self.axes[i_axis]
        ax.boxplot(data,labels=labels,boxprops={'color':c_box,'linewidth':lw_box},
                   flierprops={'marker':m_outliers,'markerfacecolor':c_outliers,'markersize':ms_outliers},
                   medianprops={'linewidth':lw_median,'color':c_median})
        if labels:
            ax.legend(loc=posLegend)

    def tabla(self,i_axis,data_celdas,row_labels=None,col_labels=None,posTextCeldas="center",c_colL=None,
              posTextFilas="left",posTextCol="center", c_celdas="#f6f6f6",c_rowL=None, special_cell_props=False,
              c_borde = "black",text_font=15,c_texto="black",opaquez_texto=1,peso_texto="normal"):
        """
        Grafica una tabla
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param data_celdas: Matriz que representa el valor que cada celda tendra
        :param row_labels: Lista de la misma longitud que la cantidad de filas que tendra nuestra tabla
        representando el label asociado a cada fila
        :param col_labels: Lista de la misma longitud que la cantidad de columnas que tendra nuestra tabla
        representando el label asociado a cada columna
        :param posTextCeldas: Representa la alineacion del texto de las celdas center,right,left
        :param posTextFilas: Representa la alineacion del texto de los labels que representan las filas center,right,left
        :param posTextCol: Representa la alineacion del texto de los labels que representan las columnas center,right,left
        :param special_cell_props: True si se quiere setear caracteristicas especiales referente a la celda
        :param c_celdas: Matriz con la misma shape que data_celdas que representa el color de cada celda, o
        un string que represente un color que sera aplicado a todas las celdas
        :param c_rowL:Lista de la misma longitud que la cantidad de filas que tendra nuestra tabla
        representando el color de cada label, o un color en formato string que aplicara a todos los labels
        :param c_colL: Lista de la misma longitud que la cantidad de columnas que tendra nuestra tabla
        representando el color de cada label, o un color en formato string que aplicara a todos los labels
        """
        def is_numpy_string(array):
            """
            Evalua si un numpy array/matriz esta compuesto por strings
            :param array: Numpy array
            :return: True si el array es un vector de strings o una matriz de strings
            """
            if(len(array.shape) == 1):
                return type(array[0]) == np.str_
            elif(len(array.shape) == 2):
                return type(array[0,0]) == np.str_
            else:
                raise Exception("El array no puede ser tridimencional")
        def stringfy(array):
            """
            Transforma los elementos de un array o matriz a string
            :param array: Numpy array
            :return: String version de los elementos del array
            """
            arr = np.array(array) if type(array) != np.ndarray else array
            if(len(array.shape) == 1):
                return np.array(list(map(str,arr)))
            elif(len(array.shape) == 2):
                return np.array([list(map(str,fila)) for fila in arr])
            else:
                raise Exception("El array no puede ser tridimencional")
        def get_celdas_tabla(data_celdas):
            """
            Transofmra la data de las celdas en el formato correcto para ser recibido en la funcion
            table de matplotlib
            :param data_celdas: Matriz/vector que representa la data que tendra nuestras celdas
            :return: Numpy array representando la data de cada celda en formato string
            """
            celdas_tabla = np.array(data_celdas) if type(data_celdas) != np.ndarray else data_celdas
            return stringfy(celdas_tabla) if not is_numpy_string(celdas_tabla) else celdas_tabla
        def es_lista_elem(var):
            """
            Chekea si una variable es una lista un numpy array
            :param var: Variable
            :return: True si es una lista o np.array
            """
            return type(var) is list or type(var) is np.ndarray
        def get_color_celdas(colorCeldas,cant_filas,cant_col):
            """
            Devuelve el color de cada celda a traves de un array de la misma shape que la tabla
            :param colorCeldas: Color que tendran las celdas
            :param cant_filas: Cantidad de filas de la tabla
            :paramm cant_col: Cantidad de columnas de la tabla
            :return: Devuelve el color de cada celda a traves de un array de la misma shape que la tabla
            """
            if es_lista_elem(colorCeldas):
                return colorCeldas
            elif not colorCeldas:
                return None
            elif cant_fil == 1:
                return [c_celdas] * cant_col
            else:
                return [[c_celdas] * cant_col] * cant_filas
        def vectorizar_colores(colores,long):
            """
            Transforma a un string en una lista de colores de longitud #long
            :param colores: String rerepsentando los colores, valor nulo, o vector de colores
            :param long: Tamaño del vector
            :return: Vector que representa una lista de colores.
            """
            if es_lista_elem(colores):
                return colores

            elif not colores:
                return None

            return [colores]*long

        celdas_tabla = get_celdas_tabla(data_celdas)
        cant_fil = celdas_tabla.shape[0]
        cant_col = celdas_tabla.shape[1]
        c_celdas = get_color_celdas(c_celdas,cant_fil,cant_col)
        c_filas = vectorizar_colores(c_rowL,cant_fil)
        c_columnas = vectorizar_colores(c_colL,cant_col)
        ax = self.axes[i_axis]
        ax.axis("off")
        tabla = ax.table(cellText=celdas_tabla,rowLabels=row_labels,colLabels=col_labels,cellLoc=posTextCeldas,
                 cellColours=c_celdas,rowColours=c_filas,colColours=c_columnas,
                 colLoc=posTextCol,rowLoc=posTextFilas,loc="center")

        tabla.auto_set_font_size(False)
        tabla.set_fontsize(text_font)
        if(special_cell_props):
            for i in range(cant_fil):
                for j in range(cant_col):
                    cell= tabla[i,j]
                    cell.set_text_props(color=c_texto,fontweight=peso_texto,alpha=opaquez_texto)
                    cell.set_edgecolor(c_borde)

    def set_ax_ticks(self,i_axis,x_ticks=None,x_labels=None,y_ticks=None,y_labels=None):
        """
        Cambia los valores que se muestran en el eje x/y de la axis indicada y cambia
        dichos valores por los labels indicados en caso de ser necesario

        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param x_ticks: Coordenadas X a mostrar
        :param x_labels: Labels de las coordendas X a mostrar
        :param y_ticks: Coordendas Y a mostrar
        :param y_labels: Labels de las coordendas Y a mostrar
        """
        ax = self.axes[i_axis]
        ppl.sca(ax)
        ppl.xticks(x_ticks,labels=x_labels)
        ppl.yticks(y_ticks,labels=y_labels)

    def format_date_axis(self,i_axis,day=True,month=True,year=True):
        """
        Formatea de una manera mas visiblemente agradable el eje x de la axis indicada.
        Obviamente asume que dicho eje esta compuesto por fechas.
        :param i_axis: Axis sobre la cual se desea trabajar
        """
        def get_date_format(day,month,year):
            format = ""
            format += "%b," if month else ""
            format += "%d " if day else ""
            format += "%Y" if year else ""
            return format

        ax = self.axes[i_axis]
        format = get_date_format(day,month,year)
        date_format = mpl_dates.DateFormatter(format)
        ax.get_xaxis().set_major_formatter(date_format)
        ppl.setp(ax.get_xticklabels(), rotation=30, ha="right")

    def set_ax_metadata__(self,i_axis,titulo=None,fuente_titulo=20,x_label=None,y_label=None,
                          x_font=None,y_font=None,c_t="black",c_x="black",c_y="black"):
        """
        Define la metadata de la axis sobre la cual se esta trabajando
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param titulo: Titulo del grafico
        :param fuente_titulo: Tamaño de la fuente del titulo
        :param x_label: label para el eje x
        :param y_label: label para el eje y
        :param x_font: Tamaño de la fuente del label para el eje x
        :param y_font: Tamaño de la fuente del label para el eje y
        :param c_x: Color de la fuente del eje X
        :param c_y: Color de la fuente del eje Y
        :param c_y: Color de la fuente del titulo
        """
        ax = self.axes[i_axis]
        ax.set_title(titulo,fontsize=fuente_titulo,color=c_t)
        ax.set_xlabel(x_label,fontsize=x_font,color=c_x)
        ax.set_ylabel(y_label,fontsize=y_font,color=c_y)

    def dibujar_linea(self,i_axis,punto,desde,hasta,indice_ax=None,orientacion="horizontal",
                      c="black",ls="solid",lw=1,posLegend="upper right", label=None):
        """
        Dibuja una linea con slope:0 horizontal o vertical sobre el punto y el rango indicado
        :param i_axis =Indice de la axis sobre la cual se desea graficar
        :param punto: Punto Y(en caso que la linea sea horizontal) o X(en caso que sea vertical) sobre
        el cual intersectara la recta con el eje correspondiente
        :param desde: Punto en caracter porcentual (0-1) desde donde comenzara la linea
        :param hasta: Punto en caracter porcentual (0-1) hasta donde llegaragi   la linea
        :param indice_ax: El indice de la axis sobre la cual queres efectuar los cambios,
        por default siempre se tomara la ultima sobre la cual se grafico.
        :param orientacion: Horizontal o Vertical, por default sera horizontal
        :param c: Color de la linea
        :param ls: Tipo de linea, solid/dashed/dotted/...
        :param lw: Ancho de la linea
        :param posLegend: Posicion donde se encontrara la leyenda
        :param label: Label asociado a la linea
        """
        ax = self.axes[i_axis]
        if(orientacion == "horizontal"):
            ax.axhline(punto,desde,hasta,color=c,linestyle=ls,linewidth=lw,label=label)
        else:
            ax.axvline(punto,desde,hasta,color=c,linestyle=ls,linewidth=lw,label=label)
        if label:
            ax.legend(loc=posLegend)

    def colorear_area(self,i_axis,cord_x,cord_y,clausula=None,c="#2980b9",opaquez=0.88,label=None,posLegend="upper right"):
        """
        Colorea el area que va desde {cord_x[0],cord_y[0]} hasta{cord_x[n],cord_y[n]}
        :param i_axis: Indice de la axis sobre la cual se desea colorear
        :param cord_x: Lista que representa las coordendas x
        :param cord_y: Lista que representa las coordenadas y
        :param clausula: Lista compuesta de 'True','False' que indica que coordenadas debemos
        omitir y cuales no
        :param c: Color que se usara para pintar el area
        :param opaquez: Opaquez que tendra el area
        :param label: Label asociado al area
        :param posLegend: Posicion en donde se encontrara la leyenda
        """
        ax = self.axes[i_axis]
        ax.fill_between(cord_x,cord_y,where=clausula,color=c,alpha=opaquez,label=label)
        if label:
            ax.legend(loc=posLegend)

    def matriz_de_confusion(self,i_axis,matriz,labels_categorias=[],cmap="Oranges",fmt='.2f',tam_fuente=11,ancho_linea=0.8):
        """
        Este funcion no fue realizada por mi sino que fue sacada de github y adaptada para que
        funcione en mi codigo. La idea es la de realizar un 'pretty print' de una matriz de confusion.
        Autor del codigo: https://github.com/wcipriano/pretty-print-confusion-matrix/blob/master/confusion_matrix_pretty_print.py

        :param i_axis: Axis sobre la cual realizar el grafico
        :param matriz: Matriz a graficar
        :param labels_categorias = Lista que representa los labels de cada categoria para la matriz
        de confusion en el orden en el que se encuentra representando en la matriz.
        :param cmap = color map valido
        :param tam_fuente = Tamaño de la fuente para el texto
        :param ancho_linea = Ancho de la linea para las celdas.
        """
        def instanciar_data_frame(matriz,labels_categorias):
            """
            Instancia un data frame con la matriz y labels otorgados
            :param matriz: Matriz de confusion
            :param labels_categorias: Labels propios de la matriz de confusion
            :return: Un dataframe en donde el index tanto de las filas y columnas esta dado por los labels(en caso que fuueron suministrados) y los
            valores estan dado por aquellos que se encuentran contenidos en la matriz
            """
            labels = (len(labels_categorias) != 0)
            if matriz.shape[0] != matriz.shape[1] or (labels and len(labels_categorias) != matriz.shape[0]):
                raise Exception("Las matrices de confusion son cuadradas, y los labels deben ser acordes a la matriz")
            dimension = matriz.shape[0]
            df = DataFrame(matriz,index=labels_categorias,columns=labels_categorias) if labels else DataFrame(matriz,index=range(dimension),columns=range(dimension))
            return df

        def insert_totals(df_cm):
            """
            Agrega una fila y columna extra en donde se encontraran los valores totales
            tanto para filas como columnas
            """
            sum_col = []
            for c in df_cm.columns:
                sum_col.append(df_cm[c].sum())
            sum_lin = []
            for item_line in df_cm.iterrows():
                sum_lin.append(item_line[1].sum())
            df_cm['sum_lin'] = sum_lin
            sum_col.append(np.sum(sum_lin))
            df_cm.loc['sum_col'] = sum_col

        def configcell_text_and_colors(array_df, lin, col, oText, facecolors, posi, fz, fmt, show_null_values=0):
            """
              config cell text and colors
              and return text elements to add and to dell
              @TODO: use fmt
            """
            text_add = [];
            text_del = [];
            cell_val = array_df[lin][col]
            tot_all = array_df[-1][-1]
            per = (float(cell_val) / tot_all) * 100
            curr_column = array_df[:, col]
            ccl = len(curr_column)

            # last line  and/or last column
            if (col == (ccl - 1)) or (lin == (ccl - 1)):
                # tots and percents
                if (cell_val != 0):
                    if (col == ccl - 1) and (lin == ccl - 1):
                        tot_rig = 0
                        for i in range(array_df.shape[0] - 1):
                            tot_rig += array_df[i][i]
                        per_ok = (float(tot_rig) / cell_val) * 100
                    elif (col == ccl - 1):
                        tot_rig = array_df[lin][lin]
                        per_ok = (float(tot_rig) / cell_val) * 100
                    elif (lin == ccl - 1):
                        tot_rig = array_df[col][col]
                        per_ok = (float(tot_rig) / cell_val) * 100
                    per_err = 100 - per_ok
                else:
                    per_ok = per_err = 0

                per_ok_s = ['%.2f%%' % (per_ok), '100%'][int(per_ok) == 100]

                # text to DEL
                text_del.append(oText)

                # text to ADD
                font_prop = fm.FontProperties(weight='bold', size=fz)
                text_kwargs = dict(color='w', ha="center", va="center", gid='sum', fontproperties=font_prop)
                lis_txt = ['%d' % (cell_val), per_ok_s, '%.2f%%' % (per_err)]
                lis_kwa = [text_kwargs]
                dic = text_kwargs.copy();
                dic['color'] = 'g';
                lis_kwa.append(dic);
                dic = text_kwargs.copy();
                dic['color'] = 'r';
                lis_kwa.append(dic);
                lis_pos = [(oText._x, oText._y - 0.3), (oText._x, oText._y), (oText._x, oText._y + 0.3)]
                for i in range(len(lis_txt)):
                    newText = dict(x=lis_pos[i][0], y=lis_pos[i][1], text=lis_txt[i], kw=lis_kwa[i])
                    # print 'lin: %s, col: %s, newText: %s' %(lin, col, newText)
                    text_add.append(newText)
                # print '\n'

                # set background color for sum cells (last line and last column)
                carr = [0.27, 0.30, 0.27, 1.0]
                if (col == ccl - 1) and (lin == ccl - 1):
                    carr = [0.17, 0.20, 0.17, 1.0]
                facecolors[posi] = carr

            else:
                if (per > 0):
                    txt = '%s\n%.2f%%' % (cell_val, per)
                else:
                    if (show_null_values == 0):
                        txt = ''
                    elif (show_null_values == 1):
                        txt = '0'
                    else:
                        txt = '0\n0.0%'
                oText.set_text(txt)

                # main diagonal
                if (col == lin):
                    # set color of the textin the diagonal to white
                    oText.set_color('w')
                    # set background color in the diagonal to blue
                    facecolors[posi] = [0.35, 0.8, 0.55, 1.0]
                else:
                    oText.set_color('r')

            return text_add, text_del

        x_label = 'Predicted'
        y_label = 'Actual'
        confusion_matrix_df = instanciar_data_frame(matriz,labels_categorias)
        insert_totals(confusion_matrix_df)

        axis = self.axes[i_axis]

        ax = sn.heatmap(confusion_matrix_df, annot=True, annot_kws={"size": tam_fuente}, linewidths=ancho_linea, ax=axis,
                        cbar=False, cmap=cmap, linecolor='w', fmt=fmt)

        #Rotamos los ticks
        ax.set_xticklabels(ax.get_xticklabels(), rotation=45, fontsize=10)
        ax.set_yticklabels(ax.get_yticklabels(), rotation=25, fontsize=10)

        # Turn off all the ticks
        for t in ax.xaxis.get_major_ticks():
            t.tick1line.set_visible(False)
            t.tick2line.set_visible(False)
        for t in ax.yaxis.get_major_ticks():
            t.tick1line.set_visible(False)
            t.tick2line.set_visible(False)

        # face colors list
        quadmesh = ax.findobj(QuadMesh)[0]
        facecolors = quadmesh.get_facecolors()

        # iter in text elements
        array_df = np.array(confusion_matrix_df.to_records(index=False).tolist())
        text_add = [];
        text_del = [];
        posi = -1  # from left to right, bottom to top.
        for t in ax.collections[0].axes.texts:  # ax.texts:
            pos = np.array(t.get_position()) - [0.5, 0.5]
            lin = int(pos[1]);
            col = int(pos[0]);
            posi += 1
            # print ('>>> pos: %s, posi: %s, val: %s, txt: %s' %(pos, posi, array_df[lin][col], t.get_text()))

            # set text
            txt_res = configcell_text_and_colors(array_df, lin, col, t, facecolors, posi, tam_fuente, fmt)

            text_add.extend(txt_res[0])
            text_del.extend(txt_res[1])

        # remove the old ones
        for item in text_del:
            item.remove()
        # append the new ones
        for item in text_add:
            ax.text(item['x'], item['y'], item['text'], **item['kw'])

        # titles and legends
        ax.set_title('Confusion matrix')
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)

    def graficar_imagen_por_matriz(self,i_axis,matriz):
        """
        Grafica una imagen dado una matriz
        :param i_axis: Indice de la axis sobre la cual graficar la imagen
        :param matriz: Matriz que representa la imagen
        """
        ax = self.axes[i_axis]
        ax.imshow(matriz)
        ax.set_axis_off()

    def graficar_imagen_por_ruta(self,i_axis,ruta):
        """
        Grafica una imagen dado una ruta
        :param i_axis: Indice de la axis sobre la cual graficar la imagen
        :param ruta: Ruta en donde se encuentra la imagen
        """
        ax = self.axes[i_axis]
        image = Image.open(ruta)
        ax.imshow(image)
        ax.set_axis_off()

    def display_graficos(self):
        """
           Hace un display de los graficos
        """
        ppl.show()


import numpy as np
import xlrd
from sys import path
path.append(r'd:\\MyDocument\\Study_makes_me_happy\\ManchineLearning\\libsvm\\python')
from svmutil import *

DATA_FILE="dataset.xlsx"
book = xlrd.open_workbook(DATA_FILE, encoding_override='utf-8')
sheet = book.sheet_by_index(0)
X = np.zeros(shape=(8,17))
Y = np.zeros(shape=(17,))
for i in range(22,39):
    for j in range(15,23):
        X[j - 15][i - 22] = sheet.cell_value(i,j)
for i in range(22,39):
    if sheet.cell_value(i,23)==1:
        Y[i - 22] = 1
    else:
        Y[i - 22] = -1
X_train = X[:,3:17]
Y_train = Y[3:17]
X_test = X[:,0:3]
Y_test = Y[0:3]
prob  = svm_problem(Y_train, X_train.T)
param = svm_parameter('-s 1 -t 0 -b 1')
m = svm_train(prob, param)
p_label, p_acc, p_val = svm_predict(Y_test, X_test.T, m, '-b 1')


import os

STEPNUMBER = 2

def processStdouts(indices, patterns):
	cwd = os.getcwd()
	stdout = 'v92.stdout'
	energies = []

	i = -1
	for subjob in os.listdir('subJobs'):
		jobDir = os.path.join(cwd, 'subJobs', subjob)
		stdoutPath = os.path.join(jobDir, 'v92.stdout')

		lines = None
		with open(stdoutPath, 'r') as f:
			lines = f.readlines()

		j = STEPNUMBER
		for line in lines:
			if '  subroutine' in line:
				if j != STEPNUMBER:
					j += 1
				elif j == STEPNUMBER:
					i+=1
					j = 1

			if 'PATH' in line and j == 1:
				terms = line.split()
				energy = float(terms[4])
				energies.append([indices[i], patterns[i], energy])

	return energies

def mapIndices(indices):
	patternLines = None
	with open('pattern_partition.info', 'r') as f:
		patternLines = f.readlines()[1:]
	triples = []
	for line in patternLines:
		triples.append(line.split())

	patterns = []
	for index in indices:
		for triple in triples:
			if index <= int(triple[2]) and index >= int(triple[1]):
				patterns.append(triple[0])

	return patterns

def processLogs():
	cwd = os.getcwd()
	logName = 'v92.log'
	energies = []
	rmsds = []
	indices = []

	for subjob in os.listdir('subJobs'):
		jobDir = os.path.join(cwd, 'subJobs', subjob)
		logPath = os.path.join(jobDir, 'v92.log')

		logLines = None
		with open(logPath, 'r') as f:
			logLines = f.readlines()

		i = 0
		for line in logLines:
			if 'Pass 2' in line:
				energyLine = logLines[i-2]
				energy = float(energyLine.split()[1])
				energies.append(energy)
				rmsdLine = logLines[i]
				rmsd = float(rmsdLine.split()[6])
				rmsds.append(rmsd)

				j = i
				indexFound = -1
				while(indexFound < 0):
					if 'Working on' in logLines[j]:
						indexFound = 1
						indexLine = logLines[j]
						index = int(indexLine.split()[4])
						indices.append(index)
					else:
						j-=1
			i+=1

	return indices, energies, rmsds

def main():
	indices, energies, rmsds = processLogs()
	patterns = mapIndices(indices)

	energies, indices, patterns, rmsds = (list(t) for t in zip(*sorted(zip(energies, indices, patterns, rmsds))))

	with open('v92.finalResult', 'w+') as f:
		f.write('INDEX'.ljust(12) + 'PATTERN'.ljust(12) +
		'ENERGY'.ljust(12) + 'RMSD'.ljust(12) + '\n')
		for i in range(0, len(indices)):
			f.write(str(indices[i]).ljust(12) + str(patterns[i]).ljust(12) +
			str(round(energies[i], 3)).ljust(12) + str(rmsds[i]).ljust(12) + '\n')

	allEnergies = processStdouts(indices, patterns)

	with open('./v92.finalResult_all', 'w+') as f:
		f.write('INDEX'.ljust(12) + 'PATTERN'.ljust(12) +
		'ENERGY'.ljust(12) + '\n')
		for i in range(0, len(allEnergies)):
			f.write(str(allEnergies[i][0]).ljust(12) + str(allEnergies[i][1]).ljust(12) +
			str(round(allEnergies[i][2], 3)).ljust(12) + '\n')

if __name__ == '__main__':
	main()