"""Walleter command line entry point."""
# Standard
import argparse
import errno
import logging
import os
import pkg_resources
import sys
import time
from logging.config import dictConfig

# Boltons
from boltons.iterutils import windowed_iter
from log_color import ColorFormatter, ColorStripper

# Project
from walleter.utils.arg_format import ArgFormatter
from walleter.utils.blockchain import BlockchainInfo
from walleter.utils.wallet import Wallet

LOG = logging.getLogger(__name__)
DEST_ADDRESS = '16Mfp5hjBmro5p4Kg6z4XqvVmrWbzq17px'

# Setup the version string globally
try:
    pkg_version = "%(prog)s {0}".format(
        pkg_resources.get_distribution("walleter").version
    )
except pkg_resources.DistributionNotFound:
    pkg_version = '%(prog)s Development'
except Exception:
    pkg_version = '%(prog)s Unknown'

# Py Compat
if sys.version_info[0] == 3:
    xrange = range

def logging_init(level, logfile=None, verbose=False):
    """
    Given the log level and an optional logging file location, configure
    all logging.
    """
    # Get logging related arguments & the configure logging
    if logfile:
        logfile = os.path.abspath(logfile)

    # Don't bother with a file handler if we're not logging to a file
    handlers = ['console', 'filehandler'] if logfile else ['console', ]

    # If the main logging level is any of these, set librarys to WARNING
    lib_warn_levels = ('DEBUG', 'INFO', 'WARNING', )

    # The base logging configuration
    BASE_CONFIG = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'ConsoleFormatter': {
                '()': ColorFormatter,
                'format': '%(levelname)s: %(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
            'FileFormatter': {
                '()': ColorStripper,
                'format': ("%(levelname)-8s: %(asctime)s '%(message)s' "
                           '%(name)s:%(lineno)s'),
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
        },
        'handlers': {
            'console': {
                'level': 'DEBUG' if verbose else level,
                'class': 'logging.StreamHandler',
                'formatter': 'ConsoleFormatter',
            },
        },
        'loggers': {
            'walleter': {
                'handlers': handlers,
                'level': 'DEBUG' if verbose else level,
                'propagate': False,
            },
            'requests': {
                'handlers': handlers,
                'level': 'WARNING' if level in lib_warn_levels else level,
                'propagate': False,
            },
        }
    }

    # If we have a log file, modify the dict to add in the filehandler conf
    if logfile:
        BASE_CONFIG['handlers']['filehandler'] = {
            'level': 'DEBUG' if verbose else level,
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': logfile,
            'formatter': 'FileFormatter',
        }

    # Setup the loggers
    dictConfig(BASE_CONFIG)

def cli():
    parser = argparse.ArgumentParser(
        description="Wallet exploration tool",
        formatter_class=ArgFormatter,
    )
    parser.add_argument(
        "-i",
        "--iterations",
        dest="iterations",
        type=int,
        default=1,
        help="Number of iterations to derive"
    )
    parser.add_argument(
        "-b",
        "--bypass-iterations",
        dest="bypass",
        action='store_true',
        help="Skip interstitial iterations"
    )
    parser.add_argument(
        "-V",
        "--version",
        dest="version",
        action="version",
        version=pkg_version,
        help="Display the version number."
    )
    parser.add_argument(
        '-l',
        '--log-level',
        default='INFO',
        choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),
        help='Logging level for command output.',
        dest='log_level'
    )
    parser.add_argument(
        '-L',
        '--logfile',
        dest='logfile',
        default=None,
        help='Location to place a log of the process output'
    )
    parser.add_argument(
        '-s',
        '--seed',
        dest='seed',
        default=None,
        help='Use a specific seed instead of core dataset'
    )
    parsed_args = parser.parse_args()
    logging_init(parsed_args.log_level, logfile=parsed_args.logfile)
    run(parsed_args.iterations,
        force_seed=parsed_args.seed, bypass=parsed_args.bypass)
    LOG.debug(u"#g<\u2713> Complete! Dataset exhausted.")

def iter_wallets(wallet, iterations):
    """Iterate a wallet feeding it's address into the next iteration."""
    prev = None
    for idx in xrange(iterations):
        if not prev:
            prev = wallet.address
            yield wallet
        else:
            try:
                new = Wallet(prev)
            except Exception:
                break
            else:
                prev = new.address
                yield new

def main():
    try:
        cli()
    except KeyboardInterrupt:
        # Write a nice message to stderr
        sys.stderr.write(
            u"\n\033[91m\u2717 Operation canceled by user.\033[0m\n"
        )
        sys.exit(errno.EINTR)

def run(iterations, force_seed=None, bypass=False):
    """Actual code shit."""

    home_folder = os.path.expanduser('~')
    config_dir = os.path.join(home_folder, '.walleter')

    if not os.path.exists(config_dir):
        os.mkdir(config_dir)

    cache_file = os.path.join(config_dir, 'check_cache')
    found_file = os.path.join(config_dir, 'found_coins')

    block_info = BlockchainInfo()
    LOG.info("Opening BlockchainInfo session")
    block_info.open_session()
    LOG.info("Session open")

    cache = []
    if os.path.exists(cache_file):
        with open(cache_file, 'rb') as f:
            cache = [x.strip().strip('\r\n').strip('\n') for x
                     in f.readlines()]

    # If given a specific seed, conjure a dataset from that
    if force_seed is not None:
        if force_seed in ('""', '\'\''):
            force_seed = ''
        all_data = [force_seed]
        LOG.info('Using custom seed: {0}'.format(force_seed))
    else:
        from data import all_data_iter as all_data

    tried = set()
    for dict_word in all_data:
        dict_word = dict_word.strip()

        if dict_word in tried:
            continue  # already did that this session

        tried.add(dict_word)
        LOG.debug('Dict word: "{0}"'.format(dict_word))

        # Create initial wallet
        try:
            wallet = Wallet(dict_word)
        except Exception:
            continue

        for idx, wallet in enumerate(iter_wallets(wallet, iterations)):

            if bypass and idx + 1 != iterations:
                continue

            if wallet.address in cache:
                LOG.debug('Skipping cached address')
                continue

            LOG.debug('Checking address: {0}'.format(wallet.address))

            # Get received bitcoins
            retry = 0
            while retry < 5:
                try:
                    received_bitcoins = block_info.get_received(wallet.address)
                    break
                except Exception:
                    LOG.warning('Response invalid for received bitcoins. '
                                'Retrying in 5 seconds.')
                    time.sleep(5)
                    retry += 1
            if retry == 5:
                LOG.error('Retries exceeded; Skipping.')
                continue

            if not received_bitcoins:
                LOG.info('Wallet never had any coins. Moving along...')

                # Write address to cache file
                with open(cache_file, 'a') as f:
                    f.write("{0}\n".format(wallet.address))
                continue

            # Get current balance
            for _ in xrange(5):
                try:
                    balance = block_info.get_balance(wallet.address)
                    break
                except Exception:
                    LOG.warning('Response invallid for balance. Retrying in '
                                '5seconds.')
                    time.sleep(5)
                    retry += 1
            else:
                LOG.error('Retries exceeded; skipping.'.format(retry_count))
                continue

            if balance == 0.00:
                balance_str = '#y<{:.8f}>'.format(balance)
            else:
                balance_str = '#g<{:.8f}>'.format(balance)

            # Output results
            output = (
                'Wallet found: {}; Received: {:.8f}; Address: {}; Private '
                'Key: {}; Balance: {}'.format(
                    wallet.passphrase,
                    received_bitcoins,
                    wallet.address,
                    wallet.private_key_wif,
                    balance_str
                )
            )

            LOG.info(output)
            with open(found_file, 'a') as f:
                f.write(output)
                f.write("\n")

if __name__ == "__main__":
    main()


from numpy import array, zeros, eye, asarray, dot, rad2deg, deg2rad, linspace, sin, cos, pi
from numpy.linalg import inv
from matplotlib.pyplot import plot, xlabel, ylabel, legend, rcParams
from sympy import symbols, simplify, trigsimp
from sympy.physics.mechanics import dynamicsymbols, ReferenceFrame, Point, inertia, RigidBody, KanesMethod
from sympy.physics.vector import init_vprinting, vlatex
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
from scipy.integrate import odeint
from scipy.linalg import solve_continuous_are
from pydy.codegen.code import generate_ode_function
import matplotlib.animation as animation
import math
from double_pendulum_setup import theta1, theta2, ankle, leg_length, waist, omega1, omega2, ankle_torque, waist_torque, coordinates, speeds, kane, mass_matrix, forcing_vector, specified, parameter_dict, constants, ke_energy, pe_energy
#from utils import controllable

init_vprinting()

rcParams['figure.figsize'] = (14.0, 6.0)

right_hand_side = generate_ode_function(mass_matrix, forcing_vector,
                                        constants,
                                        coordinates, speeds, specified)

#Initial Conditions for speeds and positions
x0 = zeros(4)
x0[:2] = deg2rad(0)
x0[1] = deg2rad(160)
#Specifies numerical constants for inertial/mass properties
#numerical_constants = array([1.035,  # leg_length[m]
#                             0.58,   # leg_com_length[m]
#                             23.779, # leg_mass[kg]
#                             0.383,  # leg_inertia [kg*m^2]
#                             0.305,  # body_com_length [m]
#                             32.44,  # body_mass[kg]
#                             1.485,  # body_inertia [kg*m^2]
#                             9.81],    # acceleration due to gravity [m/s^2]
#                             )

numerical_constants = array([1.0,  # leg_length[m]
                             1.0, # leg_mass[kg]
                             1.0, # body_length[m]
                             1.0,  # body_mass[kg]
                             9.81],    # acceleration due to gravity [m/s^2]
                             )
#Set input torques to 0
numerical_specified = array([0,0])

args = {'constants': numerical_constants,
        'specified': numerical_specified}

frames_per_sec = 60
final_time = 5.0
t = linspace(0.0, final_time, final_time*frames_per_sec)

right_hand_side(x0, 0.0, args)

y = odeint(right_hand_side, x0, t, args=(args,))

x1 = -1*numerical_constants[0]*sin(y[:,0])
y1 = numerical_constants[0]*cos(y[:,0])

x2 = x1 + -1*numerical_constants[2]*sin(y[:,0]+y[:,1])
y2 = y1 + numerical_constants[2]*cos(y[:,0]+y[:,1])

dt = 1./frames_per_sec

fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False,aspect='equal', xlim = (-2, 2), ylim = (-2, 2))
ax.grid()

line, = ax.plot([], [], 'o-', lw=2)
time_template = 'time=%.1fs'
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
energy_text = ax.text(0.02, 0.90, '', transform = ax.transAxes)

def energy(i):
  state = dict(zip(coordinates+speeds, y[i]))
  k = ke_energy.subs(state)
  u = pe_energy.subs(state)
  return k+u

def init():
  line.set_data([],[])
  time_text.set_text('')
  energy_text.set_text('')
  return line, time_text, energy_text

def animate(i):
  thisx = [0, x1[i], x2[i]]
  thisy = [0, y1[i], y2[i]]

  line.set_data(thisx, thisy)
  time_text.set_text(time_template%(i*dt))
  energy_text.set_text('energy = %.8f J' % energy(i))
  return line, time_text, energy_text

ani = animation.FuncAnimation(fig, animate, np.arange(1, len(y)), interval=dt*1000, blit=True, init_func=init)
#ani.save('double_pendulum_free.mp4')
plt.show()

plot(t, y[:,:2])
xlabel('Time [s]')
ylabel('Angle[deg]')
legend(["${}$".format(vlatex(c)) for c in coordinates])
plt.show()

plot(t, y[:, 2:])
xlabel('Time [s]')
ylabel('Angular Rate [deg/s]')
legend(["${}$".format(vlatex(s)) for s in speeds])
plt.show()


# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd

"""Unit tests for helpers module."""
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import unittest

from features import hotlist_helpers
from features import features_constants
from framework import profiler
from framework import table_view_helpers
from framework import sorting
from services import service_manager
from testing import testing_helpers
from testing import fake
from tracker import tablecell
from tracker import tracker_bizobj
from proto import features_pb2
from proto import tracker_pb2

class HotlistTableDataTest(unittest.TestCase):

  def setUp(self):
    self.services = service_manager.Services(
        issue=fake.IssueService(),
        features=fake.FeaturesService(),
        issue_star=fake.AbstractStarService(),
        config=fake.ConfigService(),
        project=fake.ProjectService(),
        user=fake.UserService(),
        cache_manager=fake.CacheManager())
    self.services.project.TestAddProject('ProjectName', project_id=1)

    self.services.user.TestAddUser('annajowang@email.com', 111)
    self.services.user.TestAddUser('claremont@email.com', 222)
    issue1 = fake.MakeTestIssue(
        1, 1, 'issue_summary', 'New', 111, project_name='ProjectName')
    self.services.issue.TestAddIssue(issue1)
    issue2 = fake.MakeTestIssue(
        1, 2, 'issue_summary2', 'New', 111, project_name='ProjectName')
    self.services.issue.TestAddIssue(issue2)
    issue3 = fake.MakeTestIssue(
        1, 3, 'issue_summary3', 'New', 222, project_name='ProjectName')
    self.services.issue.TestAddIssue(issue3)
    issues = [issue1, issue2, issue3]
    hotlist_items = [
        (issue.issue_id, rank, 222, None, '') for
        rank, issue in enumerate(issues)]

    self.hotlist_items_list = [
        features_pb2.MakeHotlistItem(
            issue_id, rank=rank, adder_id=adder_id,
            date_added=date, note=note) for (
                issue_id, rank, adder_id, date, note) in hotlist_items]
    self.test_hotlist = self.services.features.TestAddHotlist(
        'hotlist', hotlist_id=123, owner_ids=[111],
        hotlist_item_fields=hotlist_items)
    sorting.InitializeArtValues(self.services)
    self.mr = None

  def setUpCreateHotlistTableDataTestMR(self, **kwargs):
    self.mr = testing_helpers.MakeMonorailRequest(**kwargs)
    self.services.user.TestAddUser('annajo@email.com', 148)
    self.mr.auth.effective_ids = {148}
    self.mr.col_spec = 'ID Summary Modified'

  def testCreateHotlistTableData(self):
    self.setUpCreateHotlistTableDataTestMR(hotlist=self.test_hotlist)
    table_data, table_related_dict = hotlist_helpers.CreateHotlistTableData(
        self.mr, self.hotlist_items_list, self.services)
    self.assertEqual(len(table_data), 3)
    start_index = 100001
    for row in table_data:
      self.assertEqual(row.project_name, 'ProjectName')
      self.assertEqual(row.issue_id, start_index)
      start_index += 1
    self.assertEqual(len(table_related_dict['column_values']), 3)

    # test none of the shown columns show up in unshown_columns
    self.assertTrue(
        set(self.mr.col_spec.split()).isdisjoint(
            table_related_dict['unshown_columns']))
    self.assertEqual(table_related_dict['is_cross_project'], False)
    self.assertEqual(len(table_related_dict['pagination'].visible_results), 3)

  def testCreateHotlistTableData_Pagination(self):
    self.setUpCreateHotlistTableDataTestMR(
        hotlist=self.test_hotlist, path='/123?num=2')
    table_data, _ = hotlist_helpers.CreateHotlistTableData(
        self.mr, self.hotlist_items_list, self.services)
    self.assertEqual(len(table_data), 2)

  def testCreateHotlistTableData_EndPagination(self):
    self.setUpCreateHotlistTableDataTestMR(
        hotlist=self.test_hotlist, path='/123?num=2&start=2')
    table_data, _ = hotlist_helpers.CreateHotlistTableData(
        self.mr, self.hotlist_items_list, self.services)
    self.assertEqual(len(table_data), 1)

class MakeTableDataTest(unittest.TestCase):

  def test_MakeTableData(self):
    issues = [fake.MakeTestIssue(
        789, 1, 'issue_summary', 'New', 111, project_name='ProjectName',
        issue_id=1001)]
    config = tracker_bizobj.MakeDefaultProjectIssueConfig(789)
    cell_factories = {
        'summary': table_view_helpers.TableCellSummary}
    table_data = hotlist_helpers._MakeTableData(
        issues, [], ['summary'], [], {} , cell_factories,
        {}, set(), config, None, 29, 'stars')
    self.assertEqual(len(table_data), 1)
    row = table_data[0]
    self.assertEqual(row.issue_id, 1001)
    self.assertEqual(row.local_id, 1)
    self.assertEqual(row.project_name, 'ProjectName')
    self.assertEqual(row.issue_ref, 'ProjectName:1')
    self.assertTrue('hotlist_id=29' in row.issue_ctx_url)
    self.assertTrue('sort=stars' in row.issue_ctx_url)

class GetAllProjectsOfIssuesTest(unittest.TestCase):

  issue_x_1 = tracker_pb2.Issue()
  issue_x_1.project_id = 789

  issue_x_2 = tracker_pb2.Issue()
  issue_x_2.project_id = 789

  issue_y_1 = tracker_pb2.Issue()
  issue_y_1.project_id = 678

  def testGetAllProjectsOfIssues_Normal(self):
    issues = [self.issue_x_1, self.issue_x_2]
    self.assertEqual(
        hotlist_helpers.GetAllProjectsOfIssues(issues),
        set([789]))
    issues = [self.issue_x_1, self.issue_x_2, self.issue_y_1]
    self.assertEqual(
        hotlist_helpers.GetAllProjectsOfIssues(issues),
        set([678, 789]))

  def testGetAllProjectsOfIssues_Empty(self):
    self.assertEqual(
        hotlist_helpers.GetAllProjectsOfIssues([]),
        set())

class HelpersUnitTest(unittest.TestCase):

  # TODO(jojwang): Write Tests for GetAllConfigsOfProjects
  def setUp(self):
    self.services = service_manager.Services(issue=fake.IssueService(),
                                        config=fake.ConfigService(),
                                        project=fake.ProjectService(),
                                        features=fake.FeaturesService(),
                                        user=fake.UserService())
    self.project = self.services.project.TestAddProject(
        'ProjectName', project_id=1, owner_ids=[111])

    self.services.user.TestAddUser('annajowang@email.com', 111)
    self.services.user.TestAddUser('claremont@email.com', 222)
    self.issue1 = fake.MakeTestIssue(
        1, 1, 'issue_summary', 'New', 111,
        project_name='ProjectName', labels='restrict-view-Googler')
    self.services.issue.TestAddIssue(self.issue1)
    self.issue3 = fake.MakeTestIssue(
        1, 3, 'issue_summary3', 'New', 222, project_name='ProjectName')
    self.services.issue.TestAddIssue(self.issue3)
    self.issue4 = fake.MakeTestIssue(
        1, 4, 'issue_summary4', 'Fixed', 222, closed_timestamp=232423,
        project_name='ProjectName')
    self.services.issue.TestAddIssue(self.issue4)
    self.issues = [self.issue1, self.issue3, self.issue4]
    self.mr = testing_helpers.MakeMonorailRequest()

  def testFilterIssues(self):
    test_allowed_issues = hotlist_helpers.FilterIssues(
        self.mr, self.issues, self.services)
    self.assertEqual(len(test_allowed_issues), 1)
    self.assertEqual(test_allowed_issues[0].local_id, 3)

  def testFilterIssues_ShowClosed(self):
    self.mr.can = 1
    test_allowed_issues = hotlist_helpers.FilterIssues(
        self.mr, self.issues, self.services)
    self.assertEqual(len(test_allowed_issues), 2)
    self.assertEqual(test_allowed_issues[0].local_id, 3)
    self.assertEqual(test_allowed_issues[1].local_id, 4)

  def testMembersWithoutGivenIDs(self):
    h = features_pb2.Hotlist()
    owners, editors, followers = hotlist_helpers.MembersWithoutGivenIDs(
        h, set())
    # Check lists are empty
    self.assertFalse(owners)
    self.assertFalse(editors)
    self.assertFalse(followers)

    h.owner_ids.extend([1, 2, 3])
    h.editor_ids.extend([4, 5, 6])
    h.follower_ids.extend([7, 8, 9])
    owners, editors, followers = hotlist_helpers.MembersWithoutGivenIDs(
        h, {10, 11, 12})
    self.assertEqual(h.owner_ids, owners)
    self.assertEqual(h.editor_ids, editors)
    self.assertEqual(h.follower_ids, followers)

    owners, editors, followers = hotlist_helpers.MembersWithoutGivenIDs(
        h, set())
    self.assertEqual(h.owner_ids, owners)
    self.assertEqual(h.editor_ids, editors)
    self.assertEqual(h.follower_ids, followers)

    owners, editors, followers = hotlist_helpers.MembersWithoutGivenIDs(
        h, {1, 4, 7})
    self.assertEqual([2, 3], owners)
    self.assertEqual([5, 6], editors)
    self.assertEqual([8, 9], followers)

  def testMembersWithGivenIDs(self):
    h = features_pb2.Hotlist()

    # empty GivenIDs give empty member lists from originally empty member lists
    owners, editors, followers = hotlist_helpers.MembersWithGivenIDs(
        h, set(), 'follower')
    self.assertFalse(owners)
    self.assertFalse(editors)
    self.assertFalse(followers)

    # empty GivenIDs return original non-empty member lists
    h.owner_ids.extend([1, 2, 3])
    h.editor_ids.extend([4, 5, 6])
    h.follower_ids.extend([7, 8, 9])
    owners, editors, followers = hotlist_helpers.MembersWithGivenIDs(
        h, set(), 'editor')
    self.assertEqual(owners, h.owner_ids)
    self.assertEqual(editors, h.editor_ids)
    self.assertEqual(followers, h.follower_ids)

    # non-member GivenIDs return updated member lists
    owners, editors, followers = hotlist_helpers.MembersWithGivenIDs(
        h, {10, 11, 12}, 'owner')
    self.assertEqual(owners, [1, 2, 3, 10, 11, 12])
    self.assertEqual(editors, [4, 5, 6])
    self.assertEqual(followers, [7, 8, 9])

    # member GivenIDs return updated member lists
    owners, editors, followers = hotlist_helpers.MembersWithGivenIDs(
        h, {1, 4, 7}, 'editor')
    self.assertEqual(owners, [2, 3])
    self.assertEqual(editors, [5, 6, 1, 4, 7])
    self.assertEqual(followers, [8, 9])

  def testGetURLOfHotlist(self):
    cnxn = 'fake cnxn'
    user = self.services.user.TestAddUser('claremont@email.com', 432)
    user.obscure_email = False
    hotlist1 = self.services.features.TestAddHotlist(
        'hotlist1', hotlist_id=123, owner_ids=[432])
    url = hotlist_helpers.GetURLOfHotlist(
        cnxn, hotlist1, self.services.user)
    self.assertEqual('/u/claremont@email.com/hotlists/hotlist1', url)

    url = hotlist_helpers.GetURLOfHotlist(
        cnxn, hotlist1, self.services.user, url_for_token=True)
    self.assertEqual('/u/432/hotlists/hotlist1', url)

    user.obscure_email = True
    url = hotlist_helpers.GetURLOfHotlist(
        cnxn, hotlist1, self.services.user)
    self.assertEqual('/u/432/hotlists/hotlist1', url)

    # Test that a Hotlist without an owner has an empty URL.
    hotlist_unowned = self.services.features.TestAddHotlist('hotlist2',
        hotlist_id=234, owner_ids=[])
    url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist_unowned,
        self.services.user)
    self.assertFalse(url)


import sys
import Trader
from Trader import Trader

# Test class for historical bitcoin data.
class Test(Trader):

  # File for historical test data.
  testFile = ".btceUSD.csv"

  def __init__(self, deposit):
    self.ifile = open(self.testFile)
    self.prices = self.ifile.readlines()
    self.pos = 0
    Trader.__init__(self, deposit)

  # Gets the current price of bitcoin.
  def getCurrentPrice(self):
    if self.pos < len(self.prices):
      # return the price
      self.pos += 1
      return float(((self.prices[self.pos - 1]).split(','))[1])
    else:
      self.ifile.close()
      sys.exit(0)


# -*- coding: utf-8 -*-
"""This file is a careers24 spider created on top of the ATSSpider

scrapy crawl careers24 -a url="http://www.careers24.com" -a mining_job_id=999 -a iteration=1 -a extract=1
sample url:
    http://www.careers24.com
    http://www.careers24.co.ke
    http://www.careers24.com.ng
"""
from urlparse import urljoin
from re import compile

from scrapy.selector import Selector
from scrapy.http import Request

from brightcorp.base.atsspiders import ATSSpider
from brightcorp.items import BrightcorpItemLoader
from brightcorp.processors import ConvertDateString, Prefix , Replace, UrlJoin

class Careers24(ATSSpider):

    name = "careers24"
    url_fragmentanchor = "/jobs/?pagesize=100"
    ref_reg = compile('.*/(\d+)-')

    def parse(self, response):
        sel = Selector(response)

        # Set expected job count
        if not self.expected_job_count_set:
            expected_count = sel.xpath(
                "//div[@class='search_header']/h3/text()"
                ).extract()
            if expected_count:
                self.expected_job_count = expected_count[0]

        jobs = sel.xpath(
            "//div[contains(@id, '_resultContainer')]"
            )
        for job in jobs:
            link = job.xpath(".//*[@itemprop='title']/a/@href").extract()
            if link:
                job_url = urljoin(response.url, link[0])
                meta = {
                    'title': job.xpath(
                        ".//*[@itemprop='title']/a/text()"
                        ).extract(),
                    'logo_url': job.xpath(
                        ".//div[@class='recruiter_logo']/a/img/@src"
                        ).extract(),
                    'baseSalary': job.xpath(
                        ".//*[@itemprop='baseSalary'][last()]/text()"
                        ).extract(),
                    'jobtype': job.xpath(
                        ".//*[@itemprop='employmentType']/text()"
                        ).extract(),
                    'industry': job.xpath(
                        ".//*[@itemprop='baseSalary'][1]/text()"
                        ).extract(),
                    }
                yield Request(
                    job_url, meta=meta, callback=self.parse_job_callback()
                    )

        next_page = sel.xpath(
            "//a[@class='next' and contains(text(),'next')]/@href"
            ).extract()
        if next_page:
            next_url = urljoin(response.url, next_page[0])
            yield Request(next_url, callback=self.parse)

    def parse_job(self, response):
        sel = Selector(response)
        loader = BrightcorpItemLoader(selector=sel)
        loader.add_value('title', response.meta['title'])
        loader.add_value('baseSalary', response.meta['baseSalary'])
        loader.add_value('jobtype', response.meta['jobtype'])
        loader.add_value('industry', response.meta['industry'])
        loader.add_value('url', response.url)
        loader.add_value('apply_url', response.url)
        loader.add_value(
            'logo_url', response.meta['logo_url'], UrlJoin(response.url)
            )
        loader.add_value(
            'referencenumber', response.url, Prefix(self.name+"-"),
            re=self.ref_reg
            )
        loader.add_xpath(
            'description',
            "//div[text()='Job Details']|//div[@class='job_detail_container']/span[@itemprop='hiringOrganization']/node()"
            )
        loader.add_xpath(
            'company',
            "//span[@itemprop='hiringOrganization']/span[@itemprop='name']/text()"
            )
        loader.add_xpath(
            'date',
            "//div[@class='job_page_detail']//span[@class='posted']/text()",
            ConvertDateString("on %A, %B %d, %Y")
            )
        loader.add_xpath(
            'expiration_date',
            "//div[@class='job_page_detail']//span[contains(@id, '_lblClosingDate')]/text()",
            ConvertDateString("Apply before %A, %B %d, %Y -")
            )
        loader.add_xpath('requirements', "//div[contains(@id, '_divCandReq')]")
        loader.add_xpath('location', "//span[@itemprop='jobLocation']/text()")

        yield loader.load_item()


import bs4 as bs
import time
import random
import requests
from .login import login_website
from selenium.common.exceptions import TimeoutException

from Utils import DBHelper

def extract_source_torrent(base_url, db, table_name, section):
    TOTAL_ERROR_LIST = list()
    TOTAL_DATA_DIC = dict()

    webhandle = login_website(db)

    login_url = base_url + "/login.php"

    webhandle.get(base_url + "/thread0806.php?fid=" + str(section) + "&search=&page=0")
    soup = bs.BeautifulSoup(webhandle.page_source, "lxml")
    page_total = soup.findAll("input")[0]["onblur"]
    total_page_count = page_total.split("=")[-1].split("/")[-1].split("'")[0]
    cookies = webhandle.get_cookies()
    s = requests.Session()
    for cookie in cookies:
        s.cookies.set(cookie['name'], cookie['value'])

    for index in range(1, int(total_page_count) + 1):
        time.sleep(random.randint(1, 10))
        print("*********************************Current page index is : {}*********************************".format(
            index))
        complete_url = base_url + "/thread0806.php?fid=" + str(section) + "&search=&page=" + str(index)
        try:
            webhandle.get(complete_url)
            #r = s.get(complete_url)
        except Exception as ex:
            print(ex.msg)
            try:
                webhandle.get(complete_url)
            except:
                webhandle.close()
                webhandle = login_website(db)
                try:
                    webhandle.get(complete_url)
                except Exception as e:
                    print(e)
                    print("Skip this loop!")
                    continue

        source = webhandle.page_source
        #source = r.content
        soup = bs.BeautifulSoup(source, "lxml")
        for sub_item in soup.findAll("h3"):
            if len(sub_item.findAll('a')) == 0:
                TOTAL_ERROR_LIST.append(str(sub_item))
                continue
            link = sub_item.findAll('a')[0]
            title = link.text
            try:
                full_link = "/".join(login_url.split('/')[:-1]) + '/' + link["href"]
            except:
                print(link)
                TOTAL_ERROR_LIST.append(str(sub_item))
                continue
            # print("-" * 100)
            if full_link in TOTAL_DATA_DIC:
                print("{} has already exixts".format(full_link))
                continue
            if "htm_data" not in full_link:
                print("Invalid link")
                continue

            cursor = DBHelper.fetchData(db, "SELECT * FROM {} WHERE Link='{}'".format(table_name, full_link))
            if cursor.fetchone() != None:
                print("Record has already existed!")
                continue
            else:
                print("Title : {}".format(title))
                print("link : {}".format(full_link))
                print("\n")

                InsertSQL = u"INSERT INTO {} (Title, Link, Section, TorrentLink, DownloadingCount) VALUES (%s, %s, %s, %s, %s )".format(table_name)
                InsertData = (title, full_link, section, "", 0)
                try:
                    DBHelper.insert_table(db, InsertSQL, InsertData)
                except Exception as err:
                    print(err)
                    continue

    webhandle.close()


# Copyright (C) 2014 New York University
# This file is part of ReproZip which is released under the Revised BSD License
# See file LICENSE for full license details.

# This file is shared:
#   reprozip/reprozip/utils.py
#   reprounzip/reprounzip/utils.py

"""Utility functions.

These functions are shared between reprozip and reprounzip but are not specific
to this software (more utilities).

"""

from __future__ import division, print_function, unicode_literals

import codecs
import contextlib
from datetime import datetime
import email.utils
import itertools
import locale
import logging
import operator
import os
import requests
from rpaths import Path, PosixPath
import stat
import subprocess
import sys
import time

logger = logging.getLogger(__name__.split('.', 1)[0])

class StreamWriter(object):
    def __init__(self, stream):
        writer = codecs.getwriter(locale.getpreferredencoding())
        self._writer = writer(stream, 'replace')
        self.buffer = stream

    def writelines(self, lines):
        self.write(str('').join(lines))

    def write(self, obj):
        if isinstance(obj, bytes):
            self.buffer.write(obj)
        else:
            self._writer.write(obj)

    def __getattr__(self, name,
                    getattr=getattr):

        """ Inherit all other methods from the underlying stream.
        """
        return getattr(self._writer, name)

PY3 = sys.version_info[0] == 3

if PY3:
    izip = zip
    irange = range
    iteritems = lambda d: d.items()
    itervalues = lambda d: d.values()
    listvalues = lambda d: list(d.values())

    stdout_bytes = sys.stdout.buffer if sys.stdout is not None else None
    stderr_bytes = sys.stderr.buffer if sys.stderr is not None else None
    stdin_bytes = sys.stdin.buffer if sys.stdin is not None else None
    stdout, stderr = sys.stdout, sys.stderr
else:
    izip = itertools.izip
    irange = xrange  # noqa: F821
    iteritems = lambda d: d.iteritems()
    itervalues = lambda d: d.itervalues()
    listvalues = lambda d: d.values()

    _writer = codecs.getwriter(locale.getpreferredencoding())
    stdout_bytes, stderr_bytes = sys.stdout, sys.stderr
    stdin_bytes = sys.stdin
    stdout, stderr = StreamWriter(sys.stdout), StreamWriter(sys.stderr)

if PY3:
    int_types = int,
    unicode_ = str
else:
    int_types = int, long  # noqa: F821
    unicode_ = unicode  # noqa: F821

def flatten(n, iterable):
    """Flattens an iterable by repeatedly calling chain.from_iterable() on it.

    >>> a = [[1, 2, 3], [4, 5, 6]]
    >>> b = [[7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
    >>> l = [a, b]
    >>> list(flatten(0, a))
    [[1, 2, 3], [4, 5, 6]]
    >>> list(flatten(1, a))
    [1, 2, 3, 4, 5, 6]
    >>> list(flatten(1, l))
    [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 11, 12, 13, 14, 15, 16]]
    >>> list(flatten(2, l))
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    """
    for _ in irange(n):
        iterable = itertools.chain.from_iterable(iterable)
    return iterable

class UniqueNames(object):
    """Makes names unique amongst the ones it's already seen.
    """
    def __init__(self):
        self.names = set()

    def insert(self, name):
        assert name not in self.names
        self.names.add(name)

    def __call__(self, name):
        nb = 1
        attempt = name
        while attempt in self.names:
            nb += 1
            attempt = '%s_%d' % (name, nb)
        self.names.add(attempt)
        return attempt

def escape(s):
    """Escapes backslashes and double quotes in strings.

    This does NOT add quotes around the string.
    """
    return s.replace('\\', '\\\\').replace('"', '\\"')

def optional_return_type(req_args, other_args):
    """Sort of namedtuple but with name-only fields.

    When deconstructing a namedtuple, you have to get all the fields:

    >>> o = namedtuple('T', ['a', 'b', 'c'])(1, 2, 3)
    >>> a, b = o
    ValueError: too many values to unpack

    You thus cannot easily add new return values. This class allows it:

    >>> o2 = optional_return_type(['a', 'b'], ['c'])(1, 2, 3)
    >>> a, b = o2
    >>> c = o2.c
    """
    if len(set(req_args) | set(other_args)) != len(req_args) + len(other_args):
        raise ValueError

    # Maps argument name to position in each list
    req_args_pos = dict((n, i) for i, n in enumerate(req_args))
    other_args_pos = dict((n, i) for i, n in enumerate(other_args))

    def cstr(cls, *args, **kwargs):
        if len(args) > len(req_args) + len(other_args):
            raise TypeError(
                "Too many arguments (expected at least %d and no more than "
                "%d)" % (len(req_args),
                         len(req_args) + len(other_args)))

        args1, args2 = args[:len(req_args)], args[len(req_args):]
        req = dict((i, v) for i, v in enumerate(args1))
        other = dict(izip(other_args, args2))

        for k, v in iteritems(kwargs):
            if k in req_args_pos:
                pos = req_args_pos[k]
                if pos in req:
                    raise TypeError("Multiple values for field %s" % k)
                req[pos] = v
            elif k in other_args_pos:
                if k in other:
                    raise TypeError("Multiple values for field %s" % k)
                other[k] = v
            else:
                raise TypeError("Unknown field name %s" % k)

        args = []
        for i, k in enumerate(req_args):
            if i not in req:
                raise TypeError("Missing value for field %s" % k)
            args.append(req[i])

        inst = tuple.__new__(cls, args)
        inst.__dict__.update(other)
        return inst

    dct = {'__new__': cstr}
    for i, n in enumerate(req_args):
        dct[n] = property(operator.itemgetter(i))
    return type(str('OptionalReturnType'), (tuple,), dct)

def tz_offset():
    offset = time.timezone if time.localtime().tm_isdst == 0 else time.altzone
    return -offset

def isodatetime():
    offset = tz_offset()
    sign = '+'
    if offset < 0:
        sign = '-'
        offset = -offset
    if offset % 60 == 0:
        offset = '%02d:%02d' % (offset // 3600, (offset // 60) % 60)
    else:
        offset = '%02d:%02d:%02d' % (offset // 3600, (offset // 60) % 60,
                                     offset % 60)
    # Remove microsecond
    now = datetime.now()
    now = datetime(year=now.year, month=now.month, day=now.day,
                   hour=now.hour, minute=now.minute, second=now.second)
    return '%s%s%s' % (now.isoformat(),
                       sign,
                       offset)

def hsize(nbytes):
    """Readable size.
    """
    if nbytes is None:
        return "unknown"

    KB = 1 << 10
    MB = 1 << 20
    GB = 1 << 30
    TB = 1 << 40
    PB = 1 << 50

    nbytes = float(nbytes)

    if nbytes < KB:
        return "{0} bytes".format(nbytes)
    elif nbytes < MB:
        return "{0:.2f} KB".format(nbytes / KB)
    elif nbytes < GB:
        return "{0:.2f} MB".format(nbytes / MB)
    elif nbytes < TB:
        return "{0:.2f} GB".format(nbytes / GB)
    elif nbytes < PB:
        return "{0:.2f} TB".format(nbytes / TB)
    else:
        return "{0:.2f} PB".format(nbytes / PB)

def normalize_path(path):
    """Normalize a path obtained from the database.
    """
    # For some reason, os.path.normpath() keeps multiple leading slashes
    # We don't want this since it has no meaning on Linux
    path = PosixPath(path)
    if path.path.startswith(path._sep + path._sep):
        path = PosixPath(path.path[1:])
    return path

def find_all_links_recursive(filename, files):
    path = Path('/')
    for c in filename.components[1:]:
        # At this point, path is a canonical path, and all links in it have
        # been resolved

        # We add the next path component
        path = path / c

        # That component is possibly a link
        if path.is_link():
            # Adds the link itself
            files.add(path)

            target = path.read_link(absolute=True)
            # Here, target might contain a number of symlinks
            if target not in files:
                # Recurse on this new path
                find_all_links_recursive(target, files)
            # Restores the invariant; realpath might resolve several links here
            path = path.resolve()
    return path

def find_all_links(filename, include_target=False):
    """Dereferences symlinks from a path.

    If include_target is True, this also returns the real path of the final
    target.

    Example:
        /
            a -> b
            b
                g -> c
                c -> ../a/d
                d
                    e -> /f
            f
    >>> find_all_links('/a/g/e', True)
    ['/a', '/b/c', '/b/g', '/b/d/e', '/f']
    """
    files = set()
    filename = Path(filename)
    assert filename.absolute()
    path = find_all_links_recursive(filename, files)
    files = list(files)
    if include_target:
        files.append(path)
    return files

def join_root(root, path):
    """Prepends `root` to the absolute path `path`.
    """
    p_root, p_loc = path.split_root()
    assert p_root == b'/'
    return root / p_loc

@contextlib.contextmanager
def make_dir_writable(directory):
    """Context-manager that sets write permission on a directory.

    This assumes that the directory belongs to you. If the u+w permission
    wasn't set, it gets set in the context, and restored to what it was when
    leaving the context. u+x also gets set on all the directories leading to
    that path.
    """
    uid = os.getuid()

    try:
        sb = directory.stat()
    except OSError:
        pass
    else:
        if sb.st_uid != uid or sb.st_mode & 0o700 == 0o700:
            yield
            return

    # These are the permissions to be restored, in reverse order
    restore_perms = []
    try:
        # Add u+x to all directories up to the target
        path = Path('/')
        for c in directory.components[1:-1]:
            path = path / c
            sb = path.stat()
            if sb.st_uid == uid and not sb.st_mode & 0o100:
                logger.debug("Temporarily setting u+x on %s", path)
                restore_perms.append((path, sb.st_mode))
                path.chmod(sb.st_mode | 0o700)

        # Add u+wx to the target
        sb = directory.stat()
        if sb.st_uid == uid and sb.st_mode & 0o700 != 0o700:
            logger.debug("Temporarily setting u+wx on %s", directory)
            restore_perms.append((directory, sb.st_mode))
            directory.chmod(sb.st_mode | 0o700)

        yield
    finally:
        for path, mod in reversed(restore_perms):
            path.chmod(mod)

def rmtree_fixed(path):
    """Like :func:`shutil.rmtree` but doesn't choke on annoying permissions.

    If a directory with -w or -x is encountered, it gets fixed and deletion
    continues.
    """
    if path.is_link():
        raise OSError("Cannot call rmtree on a symbolic link")

    uid = os.getuid()
    st = path.lstat()

    if st.st_uid == uid and st.st_mode & 0o700 != 0o700:
        path.chmod(st.st_mode | 0o700)

    for entry in path.listdir():
        if stat.S_ISDIR(entry.lstat().st_mode):
            rmtree_fixed(entry)
        else:
            entry.remove()

    path.rmdir()

# Compatibility with ReproZip <= 1.0.3
check_output = subprocess.check_output

def copyfile(source, destination, CHUNK_SIZE=4096):
    """Copies from one file object to another.
    """
    while True:
        chunk = source.read(CHUNK_SIZE)
        if chunk:
            destination.write(chunk)
        if len(chunk) != CHUNK_SIZE:
            break

def download_file(url, dest, cachename=None, ssl_verify=None):
    """Downloads a file using a local cache.

    If the file cannot be downloaded or if it wasn't modified, the cached
    version will be used instead.

    The cache lives in ``~/.cache/reprozip/``.
    """
    if cachename is None:
        if dest is None:
            raise ValueError("One of 'dest' or 'cachename' must be specified")
        cachename = dest.components[-1]

    headers = {}

    if 'XDG_CACHE_HOME' in os.environ:
        cache = Path(os.environ['XDG_CACHE_HOME'])
    else:
        cache = Path('~/.cache').expand_user()
    cache = cache / 'reprozip' / cachename
    if cache.exists():
        mtime = email.utils.formatdate(cache.mtime(), usegmt=True)
        headers['If-Modified-Since'] = mtime

    cache.parent.mkdir(parents=True)

    try:
        response = requests.get(url, headers=headers,
                                timeout=2 if cache.exists() else 10,
                                stream=True, verify=ssl_verify)
        response.raise_for_status()
        if response.status_code == 304:
            raise requests.HTTPError(
                '304 File is up to date, no data returned',
                response=response)
    except requests.RequestException as e:
        if cache.exists():
            if e.response and e.response.status_code == 304:
                logger.info("Download %s: cache is up to date", cachename)
            else:
                logger.warning("Download %s: error downloading %s: %s",
                               cachename, url, e)
            if dest is not None:
                cache.copy(dest)
                return dest
            else:
                return cache
        else:
            raise

    logger.info("Download %s: downloading %s", cachename, url)
    try:
        with cache.open('wb') as f:
            for chunk in response.iter_content(4096):
                f.write(chunk)
        response.close()
    except Exception as e:  # pragma: no cover
        try:
            cache.remove()
        except OSError:
            pass
        raise e
    logger.info("Downloaded %s successfully", cachename)

    if dest is not None:
        cache.copy(dest)
        return dest
    else:
        return cache


#!usr/bin/env python
"""
First let's cut A into two parts at a random position i:

      left_A             |        right_A
A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
Since A has m elements, so there are m+1 kinds of cutting( i = 0 ~ m ). And we know: len(left_A) = i, len(right_A) = m - i . Note: when i = 0 , left_A is empty, and when i = m , right_A is empty.

With the same way, cut B into two parts at a random position j:

      left_B             |        right_B
B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]
Put left_A and left_B into one set, and put right_A and right_B into another set. Let's name them left_part and right_part :

      left_part          |        right_part
A[0], A[1], ..., A[i-1]  |  A[i], A[i+1], ..., A[m-1]
B[0], B[1], ..., B[j-1]  |  B[j], B[j+1], ..., B[n-1]
If we can ensure:

1) len(left_part) == len(right_part)
2) max(left_part) <= min(right_part)
then we divide all elements in {A, B} into two parts with equal length, and one part is always greater than the other. Then median = (max(left_part) + min(right_part))/2.

To ensure these two conditions, we just need to ensure:

(1) i + j == m - i + n - j (or: m - i + n - j + 1)
    if n >= m, we just need to set: i = 0 ~ m, j = (m + n + 1)/2 - i
(2) B[j-1] <= A[i] and A[i-1] <= B[j]
ps.1 For simplicity, I presume A[i-1],B[j-1],A[i],B[j] are always valid even if i=0/i=m/j=0/j=n . I will talk about how to deal with these edge values at last.

ps.2 Why n >= m? Because I have to make sure j is non-nagative since 0 <= i <= m and j = (m + n + 1)/2 - i. If n < m , then j may be nagative, that will lead to wrong result.

So, all we need to do is:

Searching i in [0, m], to find an object `i` that:
    B[j-1] <= A[i] and A[i-1] <= B[j], ( where j = (m + n + 1)/2 - i )
And we can do a binary search following steps described below:

<1> Set imin = 0, imax = m, then start searching in [imin, imax]

<2> Set i = (imin + imax)/2, j = (m + n + 1)/2 - i

<3> Now we have len(left_part)==len(right_part). And there are only 3 situations
     that we may encounter:
    <a> B[j-1] <= A[i] and A[i-1] <= B[j]
        Means we have found the object `i`, so stop searching.
    <b> B[j-1] > A[i]
        Means A[i] is too small. We must `ajust` i to get `B[j-1] <= A[i]`.
        Can we `increase` i?
            Yes. Because when i is increased, j will be decreased.
            So B[j-1] is decreased and A[i] is increased, and `B[j-1] <= A[i]` may
            be satisfied.
        Can we `decrease` i?
            `No!` Because when i is decreased, j will be increased.
            So B[j-1] is increased and A[i] is decreased, and B[j-1] <= A[i] will
            be never satisfied.
        So we must `increase` i. That is, we must ajust the searching range to
        [i+1, imax]. So, set imin = i+1, and goto <2>.
    <c> A[i-1] > B[j]
        Means A[i-1] is too big. And we must `decrease` i to get `A[i-1]<=B[j]`.
        That is, we must ajust the searching range to [imin, i-1].
        So, set imax = i-1, and goto <2>.
When the object i is found, the median is:

max(A[i-1], B[j-1]) (when m + n is odd)
or (max(A[i-1], B[j-1]) + min(A[i], B[j]))/2 (when m + n is even)

"""
def median(A,B):
    m,n=len(A),len(B)
    if m>n:
        A,B,m,n=B,A,n,m
    if n==0:
        raise ValueError
    imin, imax, half_len=0,m,(m+n+1)/2
    while imin<=imax:
        i = int((imin+imax)/2)
        j = int(half_len-i)
        if i<m and B[j-1]>A[i]:
            imin=i+1
        elif i>0 and A[i-1]>B[j]:
            imax=i-1
        else:
            #i is perfect
            if i==0:
                max_left=B[j-1]
            elif j==0:
                max_left=A[i-1]
            else:
                max_left=max(A[i-1],B[j-1])

            if (m+n)%2==1:
                return max_left
            if i==m:
                min_right=B[j]
            elif j==n:
                min_right=A[i]
            else:
                min_right=min(A[i],B[j])
            print(max_left,min_right)
            return (max_left+min_right)/2.0
A=[1,3]
B=[2]
print(median(A,B))


from flask import Flask, request
from flask_restful import Resource, Api
from threading import Thread
import DetectEmotionsOnVideo as Deov

app = Flask(__name__)
api = Api(app)
from flask import jsonify

thread = Thread(target=Deov.DetectEmotionsOnVideo.start_video)
thread.start()

class RunVideo(Resource):
    @staticmethod
    def get():
        url = request.args.get('url')
        if url in Deov.pendingResults:
            result = Deov.pendingResults[url]
            if result.progress == 100:
                del Deov.pendingResults[url]
            res = "{\"positionInQueue\":" + str(result.positionInQueue) + \
                  ",\"progress\":" + str(result.progress) + \
                  ",\"emotions\":" + str(result.emotions) + \
                  ",\"error\":" + str(result.error) + "}"
            return res

        result = Deov.Result(Deov.queue.qsize() + 1, 0, [])
        Deov.pendingResults[url] = result
        Deov.queue.put(url)
        res = "{\"positionInQueue\":" + str(result.positionInQueue) + \
              ",\"progress\":" + str(result.progress) + \
              ",\"emotions\":" + str(result.emotions) + \
              ",\"error\":" + str(result.error) + "}"
        return res

api.add_resource(RunVideo, '/runVideo')

if __name__ == '__main__':
    app.run(port='8080')


# -*- coding: utf-8 -*-
import logging
from pathlib import Path

from pandas import read_csv

def make_epsg_4326_latlon_dataset():
    logger = logging.getLogger(__name__)

    parties = ['PT', 'PSDB']
    min_latitude, max_latitude = -180, 180
    min_longitude, max_longitude = -90, 90

    interim_dir = Path(data_dir, 'interim').resolve()
    processed_dir = Path(data_dir, 'processed').resolve()
    latlon_dir = Path(interim_dir, 'latlon').resolve()

    epsg_4326_latlon_dir = Path(processed_dir, 'epsg_4326').resolve()
    epsg_4326_latlon_dir.mkdir(exist_ok=True)
    for party in parties:
        logger.info('starting to normalize {} series_latlon data'.format(party))

        file_path = Path(latlon_dir, party, 'latlon.csv').resolve()
        dataset = read_csv(file_path)

        dataset.latitude = (dataset.latitude -
                            min_latitude) / (max_latitude - min_latitude)
        dataset.longitude = (dataset.longitude -
                             min_longitude) / (max_longitude - min_longitude)

        party_dir = Path(epsg_4326_latlon_dir, party).resolve()
        party_dir.mkdir(exist_ok=True)
        file_path = Path(party_dir, 'latlon.csv').resolve()
        dataset.to_csv(file_path, index=False)

        logger.info('done normalizing {} series_latlon data'.format(party))

def main():
    """ Runs data processing scripts to turn brazil voting data from (../interim) into
        presidential data (saved in ../interim/presidential).
    """
    logger = logging.getLogger(__name__)

    logger.info(
        'normalizing series_latlon dataset with EPSG:4326... Saving at ../data/processed/latlon')
    make_epsg_4326_latlon_dataset()
    logger.info(
        'done normalizing series_latlon dataset with EPSG:4326... Saved at ../data/processed/latlon')

if __name__ == '__main__':
    log_fmt = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    logging.basicConfig(level=logging.INFO, format=log_fmt)

    project_dir = Path(__file__).resolve().parents[2]
    data_dir = Path(project_dir, 'data').resolve()

    main()


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

from hamcrest import assert_that, has_key, equal_to_ignoring_whitespace

from hermes.org import OrgApi

class TestOrg(object):

    def test_check_org_hierarchies_response_items(self, logged_client):
        _, result = OrgApi.hierarchies()
        assert_that(result[0], has_key('id'),
                    'Expect that result has _id_ key.')
        assert_that(result[0], has_key('children'),
                    'Expect that result has _children_ key.')
        assert_that(result[0], has_key('name'),
                    'Expect that result has _name_ key.')

    def test_check_org_hierarchies(self, logged_client, config):
        _, result = OrgApi.hierarchies()
        assert_that(result[0]['name'],
                    equal_to_ignoring_whitespace(config['org2']['name']),
                    'Expect that the org name is "%s", but was "%s".' % (
                        config['org2']['name'], result[0]['name']
                    ))
        assert_that(result[0]['children'][0]['name'],
                    equal_to_ignoring_whitespace(config['org4']['name']),
                    'Expected that org child name is "%s", but was "%s".' % (
                        config['org4']['name'],
                        result[0]['children'][0]['name']
                    ))
        assert_that(result[1]['name'],
                    equal_to_ignoring_whitespace(config['org3']['name']),
                    'Expect that the org name is "%s", but was "%s".' % (
                        config['org3']['name'], result[1]['name']
                    ))
        assert_that(result[1]['children'][0]['name'],
                    equal_to_ignoring_whitespace(config['org5']['name']),
                    'Expected that org child name is "%s", but was "%s".' % (
                        config['org5']['name'],
                        result[1]['children'][0]['name']
                    ))


import numpy as np
import itertools

# Функционал, реализующий комбинаторные задачи

# На вход:
# n_elems - количество элементов
# capacities - list с возможными емкостями контейнеров
def get_containers_by_elems(n_elems, capacities):
    capacities.sort()
    res_array = []

    for m in range(1, n_elems):
        current_min_sum = capacities[0] * m
        current_max_sum = capacities[-1] * m
        if current_min_sum > n_elems or current_max_sum < n_elems:
            continue

        res_array.append([p for p in itertools.combinations_with_replacement(capacities, r=m)])

    containers = []
    for res_series in res_array:
        for res in res_series:
            if sum(res) == n_elems:
                containers.append(res)

    # На выход - list с перечислением контейнеров, где значение - емкость контейнера
    return containers

# if __name__ == '__main__':
#     containers_list_outer = [2, 4, 6, 7]
#     n = 20
#
#     print(get_containers_by_elems(n, containers_list_outer))


import numpy as num
import csv
from sklearn.svm import SVC
import matplotlib.pyplot as plt

with open("Grand-slams-men-2013.csv") as f:
    csv_list = list(csv.reader(f))

wnr1_list = num.array([])
wnr2_list = num.array([])
result_list = num.array([])
for row in csv_list:
    if row != csv_list[0]:
        wnr1_list = num.append(wnr1_list, int(row[12]))
        wnr2_list = num.append(wnr2_list, int(row[30]))
        result_list = num.append(result_list, int(row[3]))

X = num.vstack((wnr1_list, wnr2_list)).T
Y = result_list.T

X_Train = X[0:200, :]
X_Test = X[200:, :]
Y_Train = Y[0:200]
Y_Test = Y[200:]

Y_pred_1 = num.array([])
Y_pred_2 = num.array([])
Y_pred_3 = num.array([])

reg1 = SVC(kernel = 'linear')
reg2 = SVC(kernel = 'poly')
reg3 = SVC(kernel = 'rbf')

reg1.fit(X_Train,Y_Train)
reg2.fit(X_Train, Y_Train)
reg3.fit(X_Train, Y_Train)

Y_pred_1 = reg1.predict(X_Test)
Y_pred_2 = reg2.predict(X_Test)
Y_pred_3 = reg3.predict(X_Test)

X0 = num.array([])
X1 = num.array([])
X0A = num.array([])
X0B = num.array([])
X1A = num.array([])
X1B = num.array([])
ind = num.array([], dtype="int")
ind2 = num.array([], dtype="int")
ind3 = num.array([], dtype="int")

##numpy.delete(arr, obj, axis=None)[source]
##Return a new array with sub-arrays along an axis deleted. For a one dimensional array, this returns those entries not returned by arr[obj].

for i in range(len(Y_pred_1)) :
    if Y_pred_1[i] == 0:
        ind = num.append(ind, i)

X0 = X_Test[ind]
X1 = num.delete(X_Test, ind, 0)

for i in range(len(Y_pred_2)) :
    if Y_pred_2[i] == 0 :
        ind2 = num.append(ind2, i)

X0A = X_Test[ind2]
X1A = num.delete(X_Test, ind2, 0)

for i in range(len(Y_pred_3)):
    if Y_pred_3[i] == 0:
        ind3 = num.append(ind3, i)

X0B = X_Test[ind3]
X1B = num.delete(X_Test, ind3, 0)

plt. figure()
plt.scatter(X0[:, 0],X0[:, 1], color ="pink")
plt.scatter(X1[:, 0],X1[:, 1], color ="brown")

plt.figure()
plt.scatter(X0A[:, 0],X0A[:, 1], color= "yellow")
plt.scatter(X1A[:, 0],X1A[:, 1], color ="black")

plt.figure()
plt.scatter(X0B[:, 0],X0B[:, 1], color="green")
plt.scatter(X1B[:, 0],X1B[:, 1], color="orange")
plt.show()


#!/usr/bin/env python
import optparse
import matplotlib.pyplot as plt
import pickle as pl

if __name__ == '__main__':

    parser = optparse.OptionParser(usage='usage: %prog run event ', version='%prog 1.0')
    parser.add_option('-c', '--cmap' , type='string'       , default='gray_r'      , help='palette for 2D image')
    parser.add_option('-s', '--step' , type='string'       , default='raw'         , help='step of the reconstruction: raw,1st,2nd,all,sc')

    (options, args) = parser.parse_args()

    font = {'family': 'arial',
            'color':  'black',
            'weight': 'normal',
            'size': 24,
    }

    suff = {'raw': 'oriIma',
            '1st': '1st_3D',
            '2nd': '2nd_3D',
            'all': 'all_3D',
            'sc' : 'sc_3D',
            }

    fig_handle = pl.load(open('pic_run0{run}_ev{ev}_{step}.pkl'.format(run=args[0],ev=args[1],step=suff[options.step]),'rb'))
    plt.set_cmap(options.cmap)
    if options.step=='raw':
        plt.title('Image after zero suppression', font, pad=40)
        plt.xlabel('x (pixels)', font, labelpad=20)
        plt.ylabel('y (pixels)', font, labelpad=20)
        plt.clim(vmin=-5,vmax=10)
        if int(args[0])==2317 and int(args[1])==8: ## example of split track
            plt.clim(vmin=0,vmax=25)
            csize = 160
            plt.xlim(4*240,4*(240+csize))
            plt.ylim(4*70,4*(70+csize))
        elif int(args[0])==2097 and int(args[1])==317: # ambe 60/40 (6 keV NR candidate)
            plt.clim(vmin=0,vmax=40)
            csize = 100
            plt.xlim(1200,1200+csize)
            plt.ylim(880,880+csize)
        elif int(args[0])==2097 and int(args[1])==59: # ambe 60/40 (6 keV NR candidate)
            plt.clim(vmin=0,vmax=40)
            csize = 100
            plt.xlim(660,660+csize)
            plt.ylim(1020,1020+csize)

    else:
        plt.title('Rebinned image', font, pad=40)
        plt.xlabel('x (macro-pixels)', font, labelpad=20)
        plt.ylabel('y (macro-pixels)', font, labelpad=20)
        if int(args[0])==1843: ## iron
            plt.clim(vmin=98,vmax=120)
            csize = 60
            plt.xlim(240,240+csize)
            plt.ylim(170,170+csize)
        elif int(args[0])==2317 and int(args[1])==8: ## example of split track
            plt.clim(vmin=100,vmax=110)
            csize = 160
            plt.xlim(240,240+csize)
            plt.ylim(70,70+csize)
        elif int(args[0])==2156: # cosmics
            plt.clim(vmin=98,vmax=110)

    plt.xticks(fontsize=14)
    plt.yticks(fontsize=14)

    #plt.show()

    for ext in ['pdf','png']:
        plt.savefig('pic_run0{run}_ev{ev}_{step}_paper.{ext}'.format(run=args[0],ev=args[1],step=suff[options.step],ext=ext))
    plt.gcf().clear()
    plt.close('all')


def d(num):
	add=0
	for i in range(1,num):
		if not num%i:add+=i
	return(add)
sets = []
for a in range(1,10000):
        b = d(a)
        if (d(b) == a and a!=b):
                sets.append(a)
                sets.append(b)

print(sum(set(sets)))


from collections import defaultdict
from ctree.tune import TuningDriver, Result
import itertools
import hpgmg

import numpy as np

__author__ = 'nzhang-dev'

class SmoothTuningDriver(TuningDriver):
    def __init__(self, objective):
        super(SmoothTuningDriver, self).__init__()
        self.iterators = {}
        self.best_results = defaultdict(Result)
        self.last_configs = {}
        self.best_configs = defaultdict(tuple)
        self.exhausted = defaultdict(bool)
        self.objective = objective
        self.args = None
        self.subconfig = None

    def _get_configs(self):
        if not hpgmg.finite_volume.CONFIG.tune:
            while True:
                #print hpgmg.finite_volume.CONFIG.block_hierarchy
                yield hpgmg.finite_volume.CONFIG.block_hierarchy
        self.args, self.subconfig = yield ()  # will always try this
        while True:
            #print(self.args, self.subconfig, self.iterators.keys())
            shape = self.subconfig['level'].interior_space
            #print(shape)
            if shape not in self.iterators:
                #print(shape)
                logs = tuple(int(np.log2(i)) for i in shape)
                iteration_space = [
                    (2**k for k in range(i+1)) for i in logs
                ]
                self.iterators[shape] = itertools.product(*iteration_space)
            #print(self.iterators[shape])
            try:
                result = next(self.iterators[shape])
                self.last_configs[shape] = result
            except StopIteration:
                result = self.best_configs[shape]
                self.exhausted[shape] = True
            response = yield result
            if response is not None:
                self.args, self.subconfig = response

    def is_exhausted(self):
        try:
            shape = self.subconfig['level'].interior_space
            return self.exhausted[shape]
        except TypeError:
            return False

    def report(self, *args, **kwargs):
        if self.subconfig is not None:
            shape = self.subconfig['level'].interior_space
            result = Result(*args, **kwargs)
            if self.objective.compare(result, self.best_results[shape]):
                self.best_results[shape] = result
                self.best_configs[shape] = self.last_configs[shape]
            print(self.best_configs[shape])


from baseAgent import HBDagent
import random
import minimax

class dubSeven(HBDagent):
    def __init__(self):
        self.isChecked = False
        self.player = None
        self.enemy = None

    def step(self, state):
        '''
            Input:
                state - It's a 2D array of the entire board at the current time

            This function should return :
                x - the x coordinate on the board
                y - the y coordinate on the board
                quadrant - the quadrant that the user wants to rotate
                            This is divided into 4 parts
                            1 - board[:3, :3]
                            2 - board[:3, 3:]
                            3 - board[3:, :3]
                            4 - board[3:, 3:]
                direction -  this is the direction in which the quadrant should rotate in
                            1 - anticlockwise
                           -1 - clockwise
        '''

        if (not self.isChecked):
            for i in state:
                for j in i:
                    if (j == 1):
                        self.player = 2
                        self.enemy = 1
                    else:
                        self.player = 1
                        self.enemy = 2
            self.isChecked = True
        action = minimax.getBestAction(state.tolist(), 6, self.player, self.enemy)
        x, y = action.x_coordinate, action.y_coordinate
        if (action.square_index == 2):
            quadrant = 3
        elif (action.square_index == 3):
            quadrant = 2
        else:
            quadrant = action.square_index
        if (action.direction == 'L'):
            direction = 1
        else:
            direction = -1

        return [x, y, quadrant, direction]


import csv

def add_list_to_csv(list, filename):
    new_rows_list = []
    with open(filename, 'r') as in_csv:
        reader = csv.reader(in_csv)
        for row, new_col in zip(reader, list):
            row.append(new_col)
            new_rows_list.append(row)
    in_csv.close()

    # Do the writing
    with open(filename, 'w+', newline='') as out_csv:
        writer = csv.writer(out_csv)
        for row in new_rows_list:
            writer.writerow(row)
    out_csv.close()


from googleapiclient import discovery, errors
import google_auth_oauthlib.flow
from bs4 import BeautifulSoup
import ast
import requests
import requests_html
import os
import re
import sys
import youtube_dl
import setting

# Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps
# tab of
#   https://cloud.google.com/console
# Please ensure that you have enabled the YouTube Data API for your project.
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
YOUTUBE_URL = "https://www.youtube.com"

def auth():
    youtube = discovery.build(YOUTUBE_API_SERVICE_NAME,
                              YOUTUBE_API_VERSION, developerKey=setting.DEVELOPER_KEY)
    return youtube

def getVideoData(youtube, options):

    # Call the search.list method to retrieve results matching the specified
    # query term.
    search_response = youtube.search().list(
        q=options.q,
        part="id,snippet",
        maxResults=options.max_results,
        channelId=options.channel_id,
        order='date'
    ).execute()

    videos = []

    # Add each result to the appropriate list, and then display the lists of
    # matching videos, channels, and playlists.
    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            videos.append("%s (%s)" % (search_result["snippet"]["title"],
                                       search_result["id"]["videoId"]))

    print("Videos:\n", "\n".join(videos), "\n")

    return videos

def getAudioFromVideo(video_id):

    url = YOUTUBE_URL + '/watch?v=' + video_id
    output_file = setting.TMP_FILE_DIR + "audio" + '.%(ext)s'

    ydl_opts = {
        'outtmpl': output_file,
        #'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'flac',
        }],
    }

    ydl = youtube_dl.YoutubeDL(ydl_opts)
    info_dict = ydl.extract_info(url, download=True)

    return output_file

def getCommentData(video_id):
    # Set up variables for requests.
    target_url = YOUTUBE_URL + "/watch?v=" + video_id
    dict_str = ''
    next_url = ''
    comment_data = []
    session = requests_html.HTMLSession()
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'}

    # Get the video page.
    resp = session.get(target_url)
    resp.html.render(sleep=3)

    # Retrieve the title and sanitize so it is a valid filename.
    title = resp.html.find('title')
    title = title[0].text.replace(' - YouTube', '')
    title = get_valid_filename(title)

    print(title)

    # Regex match for emoji.
    RE_EMOJI = re.compile('[\U00010000-\U0010ffff]', flags=re.UNICODE)

    # Find any live_chat_replay elements, get URL for next live chat message.
    for iframe in resp.html.find("iframe"):
        if "live_chat_replay" in iframe.attrs["src"]:
            next_url = "".join([YOUTUBE_URL, iframe.attrs["src"]])

    if not next_url:
        print("Couldn't find live_chat_replay iframe. Maybe try running again?")
        sys.exit(1)

    # TODO - We should fail fast if next_url is empty, otherwise you get error:
    # Invalid URL '': No schema supplied. Perhaps you meant http://?

    # TODO - This loop is fragile. It loops endlessly when some exceptions are hit.
    while(1):

        try:
            html = session.get(next_url, headers=headers)
            soup = BeautifulSoup(html.text, 'lxml')

            # Loop through all script tags.
            for script in soup.find_all('script'):
                script_text = str(script)
                if 'ytInitialData' in script_text:
                    dict_str = ''.join(script_text.split(" = ")[1:])

            # Capitalize booleans so JSON is valid Python dict.
            dict_str = dict_str.replace("false", "False")
            dict_str = dict_str.replace("true", "True")

            # Strip extra HTML from JSON.
            dict_str = re.sub(r'};.*\n?.*<\/script>', '}', dict_str)

            # Correct some characters.
            dict_str = dict_str.rstrip("  \n;")

            # TODO: I don't seem to have any issues with emoji in the messages.
            dict_str = RE_EMOJI.sub(r'', dict_str)

            # Evaluate the cleaned up JSON into a python dict.
            dics = ast.literal_eval(dict_str)

            # TODO: On the last pass this returns KeyError since there are no more
            # continuations or actions. Should probably just break in that case.
            continue_url = dics["continuationContents"]["liveChatContinuation"][
                "continuations"][0]["liveChatReplayContinuationData"]["continuation"]
            print('Found another live chat continuation:')
            print(continue_url)
            next_url = "https://www.youtube.com/live_chat_replay?continuation=" + continue_url

            # Extract the data for each live chat comment.
            for samp in dics["continuationContents"]["liveChatContinuation"]["actions"]:

                # 全コメは重いのでスパチャだけ抽出する
                if "replayChatItemAction" in samp and 'actions' in samp["replayChatItemAction"] and 'addChatItemAction' in samp["replayChatItemAction"]["actions"][0]:
                    if 'liveChatPaidMessageRenderer' in samp["replayChatItemAction"]["actions"][0]['addChatItemAction']['item']:
                        comment_data.append(str(samp))

        except requests.ConnectionError:
            print("Connection Error")
            continue
        except requests.HTTPError:
            print("HTTPError")
            break
        except requests.Timeout:
            print("Timeout")
            continue
        except requests.exceptions.RequestException as e:
            print(e)
            break
        except KeyError as e:
            error = str(e)
            if 'liveChatReplayContinuationData' in error:
                print('Hit last live chat segment, finishing job.')
            else:
                print("KeyError")
                print(e)
            break
        except SyntaxError as e:
            print("SyntaxError")
            print(e)
            break
            # continue #TODO
        except KeyboardInterrupt:
            break
        except Exception:
            print("Unexpected error:" + str(sys.exc_info()[0]))

    return comment_data


#
#   Copyright 2016 RIFT.IO Inc
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#

import gi
import logging

from . import core

import xml.etree.ElementTree as etree
from gi.repository import RwTopologyYang as RwTl

gi.require_version('RwYang', '1.0')
from gi.repository import RwYang

gi.require_version('RwKeyspec', '1.0')
from gi.repository.RwKeyspec import quoted_key

logger = logging.getLogger(__name__)

class SdnSim(core.Topology):
    def __init__(self):
        super(SdnSim, self).__init__()
        self._model = RwYang.Model.create_libyang()
        self._model.load_schema_ypbc(RwTl.get_schema())

    def get_network_list(self, account):
        """
        Returns the discovered network

        @param account - a SDN account

        """

        nwtop = RwTl.YangData_IetfNetwork()
        #topology_source = "/net/boson/home1/rchamart/work/topology/l2_top.xml"
        if not account.sdnsim.has_field('topology_source') or account.sdnsim.topology_source is None:
            return nwtop
        topology_source = account.sdnsim.topology_source
        logger.info("Reading topology file: %s", topology_source)
        if 'json' in topology_source:
            with open(topology_source,'r') as f:
                print("Reading static topology file")
                op_json = f.read()
                nwtop.from_json(self._model,op_json)
                for nw in nwtop.network:
                   nw.server_provided = False
                   logger.debug("...Network id %s", nw.network_id)
                   #nw_xpath = ("D,/nd:network[network-id={}]").format(quoted_key(nw.network_id))
                   #xact_info.respond_xpath(rwdts.XactRspCode.MORE,
                   #                 nw_xpath, nw)
        elif 'xml' in topology_source:
            tree = etree.parse(topology_source)
            root = tree.getroot()
            xmlstr = etree.tostring(root, encoding="unicode")

            # The top level topology object does not have XML conversion
            # Hence going one level down
            #l2nw1 = nwtop.network.add()
            #l2nw1.from_xml_v2(self._model, xmlstr)
            nwtop.from_xml_v2(self._model,xmlstr)

            logger.debug("Returning topology data imported from XML file")

        return nwtop


def solveCircuit(data):##THIS IS THE MEAT#######
    def getGroundCount(data):
        #Check to see for one ground - determine ground starting point
        for row in range(len(data.elementGrid)):
            for col in range(len(data.elementGrid[0])):
                if type(data.elementGrid[row][col]) == Ground:
                    data.GroundCount +=1
                    (data.startRow, data.startCol) = (row, col)
    def AllNonZero(data):
        nonZeroCount = 1
        for row in range(len(data.elementGrid)):
            for col in range(len(data.elementGrid[0])):
                if(data.elementGrid[row][col] != 0): nonZeroCount += 1
        return nonZeroCount
    def isLegalCircuitSeries(data):
        #Next, check for a complete connection
        (NORTH, EAST, SOUTH, WEST) = ((-1,0), (0,1), (1,0), (0,-1))
        nonZeroCount = AllNonZero(data)
        copyboolean = copy.deepcopy(data.booleanGrid)
        #we start at a ground
        for element in range(nonZeroCount-1):
            conditionalPenetration = 0
            for (drow, dcol) in (NORTH, WEST, SOUTH, EAST):
                #makes sure we don't go back in line
                if(data.elementGrid[data.startRow+drow][data.startCol+dcol] != 0 and
                    copyboolean[data.startRow+drow][data.startCol+dcol]):
                    conditionalPenetration += 1
                    copyboolean[data.startRow+drow][data.startCol+dcol] = False
                    data.startRow += drow
                    data.startCol += dcol
                    break
            #Check to see if last element is ground
            if(element == nonZeroCount-2):
                if (type(data.elementGrid[data.startRow][data.startCol]) != Ground): return False
            #check to see if every element aside from this is connected to another element
            elif(conditionalPenetration != 1): return False
        return True

        #ONLY FOR SERIES CIRCUITS!!
    def determineVoltageandCurrentSeries(data):
        if(isLegalCircuitSeries(data) and len(data.acVoltage) == 0 and len(data.acCurrent) == 0):
            data.isLegalCircuit = True
            if(len(data.dcVoltage) > 0 and len(data.dcCurrent) == 0):
                totalVoltageSupply = 0
                for dcVoltage in data.dcVoltage:
                    totalVoltageSupply += dcVoltage.voltage
                #All resistors are here
                if(len(data.resistors) > 0 and len(data.capacitors) == 0 and len(data.inductors) == 0):
                    totalResistance = 0
                    for resistor in data.resistors:
                        totalResistance += resistor.resistance
                    totalCurrent = totalVoltageSupply/totalResistance #Ohm's Law
                    for resistor in data.resistors:
                        (resistor.i0, resistor.i8) = (0.01*int(100*totalCurrent), 0.01*int(100*totalCurrent))
                        (resistor.v0, resistor.v8) = (0.01*int(100*totalCurrent*resistor.resistance),
                                                      0.01*int(100*totalCurrent*resistor.resistance))
                    for dcVoltage in data.dcVoltage:
                        (dcVoltage.i0, dcVoltage.i8) = (totalCurrent, totalCurrent)
                #All capacitors and resistors
                elif(len(data.resistors) > 0 and len(data.capacitors) > 0 and len(data.inductors)==0):
                    totalResistance = 0
                    (totalCapacitanceNumerator, totalCapacitanceDenomator) = (1, 0)
                    for resistor in data.resistors:
                        totalResistance += resistor.resistance
                    totalCurrent = totalVoltageSupply/totalResistance #Ohm's Law
                    for capacitor in data.capacitors:
                        if(len(data.capacitors) == 1): totalCapacitance = capacitor.capacitance
                        else:
                            totalCapacitanceNumerator *= capacitor.capacitance
                            totalCapacitanceDenomator += capacitor.capacitance
                            totalCapacitance = totalCapacitanceNumerator/totalCapacitanceDenomator
                    totalCharge = totalVoltageSupply*totalCapacitance
                    for resistor in data.resistors:
                        (resistor.i0, resistor.i8) = (0.01*int(100*totalCurrent), 0.00)
                        (resistor.v0, resistor.v8) = (0.01*int(100*totalCurrent*resistor.resistance), 0.00)
                    for capacitor in data.capacitors:
                        (capacitor.i0, capacitor.i8) = (0.01*int(100*totalCurrent), 0.00)
                        (capacitor.v0, capacitor.v8) = (0.00, 0.01*int(100*totalCharge/capacitor.capacitance))
                    for dcVoltage in data.dcVoltage:
                        (dcVoltage.i0, dcVoltage.i8) = (totalCurrent, 0.00)
                #All resistors and inductors
                elif(len(data.resistors) > 0 and len(data.capacitors) == 0 and len(data.inductors) > 0):
                    totalResistance = 0
                    totalInductance = 0
                    for resistor in data.resistors:
                        totalResistance += resistor.resistance
                    totalCurrent = totalVoltageSupply/totalResistance #Ohm's Law
                    for inductor in data.inductors:
                        totalInductance += inductor.inductance
                    for resistor in data.resistors:
                        (resistor.i0, resistor.i8) = (0.00, 0.01*int(100*totalCurrent))
                        (resistor.v0, resistor.v8) = (0.00, 0.01*int(100*totalCurrent*resistor.resistance))
                    for inductor in data.inductors:
                        (inductor.i0, inductor.i8) = (0.00, 0.01*int(100*totalCurrent))
                        (inductor.v0, inductor.v8) = (0.01*int(100*totalVoltageSupply*inductor.inductance/totalInductance), 0.00)
                    for dcVoltage in data.dcVoltage:
                        (dcVoltage.i0, dcVoltage.i8) = (0.00, totalCurrent)
            elif(len(data.dcCurrent) > 0 and len(data.dcVoltage) == 0):
                totalCurrent = 0
                for dcCurrent in data.dcCurrent:
                    totalCurrent += dcCurrent.current
                #All resistors are here
                if(len(data.resistors) > 0 and len(data.capacitors) == 0 and len(data.inductors) == 0):
                    totalResistance = 0
                    for resistor in data.resistors:
                        totalResistance += resistor.resistance
                    totalVoltage = totalCurrent*totalResistance #Ohm's Law
                    for resistor in data.resistors:
                        (resistor.i0, resistor.i8) = (0.01*int(100*totalCurrent), 0.01*int(100*totalCurrent))
                        (resistor.v0, resistor.v8) = (0.01*int(100*totalCurrent*resistor.resistance),
                                                      0.01*int(100*totalCurrent*resistor.resistance))
                    for dcCurrent in data.dcCurrent:
                        (dcCurrent.v0, dcCurrent.v8) = (-totalResistance*totalCurrent, -totalResistance*totalCurrent)
        else: data.isLegalCircuit = False

    getGroundCount(data)
    if(data.GroundCount == 2): determineVoltageandCurrentSeries(data)


# -*- coding: utf-8 -*-
"""
Health checks
=============

Functions performing basic health checks on xarray.DataArrays.
"""
import datetime as dt
import fnmatch

import numpy as np
import pandas as pd
import xarray as xr
from boltons.funcutils import wraps

from .options import cfcheck
from .options import CHECK_MISSING
from .options import datacheck
from .options import MISSING_METHODS
from .options import MISSING_OPTIONS
from .options import OPTIONS
from .options import register_missing_method
from .utils import ValidationError

# Dev notes
# ---------
#
# I suggest we use `check` for weak checking, and `assert` for strong checking.
# Weak checking would log problems in a log, while strong checking would raise an error.
#
# ANSWER to the above:
#   The use of set_options with a switch for raising vs warning vs logging would render these terms useless.
#
# `functools.wraps` is used to copy the docstring and the function's original name from the source
# function to the decorated function. This allows sphinx to correctly find and document functions.

# TODO: Implement pandas infer_freq in xarray with CFTimeIndex. >> PR pydata/xarray#4033
@cfcheck
def check_valid(var, key, expected):
    r"""Check that a variable's attribute has the expected value. Warn user otherwise."""

    att = getattr(var, key, None)
    if att is None:
        raise ValidationError(f"Variable does not have a `{key}` attribute.")
    if not fnmatch.fnmatch(att, expected):
        raise ValidationError(
            f"Variable has a non-conforming {key}. Got `{att}`, expected `{expected}`",
        )

@datacheck
def check_daily(var):
    r"""Assert that the series is daily and monotonic (no jumps in time index).

    A ValueError is raised otherwise."""

    t0, t1 = var.time[:2]

    # This won't work for non-standard calendars. Needs to be implemented in xarray. Comment for now
    if isinstance(t0.values, np.datetime64):
        if pd.infer_freq(var.time.to_pandas()) != "D":
            raise ValidationError("time series is not recognized as daily.")

    # Check that the first time step is one day.
    if np.timedelta64(dt.timedelta(days=1)) != (t1 - t0).data:
        raise ValidationError("time series is not daily.")

    # Check that the series does not go backward in time
    if not var.time.to_pandas().is_monotonic_increasing:
        raise ValidationError("time index is not monotonically increasing.")

def check_valid_temperature(var, units):
    r"""Check that variable is air temperature."""

    check_valid(var, "standard_name", "air_temperature")
    check_valid(var, "units", units)
    check_daily(var)

def check_valid_discharge(var):
    r"""Check that the variable is a discharge."""
    #
    check_valid(var, "standard_name", "water_volume_transport_in_river_channel")
    check_valid(var, "units", "m3 s-1")

def valid_daily_min_temperature(comp, units="K"):
    r"""Decorator to check that a computation runs on a valid temperature dataset."""

    @wraps(comp)
    def func(tasmin, *args, **kwds):
        check_valid_temperature(tasmin, units)
        check_valid(tasmin, "cell_methods", "time: minimum within days")
        return comp(tasmin, **kwds)

    return func

def valid_daily_mean_temperature(comp, units="K"):
    r"""Decorator to check that a computation runs on a valid temperature dataset."""

    @wraps(comp)
    def func(tas, *args, **kwds):
        check_valid_temperature(tas, units)
        check_valid(tas, "cell_methods", "time: mean within days")
        return comp(tas, *args, **kwds)

    return func

def valid_daily_max_temperature(comp, units="K"):
    r"""Decorator to check that a computation runs on a valid temperature dataset."""

    @wraps(comp)
    def func(tasmax, *args, **kwds):
        check_valid_temperature(tasmax, units)
        check_valid(tasmax, "cell_methods", "time: maximum within days")
        return comp(tasmax, *args, **kwds)

    return func

def valid_daily_max_min_temperature(comp, units="K"):
    r"""Decorator to check that a computation runs on valid min and max temperature datasets."""

    @wraps(comp)
    def func(tasmax, tasmin, **kwds):
        valid_daily_max_temperature(tasmax, units)
        valid_daily_min_temperature(tasmin, units)

        return comp(tasmax, tasmin, **kwds)

    return func

def valid_daily_mean_discharge(comp):
    r"""Decorator to check that a computation runs on valid discharge data."""

    @wraps(comp)
    def func(q, **kwds):
        check_valid_discharge(q)
        return comp(q, **kwds)

    return func

def valid_missing_data_threshold(comp, threshold=0):
    r"""Check that the relative number of missing data points does not exceed a threshold."""
    # TODO
    raise NotImplementedError

def check_is_dataarray(comp):
    r"""Decorator to check that a computation has an instance of xarray.DataArray
     as first argument."""

    @wraps(comp)
    def func(data_array, *args, **kwds):
        assert isinstance(data_array, xr.DataArray)
        return comp(data_array, *args, **kwds)

    return func

# This function can probably be made simpler once CFPeriodIndex is implemented.
class MissingBase:
    def __init__(self, da, freq, **indexer):
        self.null, self.count = self.prepare(da, freq, **indexer)

    @staticmethod
    def split_freq(freq):
        if freq is None:
            return "", None

        if "-" in freq:
            return freq.split("-")

        return freq, None

    @staticmethod
    def is_null(da, freq, **indexer):
        """Return a boolean array indicating which values are null."""
        from xclim.indices import generic

        selected = generic.select_time(da, **indexer)
        if selected.time.size == 0:
            raise ValueError("No data for selected period.")

        null = selected.isnull()
        if freq:
            return null.resample(time=freq)

        return null

    def prepare(self, da, freq, **indexer):
        """Prepare arrays to be fed to the `is_missing` function.

        Parameters
        ----------
        da : xr.DataArray
          Input data.
        freq : str
          Resampling frequency defining the periods defined in
          http://pandas.pydata.org/pandas-docs/stable/timeseries.html#resampling.
        **indexer : {dim: indexer, }, optional
          Time attribute and values over which to subset the array. For example, use season='DJF' to select winter
          values, month=1 to select January, or month=[6,7,8] to select summer months. If not indexer is given,
          all values are considered.

        Returns
        -------
        xr.DataArray, xr.DataArray
          Boolean array indicating which values are null, array of expected number of valid values.

        Notes
        -----
        If `freq=None` and an indexer is given, then missing values during period at the start or end of array won't be
        flagged.
        """
        from xclim.indices import generic

        null = self.is_null(da, freq, **indexer)

        pfreq, anchor = self.split_freq(freq)

        c = null.sum(dim="time")

        # Otherwise simply use the start and end dates to find the expected number of days.
        if pfreq.endswith("S"):
            start_time = c.indexes["time"]
            end_time = start_time.shift(1, freq=freq)
        elif pfreq:
            end_time = c.indexes["time"]
            start_time = end_time.shift(-1, freq=freq)
        else:
            i = da.time.to_index()
            start_time = i[:1]
            end_time = i[-1:]

        if indexer:
            # Create a full synthetic time series and compare the number of days with the original series.
            t0 = str(start_time[0].date())
            t1 = str(end_time[-1].date())
            if isinstance(da.indexes["time"], xr.CFTimeIndex):
                cal = da.time.encoding.get("calendar")
                t = xr.cftime_range(t0, t1, freq="D", calendar=cal)
            else:
                t = pd.date_range(t0, t1, freq="D")

            sda = xr.DataArray(data=np.ones(len(t)), coords={"time": t}, dims=("time",))
            st = generic.select_time(sda, **indexer)
            if freq:
                count = st.notnull().resample(time=freq).sum(dim="time")
            else:
                count = st.notnull().sum(dim="time")

        else:
            n = (end_time - start_time).days
            if freq:
                count = xr.DataArray(n.values, coords={"time": c.time}, dims="time")
            else:
                count = xr.DataArray(n.values[0] + 1)

        return null, count

    def is_missing(self, null, count, **kwargs):
        """Return whether or not the values within each period should be considered missing or not."""
        raise NotImplementedError

    @staticmethod
    def validate(**kwargs):
        """Return whether or not arguments are valid."""
        return True

    def __call__(self, **kwargs):
        if not self.validate(**kwargs):
            raise ValueError("Invalid arguments")
        return self.is_missing(self.null, self.count, **kwargs)

@register_missing_method("any")
class MissingAny(MissingBase):
    def is_missing(self, null, count, **kwargs):
        cond0 = null.count(dim="time") != count  # Check total number of days
        cond1 = null.sum(dim="time") > 0  # Check if any is missing
        return cond0 | cond1

@register_missing_method("wmo")
class MissingWMO(MissingAny):
    def __init__(self, da, freq, **indexer):
        # Force computation on monthly frequency
        if not freq.startswith("M"):
            raise ValueError
        super().__init__(da, freq, **indexer)

    def is_missing(self, null, count, nm=11, nc=5):
        import xclim.indices.run_length as rl

        # Check total number of days
        cond0 = null.count(dim="time") != count

        # Check if more than threshold is missing
        cond1 = null.sum(dim="time") >= nm

        # Check for consecutive missing values
        cond2 = null.map(rl.longest_run, dim="time") >= nc

        return cond0 | cond1 | cond2

    @staticmethod
    def validate(nm, nc):
        return nm < 31 and nc < 31

@register_missing_method("pct")
class MissingPct(MissingBase):
    def is_missing(self, null, count, tolerance=0.1):
        if tolerance < 0 or tolerance > 1:
            raise ValueError("tolerance should be between 0 and 1.")

        n = count - null.count(dim="time") + null.sum(dim="time")
        return n / count >= tolerance

    @staticmethod
    def validate(tolerance):
        return 0 <= tolerance <= 1

@register_missing_method("at_least_n")
class AtLeastNValid(MissingBase):
    def is_missing(self, null, count, n=20):
        """The result of a reduction operation is considered missing if less than `n` values are valid."""
        nvalid = null.count(dim="time") - null.sum(dim="time")
        return nvalid < n

    @staticmethod
    def validate(n):
        return n > 0

def missing_any(da, freq, **indexer):
    r"""Return whether there are missing days in the array.

    Parameters
    ----------
    da : DataArray
      Input array at daily frequency.
    freq : str
      Resampling frequency.
    **indexer : {dim: indexer, }, optional
      Time attribute and values over which to subset the array. For example, use season='DJF' to select winter values,
      month=1 to select January, or month=[6,7,8] to select summer months. If not indexer is given, all values are
      considered.

    Returns
    -------
    out : DataArray
      A boolean array set to True if period has missing values.
    """
    return MissingAny(da, freq, **indexer)()

def missing_wmo(da, freq, nm=11, nc=5, **indexer):
    r"""Return whether a series fails WMO criteria for missing days.

    The World Meteorological Organisation recommends that where monthly means are computed from daily values,
    it should considered missing if either of these two criteria are met:

      – observations are missing for 11 or more days during the month;
      – observations are missing for a period of 5 or more consecutive days during the month.

    Stricter criteria are sometimes used in practice, with a tolerance of 5 missing values or 3 consecutive missing
    values.

    Parameters
    ----------
    da : DataArray
      Input array at daily frequency.
    freq : str
      Resampling frequency.
    nm : int
      Number of missing values per month that should not be exceeded.
    nc : int
      Number of consecutive missing values per month that should not be exceeded.
    **indexer : {dim: indexer, }, optional
      Time attribute and values over which to subset the array. For example, use season='DJF' to select winter values,
      month=1 to select January, or month=[6,7,8] to select summer months. If not indexer is given, all values are
      considered.

    Returns
    -------
    out : DataArray
      A boolean array set to True if period has missing values.
    """
    missing = MissingWMO(da, "M", **indexer)(nm=nm, nc=nc)
    return missing.resample(time=freq).any()

def missing_pct(da, freq, tolerance, **indexer):
    r"""Return whether there are more missing days in the array than a given percentage.

    Parameters
    ----------
    da : DataArray
      Input array at daily frequency.
    freq : str
      Resampling frequency.
    tolerance : float
      Fraction of missing values that is tolerated.
    **indexer : {dim: indexer, }, optional
      Time attribute and values over which to subset the array. For example, use season='DJF' to select winter
      values,
      month=1 to select January, or month=[6,7,8] to select summer months. If not indexer is given, all values are
      considered.

    Returns
    -------
    out : DataArray
      A boolean array set to True if period has missing values.
    """
    return MissingPct(da, freq, **indexer)(tolerance=tolerance)

def at_least_n_valid(da, freq, n=1, **indexer):
    r"""Return whether there are at least a given number of valid values.

        Parameters
        ----------
        da : DataArray
          Input array at daily frequency.
        freq : str
          Resampling frequency.
        n : int
          Minimum of valid values required.
        **indexer : {dim: indexer, }, optional
          Time attribute and values over which to subset the array. For example, use season='DJF' to select winter
          values, month=1 to select January, or month=[6,7,8] to select summer months. If not indexer is given,
          all values are considered.

        Returns
        -------
        out : DataArray
          A boolean array set to True if period has missing values.
        """
    return AtLeastNValid(da, freq, **indexer)(n=n)

def missing_from_context(da, freq, **indexer):
    """Return whether each element of the resampled da should be considered missing according
    to the currently set options in `xclim.set_options`.

    See `xclim.set_options` and `xclim.core.options.register_missing_method`.
    """
    name = OPTIONS[CHECK_MISSING]
    cls = MISSING_METHODS[name]
    opts = OPTIONS[MISSING_OPTIONS][name]

    return cls(da, freq, **indexer)(**opts)