from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.postgres.search import SearchVector
from django.db.models import Q
from django.template import loader
from django.shortcuts import get_object_or_404, render

from .models import *
from .forms import *

def paginate(result_list, current_page, elements_per_page):
    """Generic function for paginating result lists."""

    paginator = Paginator(result_list, elements_per_page)
    try:
        result = paginator.page(current_page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        result = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        result = paginator.page(paginator.num_pages)
    return result

def index(request):
    """Site-wide index accessed when visiting the web root."""

    context = {
        'hide_navbar_search': True,
        'search_form': MainSearchForm(),
    }

    return render(request, 'directory/index.html', context)

def about(request):
    """Static page with project information."""

    about_page = get_object_or_404(StaticPage, pk='about')

    context = {
        'navbar_context': about_page.title,
        'search_form': NavbarSearchForm(),
        'static_page': about_page,
    }

    return render(request, 'directory/static_page.html', context)

def contact(request):
    """Static page with project information."""

    contact_page = get_object_or_404(StaticPage, pk='contact')

    context = {
        'navbar_context': contact_page.title,
        'search_form': NavbarSearchForm(),
        'static_page': contact_page,
    }

    return render(request, 'directory/static_page.html', context)

def index_cs(request):
    """CipherSuite overview, listing all instances stored in the database."""

    def get_cs_by_security_level(sec_level):
        if sec_level == 'secure':
            return CipherSuite.custom_filters.secure()
        elif sec_level == 'weak':
            return CipherSuite.custom_filters.weak()
        elif sec_level == 'insecure':
            return CipherSuite.custom_filters.insecure()
        else:
            return CipherSuite.objects.all()

    def filter_cs_by_tls_version(cipher_suites, version):
        if tls_version == "tls10":
            return cipher_suites.filter(tls_version__icontains='tls1.0')
        elif tls_version == "tls12":
            return cipher_suites.filter(tls_version__icontains='tls1.2')
        else:
            return cipher_suites

    def filter_cs_by_software(cipher_suites, software):
        if software == "gnutls":
            return cipher_suites.exclude(gnutls_name__iexact='')
        elif software == "openssl":
            return cipher_suites.exclude(openssl_name__iexact='')
        else:
            return cipher_suites

    def sort_cipher_suites(cipher_suites, order):
        """Sorts the given list of CipherSuite instances in a specific order."""

        # mapps GET sorting parameter to django ordering
        order_variants = {
            'auth-asc': 'auth_algorithm',
            'auth-desc': '-auth_algorithm',
            'enc-asc': 'enc_algorithm',
            'enc-desc': '-enc_algorithm',
            'hash-asc': 'hash_algorithm',
            'hash-desc': '-hash_algorithm',
            'kex-asc': 'kex_algorithm',
            'kex-desc': '-kex_algorithm',
            'name-asc': 'name',
            'name-desc': '-name',
        }

        try:
            csorder = order_variants[order]
        except KeyError:
            csorder = 'name' # default ordering

        return cipher_suites.order_by(csorder)

    # parse GET parameters
    sorting = request.GET.get('sorting', 'name-asc').strip()
    sec_level = request.GET.get('sec_level', 'all').strip()
    tls_version = request.GET.get('tls_version', 'all').strip()
    software = request.GET.get('software', 'all').strip()
    page = request.GET.get('page', 1)

    cipher_suites = filter_cs_by_software(
                        filter_cs_by_tls_version(
                            get_cs_by_security_level(sec_level), tls_version
                        ), software
                    )
    sorted_cipher_suites = sort_cipher_suites(cipher_suites, sorting)
    cipher_suites_paginated = paginate(sorted_cipher_suites, page, 15)

    context = {
        'cipher_suites': cipher_suites_paginated,
        'count': len(sorted_cipher_suites),
        'navbar_context': 'cs',
        'page_number_range': range(1, cipher_suites_paginated.paginator.num_pages + 1),
        'search_form': NavbarSearchForm(),
        'sec_level': sec_level,
        'software': software,
        'sorting': sorting,
        'tls_version': tls_version,
    }

    return render(request, 'directory/index_cs.html', context)

def index_rfc(request):
    """Rfc overview, listing all instances stored in the database."""

    def sort_rfcs(rfcs, order):
        """Sorts the given list of Rfc instances in a specific order."""

        # mapps GET sorting parameter to django ordering
        order_variants = {
            'number-asc': 'number',
            'number-desc': '-number',
            'title-asc': 'title',
            'title-desc': '-title',
        }

        try:
            rfcorder = order_variants[order]
        except KeyError:
            rfcorder = 'number' # default ordering

        return rfcs.order_by(rfcorder)

    # parse GET parameters
    sorting = request.GET.get('sorting', 'number-asc')
    page = request.GET.get('page', 1)

    rfc_list = sort_rfcs(Rfc.objects.all(), sorting)
    rfc_list_paginated = paginate(rfc_list, page, 15)

    context = {
        'navbar_context': 'rfc',
        'page_number_range': range(1, rfc_list_paginated.paginator.num_pages + 1),
        'rfc_list_paginated': rfc_list_paginated,
        'search_form': NavbarSearchForm(),
    }

    return render(request, 'directory/index_rfc.html', context)

def detail_cs(request, cs_name):
    """Detailed view of a CipherSuite instance."""

    # parse GET parameters
    prev_page = request.GET.get('prev', None)

    cipher_suite = get_object_or_404(CipherSuite, pk=cs_name)
    referring_rfc_list = cipher_suite.defining_rfcs.all()
    related_tech = [
        cipher_suite.protocol_version,
        cipher_suite.kex_algorithm,
        cipher_suite.auth_algorithm,
        cipher_suite.enc_algorithm,
        cipher_suite.hash_algorithm,
    ]

    context = {
        'cipher_suite': cipher_suite,
        'prev_page': prev_page,
        'referring_rfc_list': referring_rfc_list,
        'related_tech': related_tech,
        'search_form': NavbarSearchForm(),
    }

    return render(request, 'directory/detail_cs.html', context)

def detail_rfc(request, rfc_number):
    """Detailed view of an Rfc instance."""

    # parse GET parameters
    prev_page = request.GET.get('prev', None)

    rfc = get_object_or_404(Rfc, pk=rfc_number)
    all_rfc_status_codes = {
        'BCP': 'Best Current Practise',
        'DST': 'Draft Standard',
        'EXP': 'Experimental',
        'HST': 'Historic',
        'INF': 'Informational',
        'IST': 'Internet Standard',
        'PST': 'Proposed Standard',
        'UND': 'Undefined',
    }
    rfc_status_code = all_rfc_status_codes[rfc.status]
    defined_cipher_suites = rfc.defined_cipher_suites.all()
    related_docs = rfc.related_documents.all()

    context = {
        'defined_cipher_suites': defined_cipher_suites,
        'prev_page': prev_page,
        'related_docs': related_docs,
        'rfc': rfc,
        'rfc_status_code': rfc_status_code,
        'search_form': NavbarSearchForm(),
    }

    return render(request, 'directory/detail_rfc.html', context)

def search(request):
    """Search functionality and result page for Rfc and CipherSuite instances."""

    def search_rfcs(search_term):
        """Returns a QuerySet of all Rfc instances,
         whose title or number contains the given search term"""
        return Rfc.objects.filter(
            Q(title__icontains=search_term)|
            Q(number__icontains=search_term)
        )

    def search_cipher_suites(search_term):
        """Returns a QuerySet of all CipherSuite instances, whose name,
        algorithms or their vulnerabilities contain the given search term"""
        return CipherSuite.objects.filter(
            Q(name__icontains=search_term)|
            Q(openssl_name__icontains=search_term)|
            Q(gnutls_name__icontains=search_term)|
            Q(auth_algorithm__long_name__icontains=search_term)|
            Q(enc_algorithm__long_name__icontains=search_term)|
            Q(kex_algorithm__long_name__icontains=search_term)|
            Q(hash_algorithm__long_name__icontains=search_term)|
            Q(protocol_version__long_name__icontains=search_term)|
            Q(auth_algorithm__vulnerabilities__name__icontains=search_term)|
            Q(enc_algorithm__vulnerabilities__name__icontains=search_term)|
            Q(kex_algorithm__vulnerabilities__name__icontains=search_term)|
            Q(hash_algorithm__vulnerabilities__name__icontains=search_term)
        )

    def filter_cipher_suites(cipher_suite_list, filter):
        """Returns a list of CipherSuite instances filtered by their algorithm's vulnerabilities."""
        if filter=='insecure':
            return cipher_suite_list.filter(
                Q(protocol_version__vulnerabilities__severity='HIG')|
                Q(kex_algorithm__vulnerabilities__severity='HIG')|
                Q(enc_algorithm__vulnerabilities__severity='HIG')|
                Q(auth_algorithm__vulnerabilities__severity='HIG')|
                Q(hash_algorithm__vulnerabilities__severity='HIG')
            )
        elif filter=='weak':
            return cipher_suite_list.filter(
                Q(protocol_version__vulnerabilities__severity='MED')|
                Q(kex_algorithm__vulnerabilities__severity='MED')|
                Q(enc_algorithm__vulnerabilities__severity='MED')|
                Q(auth_algorithm__vulnerabilities__severity='MED')|
                Q(hash_algorithm__vulnerabilities__severity='MED')
            ).exclude(
                Q(protocol_version__vulnerabilities__severity='HIG')|
                Q(kex_algorithm__vulnerabilities__severity='HIG')|
                Q(enc_algorithm__vulnerabilities__severity='HIG')|
                Q(auth_algorithm__vulnerabilities__severity='HIG')|
                Q(hash_algorithm__vulnerabilities__severity='HIG')
            )
        elif filter=='secure':
            return cipher_suite_list.exclude(
                Q(auth_algorithm__vulnerabilities__severity='HIG')|
                Q(auth_algorithm__vulnerabilities__severity='MED')|
                Q(enc_algorithm__vulnerabilities__severity='HIG')|
                Q(enc_algorithm__vulnerabilities__severity='MED')|
                Q(hash_algorithm__vulnerabilities__severity='HIG')|
                Q(hash_algorithm__vulnerabilities__severity='MED')|
                Q(kex_algorithm__vulnerabilities__severity='HIG')|
                Q(kex_algorithm__vulnerabilities__severity='MED')|
                Q(protocol_version__vulnerabilities__severity='HIG')|
                Q(protocol_version__vulnerabilities__severity='MED')
            )
        else:
            return cipher_suite_list

    # parse GET parameters
    search_term = request.GET.get('q', '').strip()
    filter = request.GET.get('f', '')
    category = request.GET.get('c', 'cs')
    page = request.GET.get('p', 1)

    result_list_cs = filter_cipher_suites(search_cipher_suites(search_term), filter)
    result_list_rfc = search_rfcs(search_term)

    # distinguish results to display by category
    if category=='cs':
        active_tab = 'cs'
        result_list = result_list_cs
    else:
        active_tab = 'rfc'
        result_list = result_list_rfc

    result_list_paginated = paginate(result_list, page, 15)

    context = {
        'active_tab': active_tab,
        'category': category,
        'filter': filter,
        'full_path' : request.get_full_path(),
        'page_number_range': range(1, result_list_paginated.paginator.num_pages+1),
        'result_count_cs': len(result_list_cs),
        'result_count_rfc': len(result_list_rfc),
        'search_form': NavbarSearchForm(),
        'search_result_list': result_list_paginated,
        'search_term': search_term,
    }

    return render(request, 'directory/search.html', context)


import os

from setuptools import find_packages, setup

NAME = "bars"
DESCRIPTION = "Враппер для API электронного дневника БАРС.Web-Образование"
URL = "https://github.com/me/myproject"
AUTHOR = "crinny"
REQUIRES_PYTHON = ">=3.7.0"
VERSION = "1.0.3"

REQUIRED = ["aiohttp"]

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

try:
    with open(os.path.join(here, "README.md"), encoding="utf-8") as f:
        long_description = "\n" + f.read()
except FileNotFoundError:
    long_description = DESCRIPTION

about = {}
if not VERSION:
    project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
    with open(os.path.join(here, project_slug, "__version__.py")) as f:
        exec(f.read(), about)
else:
    about["__version__"] = VERSION

setup(
    name=NAME,
    version=about["__version__"],
    description=DESCRIPTION,
    long_description=long_description,
    long_description_content_type="text/markdown",
    author=AUTHOR,
    python_requires=REQUIRES_PYTHON,
    url=URL,
    packages=find_packages(),
    install_requires=REQUIRED,
    include_package_data=True,
    license="MIT",
    classifiers=[
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.7",
    ],
)


#!/usr/bin/env python3

import http.client
import json
import unittest
import urllib.parse
import urllib.request
from contextlib import contextmanager
from decimal import ROUND_UP, Decimal
from http import HTTPStatus
from threading import Thread
from typing import Any, Union

from toms_retail_calc import (
    TomsRetailCalcHTTPHandler,
    calculate_discount_price,
    calculate_final_price,
    calculate_tax_price,
    make_http_server,
)

class TestCalculateDiscountPrice(unittest.TestCase):
    def setUp(self):
        discounts = {
            "1000": "3",
            "5000": "5",
            "7000": "7",
            "10000": "10",
            "50000": "15",
        }
        self.discounts = {
            Decimal(key): Decimal(value) for key, value in discounts.items()
        }

    def test_calculate_discount_price(self):
        param_list = [
            (0, 0),
            (900, 900),
            (999, 999),
            (1000, Decimal("970")),
            (2500, Decimal("2425")),
            (5000, Decimal("4750")),
            (6001, Decimal("5700.95")),
            (7001, Decimal("6510.93")),
            (Decimal(10000.25), Decimal("9000.23")),
            (50000, Decimal("42500")),
            (60000, Decimal("51000")),
        ]
        for amount, expected_price_with_discount in param_list:
            with self.subTest():
                price_with_discount = calculate_discount_price(self.discounts, amount)
                price_with_discount = price_with_discount.quantize(
                    Decimal(".01"), ROUND_UP
                )
                self.assertEqual(price_with_discount, expected_price_with_discount)

class TestCalculateTax(unittest.TestCase):
    def setUp(self):
        taxes = {
            "UT": "6.85",
            "NV": "8",
            "TX": "6.25",
            "AL": "4",
            "CA": "8.25",
        }
        self.taxes = {key: Decimal(value) for key, value in taxes.items()}

    def test_calculate_tax(self):
        param_list = [
            ("UT", 10000, Decimal("10685.00")),
            ("UT", 123, Decimal("131.43")),
            ("NV", 0, 0),
            ("TX", Decimal(0.1), Decimal("0.11")),
            ("AL", 5991, Decimal("6230.64")),
            ("CA", Decimal(99.3), Decimal("107.50")),
        ]
        for state_code, amount, expected_tax_price in param_list:
            with self.subTest():
                price_with_tax = calculate_tax_price(self.taxes, state_code, amount)
                price_with_tax = price_with_tax.quantize(Decimal(".01"), ROUND_UP)
                self.assertEqual(price_with_tax, expected_tax_price)

    def test_calculate_tax_unknown_state(self):
        with self.assertRaises(KeyError):
            calculate_tax_price(self.taxes, "UNKNOWN", Decimal(100))

class TestCalculateFinalPrice(unittest.TestCase):
    def setUp(self):

        discounts = {
            "1000": "3",
            "5000": "5",
            "7000": "7",
            "10000": "10",
            "50000": "15",
        }
        self.discounts = {
            Decimal(key): Decimal(value) for key, value in discounts.items()
        }

        taxes = {
            "UT": "6.85",
            "NV": "8",
            "TX": "6.25",
            "AL": "4",
            "CA": "8.25",
        }
        self.taxes = {key: Decimal(value) for key, value in taxes.items()}

    def test_calculate_final_price(self):
        param_list = [
            (100, 1000, "AL", 50_000),
            (0, 1000, "AL", 0),
            (1, 999, "NV", 0),
            (1, 1000, "NV", 1000),
            (100, 400, "AL", 10_000),
        ]
        for product_amount, single_product_price, state_code, discount in param_list:
            with self.subTest():
                final_price = calculate_final_price(
                    self.discounts,
                    self.taxes,
                    product_amount=product_amount,
                    single_product_price=single_product_price,
                    state_code=state_code,
                )
                expected_final_price = self.calculate_expected_final_price(
                    discount=discount,
                    state_code=state_code,
                    product_amount=product_amount,
                    single_product_price=single_product_price,
                )
                self.assertEqual(final_price, expected_final_price)

    def calculate_expected_final_price(
        self, discount, state_code, product_amount, single_product_price
    ):

        discount = self.discounts.get(discount, 0)
        tax = self.taxes[state_code]
        total_price = product_amount * single_product_price

        expected_price_with_discount = total_price * (Decimal(100 - discount) / 100)

        expected_final_price = expected_price_with_discount * (Decimal(100 + tax) / 100)

        return expected_price_with_discount, expected_final_price

class TestHTTPApi(unittest.TestCase):
    def setUp(self):
        self.host = "localhost"
        self.port = 8888
        self.base_url = f"http://{self.host}:{self.port}"
        self.calc_url = "/api/v1/calc/final_and_discount_price"

    def test_ok(self):
        with self.start_server():

            price_with_discount, final_price = self.calculate_final_price(
                product_amount=100, single_product_price=3000, state_code="AL"
            )

            expected_price_with_discount = 255000
            expected_final_price = 265200

            self.assertEqual(price_with_discount, expected_price_with_discount)
            self.assertEqual(final_price, expected_final_price)

    def test_missing_required_params(self):
        with self.start_server():
            with self.get({"product_amount": 1, "single_product_price": 33}) as resp:

                self.assertEqual(resp.getcode(), HTTPStatus.UNPROCESSABLE_ENTITY)

                json_resp = json.load(resp)
                self.assertTrue(json_resp["error"] is not None)

    def test_product_amount_validation(self):
        param_list = [-1, -100, "not int"]
        with self.start_server():
            for product_amount in param_list:
                with self.subTest():
                    with self.get(
                        {
                            "product_amount": product_amount,
                            "single_product_price": 33,
                            "state_code": "TX",
                        }
                    ) as resp:

                        self.assertEqual(
                            resp.getcode(), HTTPStatus.UNPROCESSABLE_ENTITY
                        )

                        json_resp = json.load(resp)
                        self.assertTrue(json_resp["error"] is not None)

    def test_single_product_price_validation(self):
        param_list = [-1, -100, "not int"]
        with self.start_server():
            for single_product_price in param_list:
                with self.subTest():
                    with self.get(
                        {
                            "product_amount": 100,
                            "single_product_price": single_product_price,
                            "state_code": "TX",
                        }
                    ) as resp:

                        self.assertEqual(
                            resp.getcode(), HTTPStatus.UNPROCESSABLE_ENTITY
                        )

                        json_resp = json.load(resp)
                        self.assertTrue(json_resp["error"] is not None)

    def test_state_validation(self):
        with self.start_server():
            with self.get(
                {
                    "product_amount": 1,
                    "single_product_price": 33,
                    "state_code": "NOT SUPPORTED",
                }
            ) as resp:

                self.assertEqual(resp.getcode(), HTTPStatus.UNPROCESSABLE_ENTITY)

                json_resp = json.load(resp)
                self.assertTrue(json_resp["error"] is not None)

    def calculate_final_price(
        self,
        product_amount: int,
        single_product_price: Union[Decimal, int],
        state_code: str,
    ):
        with self.get(
            {
                "product_amount": product_amount,
                "single_product_price": str(single_product_price),
                "state_code": state_code,
            }
        ) as resp:
            json_resp = json.load(resp)

            self.assertTrue(json_resp["error"] is None)
            self.assertEqual(resp.getcode(), HTTPStatus.OK)
            data = json_resp["data"]
            return data["price_with_discount"], data["final_price"]

    @contextmanager
    def start_server(self):
        with make_http_server(
            HandlerClass=TomsRetailCalcHTTPHandler, port=self.port
        ) as httpd:

            t = Thread(target=httpd.serve_forever)
            t.start()

            try:
                yield
            finally:
                httpd.shutdown()
                t.join()

    @contextmanager
    def get(self, params: dict[str, Any]):
        qs = urllib.parse.urlencode(params)
        url = f"{self.calc_url}?{qs}"

        conn = http.client.HTTPConnection(self.host, self.port)
        try:
            conn.request("GET", url)
            resp = conn.getresponse()
            yield resp
        finally:
            conn.close()

if __name__ == "__main__":
    unittest.main()


# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_email_server -*-
#_____________________________________________________________________________
#
# This file is part of BridgeDB, a Tor bridge distribution system.
#
# :authors: Nick Mathewson <nickm@torproject.org>
#           Isis Lovecruft <isis@torproject.org> 0xA3ADB67A2CDB8B35
#           Matthew Finkel <sysrqb@torproject.org>
#           please also see AUTHORS file
# :copyright: (c) 2007-2014, The Tor Project, Inc.
#             (c) 2013-2014, Isis Lovecruft
# :license: see LICENSE for licensing information
#_____________________________________________________________________________

"""Servers which interface with clients and distribute bridges over SMTP."""

from __future__ import unicode_literals

import logging
import io
import time

from twisted.internet import defer
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from twisted.mail import smtp

from zope.interface import implements

from bridgedb import safelog
from bridgedb import translations
from bridgedb.crypto import getGPGContext
from bridgedb.crypto import gpgSignMessage
from bridgedb.crypto import NEW_BUFFER_INTERFACE
from bridgedb.Dist import EmailRequestedHelp
from bridgedb.Dist import EmailRequestedKey
from bridgedb.Dist import TooSoonEmail
from bridgedb.Dist import IgnoreEmail
from bridgedb.email import templates
from bridgedb.email import request
from bridgedb.parse import addr
from bridgedb.parse.addr import BadEmail
from bridgedb.parse.addr import UnsupportedDomain
from bridgedb.parse.addr import canonicalizeEmailDomain

def checkDKIM(message, rules):
    """Check the DKIM verification results header.

    This check is only run if the incoming email, **message**, originated from
    a domain for which we're configured (in the ``EMAIL_DOMAIN_RULES``
    dictionary in the config file) to check DKIM verification results for.

    :type message: :api:`twisted.mail.smtp.rfc822.Message`
    :param message: The incoming client request email, including headers.
    :param dict rules: The list of configured ``EMAIL_DOMAIN_RULES`` for the
        canonical domain which the client's email request originated from.

    :rtype: bool
    :returns: ``False`` if:
        1. We're supposed to expect and check the DKIM headers for the
           client's email provider domain.
        2. Those headers were *not* okay.
        Otherwise, returns ``True``.
    """
    if 'dkim' in rules:
        # getheader() returns the last of a given kind of header; we want
        # to get the first, so we use getheaders() instead.
        dkimHeaders = message.getheaders("X-DKIM-Authentication-Results")
        dkimHeader = "<no header>"
        if dkimHeaders:
            dkimHeader = dkimHeaders[0]
        if not dkimHeader.startswith("pass"):
            logging.info("Rejecting bad DKIM header on incoming email: %r "
                         % dkimHeader)
            return False
    return True

def createResponseBody(lines, context, clientAddress, lang='en'):
    """Parse the **lines** from an incoming email request and determine how to
    respond.

    :param list lines: The list of lines from the original request sent by the
        client.
    :type context: class:`MailContext`
    :param context: The context which contains settings for the email server.
    :type clientAddress: :api:`twisted.mail.smtp.Address`
    :param clientAddress: The client's email address which should be in the
        :header:`To:` header of the response email.
    :param str lang: The 2-5 character locale code to use for translating the
        email. This is obtained from a client sending a email to a valid plus
        address which includes the translation desired, i.e. by sending an
        email to ``bridges+fa@torproject.org``, the client should receive a
        response in Farsi.
    :rtype: None or str
    :returns: None if we shouldn't respond to the client (i.e., if they have
        already received a rate-limiting warning email). Otherwise, returns a
        string containing the (optionally translated) body for the email
        response which we should send out.
    """
    clientAddr = '@'.join([clientAddress.local, clientAddress.domain])
    t = translations.installTranslations(lang)

    bridges = None
    try:
        bridgeRequest = request.determineBridgeRequestOptions(lines)

        # The request was invalid, respond with a help email which explains
        # valid email commands:
        if not bridgeRequest.isValid():
            raise EmailRequestedHelp("Email request from %r was invalid."
                                     % clientAddr)

        # Otherwise they must have requested bridges:
        interval = context.schedule.getInterval(time.time())
        bridges = context.distributor.getBridgesForEmail(
            clientAddr,
            interval,
            context.nBridges,
            countryCode=None,
            bridgeFilterRules=bridgeRequest.filters)
    except EmailRequestedHelp as error:
        logging.info(error)
        return templates.buildWelcomeText(t, clientAddress)
    except EmailRequestedKey as error:
        logging.info(error)
        return templates.buildKeyMessage(t, clientAddress)
    except TooSoonEmail as error:
        logging.info("Got a mail too frequently: %s." % error)
        return templates.buildSpamWarning(t, clientAddress)
    except (IgnoreEmail, BadEmail) as error:
        logging.info(error)
        # Don't generate a response if their email address is unparsable or
        # invalid, or if we've already warned them about rate-limiting:
        return None
    else:
        answer = "(no bridges currently available)\r\n"
        if bridges:
            transport = bridgeRequest.justOnePTType()
            answer = "".join("  %s\r\n" % b.getConfigLine(
                includeFingerprint=context.includeFingerprints,
                addressClass=bridgeRequest.addressClass,
                transport=transport,
                request=clientAddr) for b in bridges)
        return templates.buildAnswerMessage(t, clientAddress, answer)

def generateResponse(fromAddress, clientAddress, body, subject=None,
                     messageID=None, gpgContext=None):
    """Create a :class:`MailResponse`, which acts like an in-memory
    ``io.StringIO`` file, by creating and writing all headers and the email
    body into the file-like ``MailResponse.mailfile``.

    :param str fromAddress: The rfc:`2821` email address which should be in
        the :header:`From:` header.
    :param str clientAddress: The rfc:`2821` email address which should be in
        the :header:`To:` header.
    :param str subject: The string to write to the :header:`subject` header.
    :param str body: The body of the email. If a **gpgContext** is also given,
        and that ``Context`` has email signing configured, then
        :meth:`MailResponse.writeBody` will generate and include any
        ascii-armored OpenPGP signatures in the **body**.
    :type messageID: None or str
    :param messageID: The :rfc:`2822` specifier for the :header:`Message-ID:`
        header, if including one is desirable.
    :type gpgContext: None or ``gpgme.Context``.
    :param gpgContext: A pre-configured GPGME context. See
        :meth:`~crypto.getGPGContext`.
    :rtype: :class:`MailResponse`
    :returns: A ``MailResponse`` which contains the entire email. To obtain
        the contents of the email, including all headers, simply use
        :meth:`MailResponse.read`.
    """
    response = MailResponse(gpgContext)
    response.writeHeaders(fromAddress, clientAddress, subject,
                          inReplyTo=messageID)
    response.writeBody(body)

    # Only log the email text (including all headers) if SAFE_LOGGING is
    # disabled:
    if not safelog.safe_logging:
        contents = response.readContents()
        logging.debug("Email contents:\n%s" % contents)
    else:
        logging.debug("Email text for %r created." % clientAddress)
    response.rewind()
    return response

class MailContext(object):
    """Helper object that holds information used by email subsystem."""

    def __init__(self, config, distributor, schedule):
        """DOCDOC

        :ivar str username: Reject any RCPT TO lines that aren't to this
            user. See the ``EMAIL_USERNAME`` option in the config file.
            (default: ``'bridges'``)
        :ivar int maximumSize: Reject any incoming emails longer than
            this size (in bytes). (default: 3084 bytes).
        :ivar int smtpPort: The port to use for outgoing SMTP.
        :ivar str smtpServer: The IP address to use for outgoing SMTP.
        :ivar str smtpFromAddr: Use this address in the raw SMTP ``MAIL FROM``
            line for outgoing mail. (default: ``bridges@torproject.org``)
        :ivar str fromAddr: Use this address in the email :header:`From:`
            line for outgoing mail. (default: ``bridges@torproject.org``)
        :ivar int nBridges: The number of bridges to send for each email.
        :ivar gpgContext: A ``gpgme.GpgmeContext`` (as created by
            :func:`bridgedb.crypto.getGPGContext`), or None if we couldn't
            create a proper GPGME context for some reason.

        :type config: :class:`bridgedb.persistent.Conf`
        :type distributor: :class:`bridgedb.Dist.EmailBasedDistributor`.
        :param distributor: DOCDOC
        :type schedule: :class:`bridgedb.schedule.ScheduledInterval`.
        :param schedule: DOCDOC
        """
        self.config = config
        self.distributor = distributor
        self.schedule = schedule

        self.maximumSize = 32*1024
        self.includeFingerprints = config.EMAIL_INCLUDE_FINGERPRINTS
        self.nBridges = config.EMAIL_N_BRIDGES_PER_ANSWER

        self.username = (config.EMAIL_USERNAME or "bridges")
        self.fromAddr = (config.EMAIL_FROM_ADDR or "bridges@torproject.org")
        self.smtpFromAddr = (config.EMAIL_SMTP_FROM_ADDR or self.fromAddr)
        self.smtpServerPort = (config.EMAIL_SMTP_PORT or 25)
        self.smtpServerIP = (config.EMAIL_SMTP_HOST or "127.0.0.1")

        self.domainRules = config.EMAIL_DOMAIN_RULES or {}
        self.domainMap = config.EMAIL_DOMAIN_MAP or {}
        self.canon = self.buildCanonicalDomainMap()

        self.gpgContext = getGPGContext(config)

    def buildCanonicalDomainMap(self):
        """Build a map for all email provider domains from which we will accept
        emails to their canonical domain name.

        .. note:: Be sure that ``MailContext.domainRules`` and
            ``MailContext.domainMap`` are set appropriately before calling
            this method.

        This method is automatically called during initialisation, and the
        resulting domain map is stored as ``MailContext.canon``.

        :rtype: dict
        :returns: A dictionary which maps all domains and subdomains which we
            accept emails from to their second-level, canonical domain names.
        """
        canon = self.domainMap
        for domain, rule in self.domainRules.items():
            if domain not in canon.keys():
                canon[domain] = domain
        for domain in self.config.EMAIL_DOMAINS:
            canon[domain] = domain
        return canon

class MailResponse(object):
    """Holds information for generating a response email for a request.

    .. todo:: At some point, we may want to change this class to optionally
        handle creating Multipart MIME encoding messages, so that we can
        include attachments. (This would be useful for attaching our GnuPG
        keyfile, for example, rather than simply pasting it into the body of
        the email.)

    :type _buff: unicode or buffer
    :cvar _buff: Used internally to write lines for the response email into
        the ``_mailfile``. The reason why both of these attributes have two
        possible types is for the same Python-buggy reasons which require
        :data:`~bridgedb.crypto.NEW_BUFFER_INTERFACE`.
    :type mailfile: :class:`io.StringIO` or :class:`io.BytesIO`.
    :cvar mailfile: An in-memory file for storing the formatted headers and
        body of the response email.
    """

    implements(smtp.IMessage)

    _buff = buffer if NEW_BUFFER_INTERFACE else unicode
    mailfile = io.BytesIO if NEW_BUFFER_INTERFACE else io.StringIO

    def __init__(self, gpgContext=None):
        """Create a response to an email we have recieved.

        This class deals with correctly formatting text for the response email
        headers and the response body into an instance of :cvar:`mailfile`.

        :type gpgContext: None or ``gpgme.Context``
        :param gpgContext: A pre-configured GPGME context. See
            :meth:`bridgedb.crypto.getGPGContext` for obtaining a
            pre-configured **gpgContext**. If given, and the ``Context`` has
            been configured to sign emails, then a response email body string
            given to :meth:`writeBody` will be signed before being written
            into the ``mailfile``.
        """
        self.gpgContext = gpgContext
        self.mailfile = self.mailfile()
        self.closed = False

    # These are methods and attributes for controlling I/O operations on our
    # underlying ``mailfile``.

    def close(self):
        self.mailfile.close()
        self.closed = True
    close.__doc__ = mailfile.close.__doc__

    def flush(self, *args, **kwargs): self.mailfile.flush(*args, **kwargs)
    flush.__doc__ = mailfile.flush.__doc__

    def read(self, *args, **kwargs):
        self.mailfile.read(*args, **kwargs)
    read.__doc__ = mailfile.read.__doc__

    def readline(self, *args, **kwargs):
        self.mailfile.readline(*args, **kwargs)
    readline.__doc__ = mailfile.readline.__doc__

    def readlines(self, *args, **kwargs):
        self.mailfile.readlines(*args, **kwargs)
    readlines.__doc__ = mailfile.readlines.__doc__

    def seek(self, *args, **kwargs):
        self.mailfile.seek(*args, **kwargs)
    seek.__doc__ = mailfile.seek.__doc__

    def tell(self, *args, **kwargs):
        self.mailfile.tell(*args, **kwargs)
    tell.__doc__ = mailfile.tell.__doc__

    def truncate(self, *args, **kwargs):
        self.mailfile.truncate(*args, **kwargs)
    truncate.__doc__ = mailfile.truncate.__doc__

    # The following are custom methods to control reading and writing to the
    # underlying ``mailfile``.

    def readContents(self):
        """Read the all the contents written thus far to the :cvar:`mailfile`,
        and then :meth:`seek` to return to the original pointer position we
        were at before this method was called.

        :rtype: str
        :returns: The entire contents of the :cvar:`mailfile`.
        """
        pointer = self.mailfile.tell()
        self.mailfile.seek(0)
        contents = self.mailfile.read()
        self.mailfile.seek(pointer)
        return contents

    def rewind(self):
        """Rewind to the very beginning of the :cvar:`mailfile`."""
        self.seek(0)

    def write(self, line):
        """Any **line** written to me will have ``'\r\n'`` appended to it."""
        self.mailfile.write(self._buff(line + '\r\n'))
        self.mailfile.flush()

    def writelines(self, lines):
        """Calls :meth:`write` for each line in **lines**."""
        if isinstance(lines, basestring):
            for ln in lines.split('\n'):
                self.write(ln)
        elif isinstance(lines, (list, tuple,)):
            for ln in lines:
                self.write(ln)

    def writeHeaders(self, fromAddress, toAddress, subject=None,
                     inReplyTo=None, includeMessageID=True,
                     contentType='text/plain; charset="utf-8"', **kwargs):
        """Write all headers into the response email.

        :param str fromAddress: The email address for the ``From:`` header.
        :param str toAddress: The email address for the ``To:`` header.
        :type subject: None or str
        :param subject: The ``Subject:`` header.
        :type inReplyTo: None or str
        :param inReplyTo: If set, an ``In-Reply-To:`` header will be
            generated. This should be set to the ``Message-ID:`` header from
            the client's original request email.
        :param bool includeMessageID: If ``True``, generate and include a
            ``Message-ID:`` header for the response.
        :param str contentType: The ``Content-Type:`` header.
        :kwargs: If given, the key will become the name of the header, and the
            value will become the Contents of that header.
        """
        self.write("From: %s" % fromAddress)
        self.write("To: %s" % toAddress)
        if includeMessageID:
            self.write("Message-ID: %s" % smtp.messageid())
        if inReplyTo:
            self.write("In-Reply-To: %s" % inReplyTo)
        self.write("Content-Type: %s" % contentType)
        self.write("Date: %s" % smtp.rfc822date())

        if not subject:
            subject = '[no subject]'
        if not subject.lower().startswith('re'):
            subject = "Re: " + subject
        self.write("Subject: %s" % subject)

        if kwargs:
            for headerName, headerValue in kwargs.items():
                headerName = headerName.capitalize()
                headerName = headerName.replace(' ', '-')
                headerName = headerName.replace('_', '-')
                self.write("%s: %s" % (headerName, headerValue))

        # The first blank line designates that the headers have ended:
        self.write("\r\n")

    def writeBody(self, body):
        """Write the response body into the :cvar:`mailfile`.

        If ``MailResponse.gpgContext`` is set, and signing is configured, the
        **body** will be automatically signed before writing its contents into
        the ``mailfile``.

        :param str body: The body of the response email.
        """
        if self.gpgContext:
            body, _ = gpgSignMessage(self.gpgContext, body)
        self.writelines(body)

    # The following methods implement the IMessage interface.

    def lineReceived(self, line):
        """Called when we receive a line from an underlying transport."""
        self.write(line)

    def eomRecieved(self):
        """Called when we receive an EOM.

        :rtype: :api:`twisted.internet.defer.Deferred`
        :returns: A ``Deferred`` which has already been callbacked with the
            entire response email contents retrieved from
            :meth:`readContents`.
        """
        contents = self.readContents()
        if not self.closed:
            self.connectionLost()
        return defer.succeed(contents)

    def connectionLost(self):
        """Called if we die partway through reading a message.

        Truncate the :cvar:`mailfile` to null length, then close it.
        """
        self.mailfile.truncate(0)
        self.mailfile.close()

class MailMessage(object):
    """Plugs into the Twisted Mail and receives an incoming message.

    :ivar list lines: A list of lines from an incoming email message.
    :ivar int nBytes: The number of bytes received thus far.
    :ivar bool ignoring: If ``True``, we're ignoring the rest of this message
        because it exceeded :ivar:`MailContext.maximumSize`.
    """
    implements(smtp.IMessage)

    def __init__(self, context, fromCanonical=None):
        """Create a new MailMessage from a MailContext.

        :type context: :class:`MailContext`
        :param context: The configured context for the email server.
        :type canonicalFrom: str or None
        :param canonicalFrom: The canonical domain which this message was
            received from. For example, if ``'gmail.com'`` is the configured
            canonical domain for ``'googlemail.com'`` and a message is
            received from the latter domain, then this would be set to the
            former.
        """
        self.context = context
        self.fromCanonical = fromCanonical
        self.lines = []
        self.nBytes = 0
        self.ignoring = False

    def lineReceived(self, line):
        """Called when we get another line of an incoming message."""
        self.nBytes += len(line)
        if self.nBytes > self.context.maximumSize:
            self.ignoring = True
        else:
            self.lines.append(line)
        if not safelog.safe_logging:
            logging.debug("> %s", line.rstrip("\r\n"))

    def eomReceived(self):
        """Called when we receive the end of a message."""
        if not self.ignoring:
            self.reply()
        return defer.succeed(None)

    def connectionLost(self):
        """Called if we die partway through reading a message."""
        pass

    def getIncomingMessage(self):
        """Create and parse an :rfc:`2822` message object for all ``lines``
        received thus far.

        :rtype: :api:`twisted.mail.smtp.rfc822.Message`
        :returns: A ``Message`` comprised of all lines received thus far.
        """
        rawMessage = io.StringIO()
        rawMessage.writelines([unicode('{0}\n'.format(ln)) for ln in self.lines])
        rawMessage.seek(0)
        return smtp.rfc822.Message(rawMessage)

    def getClientAddress(self, incoming):
        """Attempt to get the client's email address from an incoming email.

        :type incoming: :api:`twisted.mail.smtp.rfc822.Message`
        :param incoming: An incoming ``Message``, i.e. as returned from
            :meth:`getIncomingMessage`.
        :rtype: ``None`` or :api:`twisted.mail.smtp.Address`
        :returns: The client's email ``Address``, if it originated from a
            domain that we accept and the address was well-formed. Otherwise,
            returns ``None``.
        """
        addrHeader = None
        try: fromAddr = incoming.getaddr("From")[1]
        except (IndexError, TypeError, AttributeError): pass
        else: addrHeader = fromAddr

        if not addrHeader:
            logging.warn("No From header on incoming mail.")
            try: senderHeader = incoming.getaddr("Sender")[1]
            except (IndexError, TypeError, AttributeError): pass
            else: addrHeader = senderHeader
        if not addrHeader:
            logging.warn("No Sender header on incoming mail.")
        else:
            try:
                client = smtp.Address(addr.normalizeEmail(
                    addrHeader,
                    self.context.domainMap,
                    self.context.domainRules))
            except (UnsupportedDomain, BadEmail, smtp.AddressError) as error:
                logging.warn(error)
            else:
                return client

    def getRecipient(self, incoming):
        """Find our address in the recipients list of the **incoming** message.

        :type incoming: :api:`twisted.mail.smtp.rfc822.Message`
        :param incoming: An incoming ``Message``, i.e. as returned from
            :meth:`getIncomingMessage`.
        :rtype: str
        :return: Our address from the recipients list. If we can't find it
            return our default ``SMTP_FROM_ADDRESS`` from the config file.
        """
        address = self.context.fromAddr
        addressList = incoming.getaddrlist("To")

        try:
            ours = smtp.Address(address)
        except smtp.AddressError as error:
            logging.warn("Our address seems invalid: %r" % address)
            logging.warn(error)
        else:
            for _, addr in addressList:
                try:
                    maybeOurs = smtp.Address(addr)
                except smtp.AddressError:
                    pass
                else:
                    # See if the user looks familiar. We do a 'find' instead of
                    # compare because we might have a '+' address here.
                    if maybeOurs.local.find(ours.local) != -1:
                        return '@'.join([maybeOurs.local, maybeOurs.domain])
        return address

    def getCanonicalDomain(self, domain):
        try:
            canonical = canonicalizeEmailDomain(domain, self.context.canon)
        except (UnsupportedDomain, BadEmail) as error:
            logging.warn(error)
        else:
            return canonical

    def reply(self):
        """Reply to an incoming email. Maybe.

        If no `response` is returned from :func:`createMailResponse`, then the
        incoming email will not be responded to at all. This can happen for
        several reasons, for example: if the DKIM signature was invalid or
        missing, or if the incoming email came from an unacceptable domain, or
        if there have been too many emails from this client in the allotted
        time period.

        :rtype: :api:`twisted.internet.defer.Deferred`
        :returns: A ``Deferred`` which will callback when the response has
            been successfully sent, or errback if an error occurred while
            sending the email.
        """
        logging.info("Got an email; deciding whether to reply.")

        def _replyEB(fail):
            """Errback for a :api:`twisted.mail.smtp.SMTPSenderFactory`.

            :param fail: A :api:`twisted.python.failure.Failure` which occurred during
            the transaction.
            """
            logging.debug("_replyToMailEB() called with %r" % fail)
            error = fail.getTraceback() or "Unknown"
            logging.error(error)

        d = defer.Deferred()
        d.addErrback(_replyEB)

        incoming = self.getIncomingMessage()
        recipient = self.getRecipient(incoming)
        client = self.getClientAddress(incoming)

        if not client:
            return d

        if not self.fromCanonical:
            self.fromCanonical = self.getCanonicalDomain(client.domain)
        rules = self.context.domainRules.get(self.fromCanonical, [])
        if not checkDKIM(incoming, rules):
            return d

        clientAddr = '@'.join([client.local, client.domain])
        messageID = incoming.getheader("Message-ID", None)
        subject = incoming.getheader("Subject", None)

        # Look up the locale part in the 'To:' address, if there is one and
        # get the appropriate Translation object:
        lang = translations.getLocaleFromPlusAddr(recipient)
        logging.info("Client requested email translation: %s" % lang)

        body = createResponseBody(self.lines, self.context, client, lang)
        if not body: return d  # The client was already warned.

        response = generateResponse(self.context.fromAddr, clientAddr, body,
                                    subject, messageID, self.context.gpgContext)
        if not response: return d

        logging.info("Sending reply to %s" % client)
        factory = smtp.SMTPSenderFactory(self.context.smtpFromAddr, clientAddr,
                                         response, d, retries=0, timeout=30)
        reactor.connectTCP(self.context.smtpServerIP,
                           self.context.smtpServerPort,
                           factory)
        return d

class MailDelivery(object):
    """Plugs into Twisted Mail and handles SMTP commands."""
    implements(smtp.IMessageDelivery)

    def setBridgeDBContext(self, context):
        self.context = context
        self.fromCanonical = None

    def receivedHeader(self, helo, origin, recipients):
        """Create the ``Received:`` header for an incoming email.

        :type helo: tuple
        :param helo: The lines received during SMTP client HELO.
        :type origin: :api:`twisted.mail.smtp.Address`
        :param origin: The email address of the sender.
        :type recipients: list
        :param recipients: A list of :api:`twisted.mail.smtp.User` instances.
        """
        cameFrom = "%s (%s [%s])" % (helo[0] or origin, helo[0], helo[1])
        cameFor = ', '.join(["<{0}>".format(recp.dest) for recp in recipients])
        hdr = str("Received: from %s for %s; %s"
                  % (cameFrom, cameFor, smtp.rfc822date()))
        return hdr

    def validateFrom(self, helo, origin):
        try:
            logging.debug("ORIGIN: %r" % repr(origin.addrstr))
            canonical = canonicalizeEmailDomain(origin.domain,
                                                self.context.canon)
        except UnsupportedDomain as error:
            logging.info(error)
            raise smtp.SMTPBadSender(origin.domain)
        except Exception as error:
            logging.exception(error)
        else:
            logging.debug("Got canonical domain: %r" % canonical)
            self.fromCanonical = canonical
        return origin  # This method *cannot* return None, or it'll cause a 503.

    def validateTo(self, user):
        """If the local user that was addressed isn't our configured local user
        or doesn't contain a '+' with a prefix matching the local configured
        user: Yell.
        """
        u = user.dest.local
        # Hasplus? If yes, strip '+foo'
        idx = u.find('+')
        if idx != -1:
            u = u[:idx]
        if u != self.context.username:
            raise smtp.SMTPBadRcpt(user)
        return lambda: MailMessage(self.context, self.fromCanonical)

class MailFactory(smtp.SMTPFactory):
    """Plugs into Twisted Mail; creates a new MailDelivery whenever we get
       a connection on the SMTP port."""

    def __init__(self, context=None, **kw):
        smtp.SMTPFactory.__init__(self, **kw)
        self.delivery = MailDelivery()
        if context:
            self.setBridgeDBContext(context)

    def setBridgeDBContext(self, context):
        self.context = context
        self.delivery.setBridgeDBContext(context)

    def buildProtocol(self, addr):
        p = smtp.SMTPFactory.buildProtocol(self, addr)
        p.delivery = self.delivery
        return p

def addServer(config, distributor, schedule):
    """Set up a SMTP server for responding to requests for bridges.

    :param config: A configuration object from Main. We use these
        options::
            EMAIL_BIND_IP
            EMAIL_PORT
            EMAIL_N_BRIDGES_PER_ANSWER
            EMAIL_DOMAIN_RULES
    :type distributor: :class:`bridgedb.Dist.EmailBasedDistributor`
    :param dist: A distributor which will handle database interactions, and
        will decide which bridges to give to who and when.
    :type schedule: :class:`bridgedb.schedule.ScheduledInterval`
    :param schedule: The schedule. XXX: Is this even used?
    """
    context = MailContext(config, distributor, schedule)
    factory = MailFactory(context)

    addr = config.EMAIL_BIND_IP or ""
    port = config.EMAIL_PORT

    reactor.listenTCP(port, factory, interface=addr)

    # Set up a LoopingCall to run every 30 minutes and forget old email times.
    lc = LoopingCall(distributor.cleanDatabase)
    lc.start(1800, now=False)

    return factory


import tensorflow as tf
from abc import ABCMeta, abstractmethod
from os import path
import json
import numpy as np

import network
import data
import meta

def _decode_step(X, A, NX, NA, last_action, finished,
                 get_init, get_action,
                 random=False, n_node_types=len(meta.ATOM_TYPES), n_edge_types=len(meta.BOND_TYPES)):
    if X is None:
        init = get_init()

        if random:
            X = []
            for i in range(init.shape[0]):
                p = init[i, :]
                selected_atom = np.random.choice(np.arange(init.shape[1]), 1, p=p)[0]
                X.append(selected_atom)
            X = np.array(X, dtype=np.int32)
        else:
            X = np.argmax(init, axis=1)
        A = np.zeros((0, 3), dtype=np.int32)
        NX = last_action = np.ones([X.shape[0]], dtype=np.int32)
        NA = np.zeros([X.shape[0]], dtype=np.int32)
        finished = np.array([False, ] * X.shape[0], dtype=np.bool)

        return X, A, NX, NA, last_action, finished
    else:
        X_u = X[np.repeat(np.logical_not(finished), NX)]
        A_u = A[np.repeat(np.logical_not(finished), NA), :]
        NX_u = NX[np.logical_not(finished)]
        NA_u = NA[np.logical_not(finished)]
        last_action_u = last_action[np.logical_not(finished)]

        # conv
        mol_ids_rep = NX_rep = np.repeat(np.arange(NX_u.shape[0]), NX_u)
        rep_ids_rep = np.zeros_like(mol_ids_rep)

        if A.shape[0] == 0:
            D_2 = D_3 = np.zeros((0, 2), dtype=np.int32)
            A_u = [np.zeros((0, 2), dtype=np.int32) for _ in range(meta)]
            A_u += [D_2, D_3]
        else:
            cumsum = np.cumsum(np.pad(NX_u, [[1, 0]], mode='constant')[:-1])
            shift = np.repeat(cumsum, NA_u)
            A_u[:, :2] += np.stack([shift, ] * 2, axis=1)
            D_2, D_3 = data.get_d(A_u, X_u)
            A_u = [A_u[A_u[:, 2] == _i, :2] for _i in range(n_edge_types)]
            A_u += [D_2, D_3]

        mask = np.zeros([X_u.shape[0]], dtype=np.int32)
        last_append_index = np.cumsum(NX_u) - 1
        mask[last_append_index] = np.where(last_action_u == 1,
                                           np.ones_like(last_append_index, dtype=np.int32),
                                           np.ones_like(last_append_index, dtype=np.int32) * 2)

        decode_input = [X_u, A_u, NX_u, NX_rep, mask, mol_ids_rep, rep_ids_rep]
        append, connect, end = get_action(decode_input)

        if A.shape[0] == 0:
            max_index = np.argmax(np.reshape(append, [-1, n_node_types * n_edge_types]), axis=1)
            atom_type, bond_type = np.unravel_index(max_index, [n_node_types, n_edge_types])
            X = np.reshape(np.stack([X, atom_type], axis=1), [-1])
            NX = np.array([2, ] * len(finished), dtype=np.int32)
            A = np.stack([np.zeros(finished, dtype=np.int32),
                          np.ones(finished, dtype=np.int32),
                          bond_type], axis=1)
            NA = np.ones([finished], dtype=np.int32)
            last_action = np.ones_like(NX, dtype=np.int32)

        else:
            # process for each molecule
            append, connect = np.split(append, np.cumsum(NX_u)), np.split(connect, np.cumsum(NX_u))
            end = end.tolist()

            unfinished_ids = np.where(np.logical_not(finished))[0].tolist()
            cumsum = np.cumsum(NX)
            cumsum_a = np.cumsum(NA)

            X_insert = []
            X_insert_ids = []
            A_insert = []
            A_insert_ids = []
            finished_ids = []

            for i, (unfinished_id, append_i, connect_i, end_i) \
                    in enumerate(zip(unfinished_ids, append, connect, end)):
                if random:
                    def _rand_id(*_x):
                        _x_reshaped = [np.reshape(_xi, [-1]) for _xi in _x]
                        _x_length = np.array([_x_reshape_i.shape[0] for _x_reshape_i in _x_reshaped],
                                             dtype=np.int32)
                        _begin = np.cumsum(np.pad(_x_length, [[1, 0]], mode='constant')[:-1])
                        _end = np.cumsum(_x_length) - 1
                        _p = np.concatenate(_x_reshaped)
                        _p = _p / np.sum(_p)
                        _rand_index = np.random.choice(np.arange(_p.shape[0]), 1, p=_p)[0]
                        _p_step = _p[_rand_index]
                        _x_index = np.where(np.logical_and(_begin <= _rand_index, _end >= _rand_index))[0][0]
                        _rand_index = _rand_index - _begin[_x_index]
                        _rand_index = np.unravel_index(_rand_index, _x[_x_index].shape)
                        return _x_index, _rand_index, _p_step

                    action_type, action_index, p_step = _rand_id(append_i, connect_i, np.array([end_i]))
                else:
                    _argmax = lambda _x: np.unravel_index(np.argmax(_x), _x.shape)
                    append_id, append_val = _argmax(append_i), np.max(append_i)
                    connect_id, connect_val = _argmax(connect_i), np.max(connect_i)
                    end_val = end_i
                    if end_val >= append_val and end_val >= connect_val:
                        action_type = 2
                        action_index = None
                    elif append_val >= connect_val and append_val >= end_val:
                        action_type = 0
                        action_index = append_id
                    else:
                        action_type = 1
                        action_index = connect_id
                if action_type == 2:
                    # finish growth
                    finished_ids.append(unfinished_id)
                elif action_type == 0:
                    # append action
                    append_pos, atom_type, bond_type = action_index
                    X_insert.append(atom_type)
                    X_insert_ids.append(unfinished_id)
                    A_insert.append([append_pos, NX[unfinished_id], bond_type])
                    A_insert_ids.append(unfinished_id)
                else:
                    # connect
                    connect_ps, bond_type = action_index
                    A_insert.append([NX[unfinished_id] - 1, connect_ps, bond_type])
                    A_insert_ids.append(unfinished_id)
            if len(A_insert_ids) > 0:
                A = np.insert(A, cumsum_a[A_insert_ids], A_insert, axis=0)
                NA[A_insert_ids] += 1
                last_action[A_insert_ids] = 0
            if len(X_insert_ids) > 0:
                X = np.insert(X, cumsum[X_insert_ids], X_insert, axis=0)
                NX[X_insert_ids] += 1
                last_action[X_insert_ids] = 1
            if len(finished_ids) > 0:
                finished[finished_ids] = True
            # print finished

        return X, A, NX, NA, last_action, finished

class Visualizer(object):

    __metaclass__ = ABCMeta

    def __init__(self, model_dir):
        self.g = tf.Graph()
        with open(path.join(model_dir, 'model.json')) as f:
            self.params = json.load(f)
        with self.g.as_default():
            self._build()
            self.sess = tf.Session()
            self.saver = tf.train.Saver()
            self.saver.restore(self.sess, path.join(model_dir, 'ckpt'))
            self.g.finalize()

    @abstractmethod
    def _build(self):
        raise NotImplementedError

class GraphLM_Visualizer(Visualizer):

    def _build(self):
        self.mdl = network.GraphLM(self.params)
        self._build_in_out()

    def _build_in_out(self):
        _, self.decode_0_output = self.mdl('decode_0')
        self.decode_step_input, self.decode_step_output = self.mdl('decode_step')
        self.loss_input, self.loss_output = self.mdl('val')

    def sample(self, num_samples):
        with self.g.as_default():
            # step one
            finished = [False,]*num_samples
            def get_init():
                init = self.sess.run(self.decode_0_output)[0]
                init = np.tile(init, [num_samples, 1])
                return init
            outputs = _decode_step(X=None, A=None, NX=None, NA=None, last_action=None, finished=finished,
                                   get_init=get_init, get_action=None,
                                   n_node_types=self.mdl.n_node_types, n_edge_types=self.mdl.n_edge_types,
                                   random=False)
            X, A, NX, NA, last_action, finished = outputs

            count = 1
            while not np.all(finished) and count < 100:
                def get_action(inputs):
                    return self.sess.run(self.decode_step_output,
                                         network.get_feed_dict(self.decode_step_input,
                                                               inputs[:-2]))

                outputs = _decode_step(X, A, NX, NA, last_action, finished,
                                       get_init=None, get_action=get_action,
                                       n_node_types=self.mdl.n_node_types, n_edge_types=self.mdl.n_edge_types,
                                       random=False)
                X, A, NX, NA, last_action, finished = outputs

                count += 1

            graph_list = []

            cumsum_X_ = np.cumsum(np.pad(NX, [[1, 0]], mode='constant')).tolist()
            cumsum_A_ = np.cumsum(np.pad(NA, [[1, 0]], mode='constant')).tolist()

            for cumsum_A_pre, cumsum_A_post, \
                cumsum_X_pre, cumsum_X_post in zip(cumsum_A_[:-1], cumsum_A_[1:],
                           cumsum_X_[:-1], cumsum_X_[1:]):
                graph_list.append([X[cumsum_X_pre:cumsum_X_post], A[cumsum_A_pre:cumsum_A_post, :]])

            return graph_list

class CGraphLM_Visualizer(Visualizer):

    def _build(self):
        self.mdl = network.CGraphLM(self.params)
        self._build_in_out()

    def _build_in_out(self):
        self.decode_0_input, self.decode_0_output = self.mdl('decode_0')
        self.decode_step_input, self.decode_step_output = self.mdl('decode_step')
        self.loss_input, self.loss_output = self.mdl('val')

    def sample(self, num_samples, c):
        if len(c.shape) < 2:
            c = c[np.newaxis, :]
            c = np.tile(c, [num_samples, 1])

        with self.g.as_default():
            # step one
            finished = [False,]*num_samples
            def get_init():
                init = self.sess.run(self.decode_0_output,
                                     {self.decode_0_input[0]:c})[0]
                return init
            outputs = _decode_step(X=None, A=None, NX=None, NA=None, last_action=None, finished=finished,
                                   get_init=get_init, get_action=None,
                                   n_node_types=self.mdl.n_node_types, n_edge_types=self.mdl.n_edge_types,
                                   random=False)
            X, A, NX, NA, last_action, finished = outputs

            count = 1
            while not np.all(finished) and count < 100:
                def get_action(inputs):
                    c_u = c[np.logical_not(finished), :]
                    return self.sess.run(self.decode_step_output,
                                         network.get_feed_dict(self.decode_step_input,
                                                               inputs + [c_u, ]))

                outputs = _decode_step(X, A, NX, NA, last_action, finished,
                                       get_init=None, get_action=get_action,
                                       n_node_types=self.mdl.n_node_types, n_edge_types=self.mdl.n_edge_types,
                                       random=False)
                X, A, NX, NA, last_action, finished = outputs

                count += 1

            graph_list = []

            cumsum_X_ = np.cumsum(np.pad(NX, [[1, 0]], mode='constant')).tolist()
            cumsum_A_ = np.cumsum(np.pad(NA, [[1, 0]], mode='constant')).tolist()

            for cumsum_A_pre, cumsum_A_post, \
                cumsum_X_pre, cumsum_X_post in zip(cumsum_A_[:-1], cumsum_A_[1:],
                           cumsum_X_[:-1], cumsum_X_[1:]):
                graph_list.append([X[cumsum_X_pre:cumsum_X_post], A[cumsum_A_pre:cumsum_A_post, :]])

            return graph_list


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

from flask.ext.restful import Resource, marshal_with, reqparse
from flask.ext.login import current_user
from flask.globals import request

from common.mods import db
from common.fields import message_field
from common.models import User, Message, MessageTimestamp, Notification
from common.service_configs import MESSAGE_ROW
from common.api_errors import UserNotFound
from utils import get_page_offset, api_login_required, get_now_mysql_datetime

__author__ = "Philgyu,Seong"
__email__ = "philgyu.seong@gluvi.co"

KEY_ROW = "row"
KEY_PAGE = "page"

KEY_MESSAGE = "message"

LOCATION_FORM = "form"

class MessageApi(Resource):
    def __init__(self):
        self.post_parser = reqparse.RequestParser()
        self.post_parser.add_argument(KEY_MESSAGE, location=LOCATION_FORM)

    @marshal_with(message_field, "messages")
    def get(self, user_id):
        row = int(request.args.get(KEY_ROW, default=MESSAGE_ROW))
        page = int(request.args.get(KEY_PAGE, default=1))

        id1 = current_user.id
        id2 = user_id

        messages = Message.query.\
            filter("(sender_id=:id1 and reciever_id=:id2) or (sender_id=:id3 and reciever_id=:id4)").\
            params(id1=id1, id2=id2, id3=id2, id4=id1).offset(get_page_offset(page, row)).limit(row).all()

        return messages

    @api_login_required
    def post(self, user_id):
        sender_id = current_user.id
        reciever_id = user_id

        args = self.post_parser.parse_args()

        user = User.query.filter(User.id == reciever_id).first()

        if user is None:
            raise UserNotFound

        message = args[KEY_MESSAGE]

        new_message = Message(sender_id=sender_id, reciever_id=reciever_id, message=message,
                              created_at=get_now_mysql_datetime())

        timestamp = MessageTimestamp.query.filter(MessageTimestamp.user_id == reciever_id).first()

        notification = Notification(user_id=reciever_id, sender_id=sender_id, code=1, message="메세지가 도착하였습니다",
                                    created_at=get_now_mysql_datetime())

        db.session.add(notification)

        if timestamp is None:
            timestamp = MessageTimestamp(user_id=reciever_id, timestamp=get_now_mysql_datetime())
            db.session.add(timestamp)
        else:
            timestamp.timestamp = get_now_mysql_datetime()
            db.session.merge(timestamp)

        db.session.add(new_message)
        db.session.commit()

        return {}


# Dominator
#
# given an array of integers arr containing N many elements, find the index of element
# that is the dominator of the array
#
# The definition of dominator is the element that contains more than half of the total elements
#
# [3,4,3,2,3,-1,3,3] --> the dominator is 3 because 5 are present in 8 total --> return index 0
#
# if solution doesn't exist, return -1
#
# input
#   - list of integers
#
# output
#   - integer (is the index of dominator)
#
# constraints / known
#   - dominator is the element with count more than half of the length of array
#
#   - the size of N is in [0 ... 100,000]
#   - element is of range [-INT.MAX, INT.MAX]
#
# cases
#   1. len(A) == 0 --> return - 1
#   2. len(A) == 1 --> return 0
#   3. len(A) != 1
#
# Brainstorming
#
# []
#
# [1]
#
# [3,3,1,1,2,2] --> is not dominator --> return -1
#
# [3,4,3,2,3,-1,3,3] {} --> [3,4,3,2,3,-1,3,3] {3: 5, 4: 1, 2: 1, -1: 1} --> 3 has count > half of array (4) --> return 0
#  x                                          x
#
class Solution:
    def solve(self, A):
        # 1. if len(A) == 0, return -1
        if len(A) == 0:
            return -1
        # 2. if len(A) == 1, return 0
        if len(A) == 1:
            return 0

        # 3. count frequency of each number and store in dictionary 'number_frequency'
        number_frequency= self.get_number_frequency(A)

        # 4. get dominator
        dominator = self.get_dominator(number_frequency, A)

        # 5. if dominator doesn't exist, return -1
        if dominator == None:
            return -1

        # 6. find earliest index of the domninator
        index = 0
        while index < len(A):
            if A[index] == dominator:
                return index
            index += 1

        # 7. return index
        return -1
        # Time complexity O(N), spatial complexity O(N)

    def get_number_frequency(self, A):
        number_frequency = {}

        for number in A:
            if number in number_frequency:
                number_frequency[number] += 1
            else:
                number_frequency[number] = 1

        return number_frequency

    def get_dominator(self, number_frequency, A):

        for key in number_frequency.keys():

            is_dominator = number_frequency[key] > (len(A) // 2)
            if is_dominator:
                return key

        return None

if __name__ == '__main__':
    case_1 = [3,4,3,2,3,-1,3,3]
    case_2 = []
    case_3 = [1]
    case_4 = [1,1,1,1,2,2,2,2]

    expected_1 = 0
    expected_2 = -1
    expected_3 = 0
    expected_4 = -1

    solution_1 = Solution().solve(case_1)
    solution_2 = Solution().solve(case_2)
    solution_3 = Solution().solve(case_3)
    solution_4 = Solution().solve(case_4)

    assert expected_1 == solution_1
    assert expected_2 == solution_2
    assert expected_3 == solution_3
    assert expected_4 == solution_4


import requests, json, hashlib, time, logging

class MasheryV2:

    def __init__(self, protocol, api_host):
        self.protocol = protocol
        self.api_host = api_host

    def get(self, site_id, apikey, secret, resource, params):
        resourceEndpoint = '/v2/rest'
        url = str(self.protocol) + '://' + str(self.api_host) + resourceEndpoint + '/' + str(site_id) + resource + '?apikey=' + apikey + '&sig=' + self.hash(apikey, secret) + params
        response = requests.get(url)
        if (response.status_code == 200):
            return response.json()
        else:
            return None

    def post(self, site_id, apikey, secret, payload):
        resourceEndpoint = '/v2/json-rpc'
        headers = {"Content-type": "application/json"}
        url = str(self.protocol) + '://' + str(self.api_host) + resourceEndpoint + '/' + str(site_id) + '?apikey=' + apikey + '&sig=' + self.hash(apikey, secret)

        response = requests.post(url, headers=headers, data=payload)
        responseJson = response.json()

        if (response.status_code == 200):
          return responseJson
        else:
          raise ValueError(responseJson['error'])

    def hash(self, apikey, secret):
        authHash = hashlib.md5();
        temp = str.encode(str(apikey) + str(secret) + repr(int(time.time())))
        authHash.update(temp)
        return authHash.hexdigest()


class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        if len(needle) == 0:
            return 0

        for haystack_index in xrange(len(haystack) - len(needle) + 1):
            for needle_index in xrange(len(needle)):
                if haystack[haystack_index + needle_index] != needle[needle_index]:
                    break

                if needle_index == len(needle) - 1:
                    return haystack_index
        return -1


#!/usr/bin/env python3

from optim.CentraleSupelec import CSP
import sys

n = int(sys.argv[1])
N = range(n)
P = CSP([set(range(n)) for x in N])
for y in N:
    for x in range(y):
        P.addConstraint(x, y, {(u, v) for u in N for v in N if u - v not in [x-y, 0, y-x]})
# P.maintain_arc_consistency()

count = 0
for sol in P.solve():
    count += 1
    if count == 1:
        if n < 20:   # sinon la grille est trop grande
            for i in N:
                for j in N:
                    if sol[i] == j:
                        print("# ", end='')
                    else:
                        print(". ", end='')
                print()
        else:
            print(sol)
    else:
        break

print("Nodes explored : %i " % P.nodes)
if count == 0:
    print("There is no solution")
elif count == 1:
    print("The solution is unique")
else:
    print("The solution is not unique")


import sys
import os
import random

os.system('cls')

# defines the game logic
def logic(p1, p2):
    # checks if the input is valid or not
    if not ((p1 == "1" or p1 == "2" or p1 == "3") and (p2 == "1" or p2 == "2" or p2 == "3")):
        print("something went wrong")
        main()
    else:
        if p1 == p2:
            print("that's a tie ...")

        if p1 == "1":
            if p2 == "2":
                print("player2 wins!!")
            elif p2 == "3":
                print("player1 wins!!")

        if p1 == "2":
            if p2 == "1":
                print("player1 wins!!")
            elif p2 == "3":
                print("player2 wins!!")

        if p1 == "3":
            if p2 == "1":
                print("player2 wins!!")
            elif p2 == "2":
                print("player1 wins!!")

# deletes the previous line
def deleteLine():
    sys.stdout.write('\x1b[1A')
    sys.stdout.write('\x1b[2K')

# asks for play again or exit
def exit():
    playAgain = input(" \ndo you want to play again ? y/n \n")
    if playAgain == "y":
        os.system('cls')
        main()
    elif playAgain == "n":
        sys.exit()
    else:
        exit()

def main():

    print("""
    ###################
    ##               ##
    ##  1. rock      ##
    ##  2. paper     ##
    ##  3. scissors  ##
    ##               ##
    ###################
    """)

    # asks for game mode
    gameMode = input("multiplayer or single player? m/s \n").lower()

    if gameMode == "m":

        # gets palyers moves
        player1 = input("player 1 choose your move number:  ").lower()
        deleteLine()
        player2 = input("player 2 choose your move number:  ").lower()
        deleteLine()

        logic(player1, player2)
        exit()

    elif gameMode == "s":
        # gets palyers moves
        player1 = input("player 1 choose your move number:  ").lower()
        deleteLine()
        player2 = str(random.randint(1, 3))
        print(f"Computer move was: {player2}")

        logic(player1, player2)
        exit()
    else:
        os.system('cls')
        main()

# runs the program
main()


import random

size = 200000
table = [[0 for i in range(3)] for i in range(size)]

for i in range(size):
	f1 = random.uniform(-1, 1)
	f2 = random.uniform(-1, 1)
	if f1 ** 2 + f2 ** 2 <= 1:
		Class = 1
	else:
		Class = -1
	if 0.75 < f1 ** 2 + f2 ** 2 < 1.25:
		if random.random() <= .15:
			Class *= -1
	if Class == 1:
		table[i][0] = "+1"
	else:
		table[i][0] = "-1"
	table[i][1] = f1
	table[i][2] = f2

with open('TestCircleSoftTraining.txt', 'w') as training, open('TestCircleSoftTestingAll.txt', 'w') as testingall, open('TestCircleSoftTestingSignal.txt', 'w') as testingsignal, open('CircleSoftTestingBackground.txt', 'w') as testingbackground:
	for i in range(0, size, 2):
		training.write(table[i][0] + " 1:" + str(table[i][1]) + " 2:" + str(table[i][2]) + "\n")
	for i in range(1, size, 2):
		testingall.write(table[i][0] + " 1:" + str(table[i][1]) + " 2:" + str(table[i][2]) + "\n")
		if table[i][0] == "+1":
			testingsignal.write(table[i][0] + " 1:" + str(table[i][1]) + " 2:" + str(table[i][2]) + "\n")
		else:
			testingbackground.write(table[i][0] + " 1:" + str(table[i][1]) + " 2:" + str(table[i][2]) + "\n")


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import json
import tornado.web
from modules.smtp.smtp_manage import SmtpManage

class SmtpTestHandler(tornado.web.RequestHandler):
    """
    """
    def post(self):
        """
        """
        try:
            config = json.loads(self.request.body)
            SmtpManage().send_test_email(config['emails'])
        except Exception as ex:
            self.write({'errmsg': str(ex)})
            self.set_status(500)


#!/usr/bin/env python3
#
# Copyright (c) 2019 Ableton AG, Berlin. All rights reserved.
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file.

"""A script to download JAR file dependencies for run_codenarc.py."""

import argparse
import logging
import os
import zipfile

import requests

def download_file(url, output_dir, force=False):
    """Download a file from a URL to the download directory."""
    output_file_name = url.split('/')[-1]
    output_file_path = os.path.join(output_dir, output_file_name)

    if force:
        try:
            os.remove(output_file_path)
        except FileNotFoundError:
            pass
    elif os.path.exists(output_file_path):
        logging.debug('%s already exists, skipping download', output_file_path)
        return output_file_path

    logging.debug('Downloading %s to %s', url, output_file_path)
    response = requests.get(url, stream=True)

    response.raise_for_status()

    with open(output_file_path, mode='wb') as output_file:
        for chunk in response.iter_content(chunk_size=256):
            output_file.write(chunk)

    logging.info('Downloaded %s', output_file_name)
    return output_file_path

def fetch_jars(args):
    """Fetch JAR file dependencies."""
    if not os.path.exists(args.output_dir):
        os.mkdir(args.output_dir)

    jar_urls = [
        (
            'https://github.com/CodeNarc/CodeNarc/releases/download'
            f'/v{args.codenarc_version}/CodeNarc-{args.codenarc_version}.jar'
        ),
        (
            'https://github.com/dx42/gmetrics/releases/download'
            f'/v{args.gmetrics_version}/GMetrics-{args.gmetrics_version}.jar'
        ),
        (
            f'https://repo1.maven.org/maven2/org/slf4j/slf4j-api/{args.slf4j_version}'
            f'/slf4j-api-{args.slf4j_version}.jar'
        ),
        (
            f'https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/{args.slf4j_version}'
            f'/slf4j-simple-{args.slf4j_version}.jar'
        ),
    ]

    for url in jar_urls:
        verify_jar(download_file(url, args.output_dir, args.force))

def parse_args():
    """Parse arguments from the command line."""
    arg_parser = argparse.ArgumentParser()

    arg_parser.add_argument(
        '--codenarc-version', help='Version of CodeNarc to download.', required=True
    )

    arg_parser.add_argument(
        '--gmetrics-version', help='Version of GMetrics to download.', required=True
    )

    arg_parser.add_argument(
        '--slf4j-version', help='Version of SLF4J to download.', required=True
    )

    arg_parser.add_argument(
        '-f',
        '--force',
        action='store_true',
        help='Download JAR files regardless of whether or not they already exist.',
    )

    arg_parser.add_argument(
        '-o',
        '--output-dir',
        default=os.path.abspath(os.path.curdir),
        help='Directory to save JAR files to.',
    )

    arg_parser.add_argument(
        '-v', '--verbose', action='store_true', help='Show verbose output.'
    )

    args = arg_parser.parse_args()

    log_level = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(level=log_level)

    return args

def verify_jar(file_path):
    """Verify that a file is a valid JAR file."""
    logging.debug('Verifying %s', file_path)
    with zipfile.ZipFile(file_path, 'r') as jar_file:
        if 'META-INF/MANIFEST.MF' not in jar_file.namelist():
            raise ValueError(f'{file_path} does not appear to be a valid JAR')

if __name__ == '__main__':
    fetch_jars(parse_args())


from pony.orm import *

@db_session
def populateTables(db):
    #class SignalPath
    db.SignalPath(name='Default')

    #class Component
    db.Oscillator(name='Oscillator1',
                  in1='Frequency', in2='Frequency',
                  out1='Oscillator2', out2='Oscillator2')

    db.Oscillator(name='Oscillator2',
                  in1='Oscillator1', in2='Oscillator1',
                  out1='Oscillator3', out2='Oscillator3')

    db.Oscillator(name='Oscillator3',
                  in1='Oscillator2', in2='Oscillator2',
                  out1='Envelope', out2='Envelope')

    db.Envelope(name='Envelope',
                in1='Oscillator3', in2='Oscillator3',
                out1='Filter', out2='Filter')

    db.Filter(name='Filter',
              in1='Envelope', in2='Envelope',
              out1='Volume', out2='Volume')

    db.Volume(name='Volume',
                  in1='Filter', in2='Filter')

    db.Frequency(name='Frequency',
                  out1='Oscillator1', out2='Oscillator1')

    #set up default signal path
    signalPath = [
                ['Default', 'Oscillator1'],
                ['Default', 'Oscillator2'],
                ['Default', 'Filter'],
                ['Default', 'Envelope'],
                ['Default', 'Volume'],
                ['Default', 'Frequency']
              ]
    for sp in signalPath:
        db.SignalPathComponents(
            signalPath = select(s for s in db.SignalPath if s.name == sp[0]).get(),
            component = select(c for c in db.Component if c.name == sp[1]).get()
        )

    #program startup settings [name, boolval, intval, floatval, stringval]
    init = [
            ['DisplayToolTips', True,   0,  0,  ''],
            ['UserName',        False,  0,  0,  ''],
            ['FilePath',        False,  0,  0,  ''],
            ['FileName',        False,  0,  0,  '']
           ]
    for i in init:
        db.Init(name=i[0], boolVal=i[1], intVal=i[2],
                    floatVal=i[3], stringVal=i[4])

    '''
    chain = [
             ['GammaSine',      1,  True],
             ['GammaBiquad',    2,  True]
            ]
    for ch in chain:
        db.Chain(modId=select(c for c in db.Module if c.name == ch[0]).get(),
                        modPos=ch[1], isActive=ch[2])
    '''

    '''
    for md in module:
        db.Module(name=md[0], classNameId=
                select(c for c in db.ClassName if c.name == md[1]).get())

    #User-defined module attributes [moduleId, attributeId, attributeVal]
    modattr = [
               ['GammaSine', 'freq',
                 select(f.defaultVal for f in db.ClassAttribute if f.name == 'freq').get()],
               ['GammaSine', 'phase',
                 select(f.defaultVal for f in db.ClassAttribute if f.name == 'phase').get()],
               ['GammaSine', 'mul',
                 select(f.defaultVal for f in db.ClassAttribute if f.name == 'mul').get()],
               ['GammaSine', 'add',
                 select(f.defaultVal for f in db.ClassAttribute if f.name == 'add').get()]
              ]
    for ma in modattr:
        db.ModAttributes(moduleId=select(m for m in db.Module if m.name == ma[0]).get(),
                         attributeId=select(a for a in db.ClassAttribute if a.name == ma[1]).get(),
                         attributeVal=ma[2])
    '''


from typing import List

def sortColors(nums: List[int]) -> None:
    n = len(nums)
    p0, p2 = 0, n - 1
    i = 0
    while i <= p2:
        while i <= p2 and nums[i] == 2:
            nums[i], nums[p2] = nums[p2], nums[i]
            p2 -= 1
        if nums[i] == 0:
            nums[i], nums[p0] = nums[p0], nums[i]
            p0 += 1
        i += 1

arr = [2,0,2,1,1,0]
sortColors(arr)
print(arr)


from ...models.account import Account
from ...models.attribute import Attribute
from ..db_utils import Value
from .. import database_connector as db_conn

attributes_table_name = 'attribute'
character_attributes_table_name = 'character_attributes'

def get_attributes_for_character(character_id: int) -> list:
    attribute_list = []
    command_portions = []
    command_portions.append('SELECT attribute.attribute_id, attribute.world_id, attribute.name, attribute.description, attribute.type, attribute.negative_enabled, character_attributes.value')
    command_portions.append('FROM character_attributes')
    command_portions.append('INNER JOIN attribute ON character_attributes.attribute_id = attribute.attribute_id')
    command_portions.append('WHERE character_attributes.character_id = %s'%character_id)
    command = ' '.join(command_portions)

    try:
        db_list = db_conn.custom_select(command, False)

        if len(db_list) > 0:
            for i in range(0, len(db_list)):
                attr_id, world_id, name, description, attr_type, negative_enabled, value = db_list[i]
                attribute_list.append(Attribute(attr_id, name, description, attr_type, negative_enabled, value))
    except TypeError as e:
        print(e)
        pass

    return attribute_list

def insert_attributes_for_character(character_id: int, attributes: list):
    fields = ['character_id', 'attribute_id', 'value']

    if len(attributes) > 0:
        for i in range(0, len(attributes)):
            attribute = attributes[i]
            values = [Value(character_id), Value(attribute.id), Value(attribute.value)]
            db_conn.insert(character_attributes_table_name, fields, values)

def get_attributes_for_world(world_id: int) -> list:
    fields = ['world_id']
    values = [Value(world_id)]
    attribute_list = []

    try:
        db_list = db_conn.select(attributes_table_name, fields, values)

        if len(db_list) > 0:
            for i in range(0, len(db_list)):
                attr_id, world_id, name, description, attr_type, negative_enabled, default_value = db_list[i]
                attribute_list.append(Attribute(attr_id, name, description, attr_type, negative_enabled, default_value))
    except TypeError as e:
        print(e)
        pass

    return attribute_list

def create_attribute(world_id: int, attribute: Attribute) -> int:
    negative_enabled = 1
    if attribute.negative_enabled:
        negative_enabled = 0

    fields = ['world_id', 'name', 'description', 'type', 'negative_enabled', 'default_value']
    values = [
        Value(world_id),
        Value(attribute.name),
        Value(attribute.description),
        Value(attribute.attr_type),
        Value(negative_enabled),
        Value(attribute.value)
    ]
    return db_conn.insert(attributes_table_name, fields, values)


import sys

def readfile(filename):
	f = open(filename)
	chunk = f.read()
	linelist = chunk.split("\r\n")
	linelist.pop()
	l = sorted(linelist)
	f.close()
	return l

def writefile(filename, linelist):
	s = ""
	for line in linelist :
		# print line
		s = s + line + "\r\n"
	filepath = filename + ".sortr"
	f = open(filepath, "w")
	f.write(s)
	f.close()

def sort(filename) :
	f = open(filename)
	chunk = f.read()
	linelist = chunk.split("\r\n")
	linelist.pop()
	l = sorted(linelist)
	s = ""
	wf = open(filename + ".sorted", "w")
	for word in l :
		# s = s + word + "\r\n"
		wf.write(word + "\r\n")
	# wf.write(s)

if __name__ == '__main__':
	filename = sys.argv[1]
	# l = readfile(filename)
	# writefile(filename, l)
	sort(filename)


#!/usr/bin/env python

from __future__ import print_function

import unittest
import os
import shlex
import subprocess as sp

def run_test_model(rundir):

    root_dir = os.getcwd()

    atm_exe = os.path.join(root_dir, 'build/test_atm/atm.exe')
    ice_exe = os.path.join(root_dir, 'build/test_ice/ice.exe')
    ocn_exe = os.path.join(root_dir, 'build/test_ocn/ocn.exe')

    os.chdir(os.path.join('tests', rundir))

    mpirun = '/usr/local/bin/mpirun'
    cmd = '{} -np 1 {} : -np 1 {} : -np 1 {}'.format(mpirun, atm_exe, ice_exe, ocn_exe)

    r = sp.call(shlex.split(cmd))

    return r

class TestBasicTransfer(unittest.TestCase):

    def setUp(self):
        self.root_dir = os.getcwd()

    def tearDown(self):
        os.chdir(self.root_dir)

    def test_itruns(self):
        """
        Test that the models run.
        """

        r = run_test_model('transfer')
        assert(r == 0)

    def test_passthrough(self):
        """
        Test that data is passed through correctly.

        No interpolation is done.
        """
        pass

class TestTools(unittest.TestCase):

    def setUp(self):
        self.root_dir = os.getcwd()

    def tearDown(self):
        os.chdir(self.root_dir)

    def test_make_restarts(self):
        """
        Generate restarts.
        """

        tools_dir = os.path.join(self.root_dir, 'tools')
        test_dir = os.path.join(self.root_dir, 'tests/transfer')

        atm_nml = os.path.join(test_dir, 'atm.nml')
        ice_nml = os.path.join(test_dir, 'ice.nml')
        ocn_nml = os.path.join(test_dir, 'ocn.nml')

        restart_files = ['atm_to_ice_restart.nc', 'ice_to_atm_restart.nc',
                         'ice_to_ocn_restart.nc', 'ocn_to_ice_restart.nc']

        restarts = [os.path.join(tools_dir, r) for r in restart_files]
        # Ensure that they don't already exist.
        assert(not any([os.path.exists(r) for r in restarts]))

        # Run script.
        os.chdir(tools_dir)

        cmd = './make_initial_restarts.py --atm_nml {} --ice_nml {} --ocn_nml {}'.format(atm_nml, ice_nml, ocn_nml)
        r = sp.call(shlex.split(cmd))

        # Ensure that they do exist.
        assert(all([os.path.exists(r) for r in restarts]))

        # Delete them.
        map(os.remove, restarts)

if __name__ == '__main__':
    unittest.main()


import numpy as np

def sigmoid(z):
    '''
    J = SIGMOID(z) computes the sigmoid of z.
    '''

    return 1./(1+np.exp(-z))

def costFunction(theta,X,y):
    '''
    J = COSTFUNCTION(theta, X, y) computes the cost of using theta as the
    parameter for logistic regression
    '''

    m,n = X.shape
    h = sigmoid(np.dot(X,theta))
    J = (-np.dot(y.T,np.log(h))-np.dot((1-y).T,np.log(1-h)))*1/m

    return J

def gradient(theta,X,y):
    '''
    grad = gradient(theta, X, y)
    computes the gradient of the cost w.r.t. to the parameters.
    '''

    m,n = X.shape
    y = np.matrix(y)
    X = np.matrix(X)
    theta = np.matrix(theta)
    h = sigmoid(X.dot(theta.T))
    grad = (X.T*(h-y))/m

    return grad

def accuracy(X,y,theta):

    m,n = X.shape
    theta = theta.reshape(n,1)
    prob = sigmoid( X.dot(theta))

    return np.mean(np.array( prob>0.5, dtype='int_') == y)*100

def costFunctionReg(theta, X, y, lambda_):
    '''
    J = COSTFUNCTIONREG(theta, X, y, lambda) computes the cost of using
    theta as the parameter for regularized logistic regression and the
    gradient of the cost w.r.t. to the parameters.
    '''

    m,n = X.shape
    X = np.array(X)
    y = np.array(y)
    h = sigmoid(X.dot(theta))
    reg = lambda_/(2.*m)*(theta.T.dot(theta))
    J = -(y.T.dot(np.log(h))+(1-y).T.dot(np.log(1.-h)))*1./m + reg

    return J

def gradientReg(theta, X, y, lambda_):
    '''
    grad = gradient(theta, X, y, lambda) computes the
    gradient of the cost w.r.t. to the parameters.
    '''

    m,n = X.shape
    y = np.matrix(y)
    X = np.matrix(X)
    theta = np.matrix(theta)
    h = sigmoid(X.dot(theta.T))
    grad = X.T*(h-y)

    z = np.zeros(n)
    z[1:]=1
    reg = lambda_*(np.multiply(theta,z).T)

    grad = (grad + reg)/m

    return grad

def accuracyReg(theta,X,y):

    theta = np.matrix(theta)
    X = np.matrix(X)
    predict = (sigmoid(X*(theta.T))>=0.5).astype(int)

    return np.asscalar(sum(predict == y)/float(len(y)))*100


# -*- coding: UTF-8 -*-
# Module  : py
# Description :请求
# Author  : Wujj
# Date    : 2018/07/10
# Version : 1.0
import requests
import json

"""
params  dict
 """
def toGetUrl(url,params={}):
    r = requests.get(url=url, params=params)
    if r.status_code==200:
        return r.content
    else:
        return ""

def toPostUrl(url,params={},**kwargs):
    headers = {
        'Content-Type': 'application/json; charset=UTF-8',
        "Accept": "application/json"}
    if "contentType" in kwargs:
        headers['Content-Type']=kwargs["contentType"]
    r = requests.post(url=url,headers=headers, json=params)
    if r.status_code==200:
        return {
            "status":"OK",
            "data":json.loads(r.content)
        }
    else:
        return {
            "status":"Err",
            "data":r.content
        }


from datetime import date
from os.path import join

import numpy as np
from geoalchemy2.shape import to_shape
from geoalchemy2.types import Raster
from shapely.geometry import Point
from sqlalchemy import func

from snowexsql.conversions import raster_to_rasterio
from snowexsql.data import ImageData
from snowexsql.functions import ST_PixelAsPoint
from snowexsql.upload import UploadRaster

from .sql_test_base import DBSetup, TableTestBase, pytest_generate_tests

class TestRaster(TableTestBase):
    """
    Test uploading a raster
    """

    # Class to use to upload the data
    UploaderClass = UploadRaster

    # Positional arguments to pass to the uploader class
    args = [join('be_gm1_0328', 'w001001x.adf')]

    # Keyword args to pass to the uploader class
    kwargs = {'type': 'dem', 'epsg': 26912, 'description': 'test'}

    # Always define this using a table class from data.py and is used for ORM
    TableClass = ImageData

    # First filter to be applied is count_attribute == data_name
    count_attribute = 'type'

    # Define params which is a dictionary of test names and their args
    params = {
        'test_count': [dict(data_name='dem', expected_count=1)],
        'test_value': [dict(data_name='dem', attribute_to_check='description',
                            filter_attribute='id', filter_value=1,
                            expected='test')],
        'test_unique_count': [dict(data_name='dem', attribute_to_count='id',
                                   expected_count=1)]
    }

class TestTiledRaster(DBSetup):
    """
    A class to test common operations and features of tiled raster in the DB
    """

    def setup_class(self):
        """
        Setup the database one time for testing
        """
        super().setup_class()
        # Positional arguments to pass to the uploader class
        args = [join(self.data_dir, 'uavsar', 'uavsar_utm.amp1.real.tif')]

        # Keyword args to pass to the uploader class
        kwargs = {'type': 'insar', 'epsg': 26912, 'description': 'test', 'tiled': True}
        # Upload two rasters (next two each other)
        u = UploadRaster(*args, **kwargs)
        u.submit(self.session)

    def test_tiled_raster_count(self):
        """
        Test two rasters uploaded
        """
        records = self.session.query(ImageData.id).all()
        assert len(records) == 4

    def test_tiled_raster_size(self):
        """
        Tiled raster should be 500x500 in most cases (can be smaller to fit domains)
        """
        rasters = self.session.query(func.ST_AsTiff(ImageData.raster)).all()
        datasets = raster_to_rasterio(self.session, rasters)

        for d in datasets:
            assert d.width <= 500
            assert d.height <= 500

    def test_raster_point_retrieval(self):
        """
        Test we can retrieve coordinates of a point from the database
        """

        # Get the first pixel as a point
        records = self.session.query(ST_PixelAsPoint(ImageData.raster, 1, 1)).limit(1).all()
        received = to_shape(records[0][0])
        expected = Point(748446.1945536422, 4328702.971977075)

        # Convert geom to shapely object and compare
        np.testing.assert_almost_equal(received.x, expected.x, 6)
        np.testing.assert_almost_equal(received.y, expected.y, 6)

    def test_raster_union(self):
        """
        Test we can retrieve coordinates of a point from the database
        """

        # Get the first pixel as a point
        rasters = self.session.query(func.ST_AsTiff(func.ST_Union(ImageData.raster, type_=Raster))).all()
        assert len(rasters) == 1

    def test_raster_union2(self):
        """
        Test we can retrieve coordinates of a point from the database
        """

        # Get the first pixel as a point
        merged = self.session.query(func.ST_Union(ImageData.raster, type_=Raster)).filter(
            ImageData.id.in_([1, 2])).all()
        assert len(merged) == 1

    def test_date_accessed(self):
        """
        Tests that the date accessed is auto assigned on upload
        """
        result = self.session.query(ImageData.date_accessed).limit(1).all()
        assert type(result[0][0]) is date


from chapter_2.linked_list_utils import Node, llol

def check_ll_palindrome(h: Node):
    sl_len = -1
    fst_len = -1

    if not h:
        return True

    slp = h
    fstp = h
    stack = []
    while fstp:
        sl_len += 1
        fst_len += 2
        stack.append(slp.val)

        slp = slp.next
        fstp = fstp.next

        if fstp:
            fstp = fstp.next
            if not fstp:
                fst_len += 1

    if fst_len > 0 and fst_len % 2:
        stack.pop()

    print(f"Stack is {stack}, slp is {slp}")

    while slp:
        if slp.val != stack.pop():
            return False
        slp = slp.next

    return not stack

if __name__ == "__main__":

    exs = [
        [],
        [4],
        [1, 2, 2],
        [1, 2, 3, 4],
        [1, 1, 2, 1],
        [1, 1, 1],
        [1, 1, 1, 1],
        [1, 2, 0, 2, 1],
    ]

    for ex in exs:
        h_ex = llol(ex) if ex else None
        print(f"Result for {ex} is {check_ll_palindrome(h_ex)}")
        print("-"*50)