from pyramid.httpexceptions import HTTPNotFound

from nextgisweb.env import _
from nextgisweb.lib import dynmenu as dm

from nextgisweb.pyramid import JSONType, viewargs
from nextgisweb.resource import (
    DataScope,
    DataStructureScope,
    Resource,
    ResourceScope,
    Widget,
    resource_factory,
)
from nextgisweb.resource.extaccess import ExternalAccessLink
from nextgisweb.resource.view import resource_sections

from .extension import FeatureExtension
from .interface import IFeatureLayer
from .ogrdriver import MVT_DRIVER_EXIST

class FeatureLayerFieldsWidget(Widget):
    interface = IFeatureLayer
    operation = ("update",)
    amdmod = "ngw-feature-layer/FieldsWidget"

PD_READ = DataScope.read
PD_WRITE = DataScope.write

PDS_R = DataStructureScope.read
PDS_W = DataStructureScope.write

PR_R = ResourceScope.read

@viewargs(renderer="react")
def feature_browse(request):
    request.resource_permission(PD_READ)
    request.resource_permission(PDS_R)

    readonly = not request.context.has_permission(PD_WRITE, request.user)

    return dict(
        obj=request.context,
        title=_("Feature table"),
        entrypoint="@nextgisweb/feature-layer/feature-grid",
        props=dict(id=request.context.id, readonly=readonly, editOnNewPage=True),
        maxwidth=True,
        maxheight=True,
    )

@viewargs(renderer="mako")
def feature_show(request):
    request.resource_permission(PD_READ)
    request.resource_permission(PDS_R)

    feature_id = int(request.matchdict["feature_id"])

    ext_mid = dict()
    for k, ecls in FeatureExtension.registry._dict.items():
        if hasattr(ecls, "display_widget"):
            ext_mid[k] = ecls.display_widget

    return dict(
        obj=request.context,
        title=_("Feature #%d") % feature_id,
        feature_id=feature_id,
        ext_mid=ext_mid,
    )

@viewargs(renderer="react")
def feature_update(request):
    request.resource_permission(PD_WRITE)

    feature_id = int(request.matchdict["feature_id"])

    return dict(
        obj=request.context,
        entrypoint="@nextgisweb/feature-layer/feature-editor",
        props=dict(resourceId=request.context.id, featureId=feature_id),
        title=_("Feature #%d") % feature_id,
        maxheight=True,
    )

def field_collection(request) -> JSONType:
    request.resource_permission(PDS_R)
    return [f.to_dict() for f in request.context.fields]

@viewargs(renderer="mako")
def test_mvt(request):
    return dict()

@viewargs(renderer="react")
def export(request):
    if not request.context.has_export_permission(request.user):
        raise HTTPNotFound()
    return dict(
        obj=request.context,
        title=_("Save as"),
        props=dict(id=request.context.id),
        entrypoint="@nextgisweb/feature-layer/export-form",
        maxheight=True,
    )

@viewargs(renderer="react")
def export_multiple(request):
    return dict(
        obj=request.context,
        title=_("Save as"),
        props=dict(multiple=True, pick=True),
        entrypoint="@nextgisweb/feature-layer/export-form",
        maxheight=True,
    )

class MVTLink(ExternalAccessLink):
    title = _("MVT Vector Tiles")
    help = _(
        "The Mapbox Vector Tile is an efficient encoding for map data into vector tiles that can be rendered dynamically."
    )
    docs_url = "docs_ngweb_dev/doc/developer/misc.html#mvt-vector-tiles"

    interface = IFeatureLayer

    @classmethod
    def is_applicable(cls, obj, request) -> bool:
        return MVT_DRIVER_EXIST and super().is_applicable(obj, request)

    @classmethod
    def url_factory(cls, obj, request) -> str:
        return (
            request.route_url("feature_layer.mvt", _query=dict(resource=obj.id))
            + "&z={z}&x={x}&y={y}"
        )

def setup_pyramid(comp, config):
    config.add_route(
        "feature_layer.export_multiple",
        r"/resource/export_multiple",
    ).add_view(export_multiple)

    config.add_route(
        "feature_layer.feature.browse",
        r"/resource/{id:uint}/feature/",
        factory=resource_factory,
    ).add_view(feature_browse)

    config.add_route(
        "feature_layer.feature.show",
        r"/resource/{id:uint}/feature/{feature_id:int}",
        factory=resource_factory,
    ).add_view(feature_show, context=IFeatureLayer)

    config.add_route(
        "feature_layer.feature.update",
        r"/resource/{id:uint}/feature/{feature_id:int}/update",
        factory=resource_factory,
    ).add_view(feature_update, context=IFeatureLayer)

    config.add_route(
        "feature_layer.field",
        r"/resource/{id:uint}/field/",
        factory=resource_factory,
    ).add_view(field_collection, context=IFeatureLayer)

    config.add_view(
        export,
        route_name="resource.export.page",
        context=IFeatureLayer,
    )

    config.add_route("feature_layer.test_mvt", "/feature_layer/test_mvt").add_view(test_mvt)

    # Layer menu extension
    class LayerMenuExt(dm.DynItem):
        def build(self, args):
            if IFeatureLayer.providedBy(args.obj):
                yield dm.Label("feature_layer", _("Features"))

                if args.obj.has_permission(PD_READ, args.request.user):
                    if args.obj.has_permission(PDS_R, args.request.user):
                        yield dm.Link(
                            "feature_layer/feature-browse",
                            _("Table"),
                            lambda args: args.request.route_url(
                                "feature_layer.feature.browse", id=args.obj.id
                            ),
                            important=True,
                            icon="mdi-table-large",
                        )

                if args.obj.has_export_permission(args.request.user):
                    yield dm.Link(
                        "feature_layer/export",
                        _("Save as"),
                        lambda args: args.request.route_url(
                            "resource.export.page", id=args.obj.id
                        ),
                        icon="material-save_alt",
                    )

    Resource.__dynmenu__.add(LayerMenuExt())

    @resource_sections(title=_("Attributes"))
    def resource_section_fields(obj):
        return IFeatureLayer.providedBy(obj)


import unittest
import numpy as np
from ..particles import PointDipole, PointDipoleList
from .test_particles import H2
from .util import iterize
from nose.plugins.attrib import attr

@attr(speed='fast')
class MultiDipoleTest(unittest.TestCase):

    def setUp(self):
        self.He2 = PointDipoleList(iter("""AA
2 2 0 1
1 0 0  0 0 6.429866513469e-01
2 0 0 52 0 6.429866513469e-01
""".split("\n")))
        pass

        self.h2o = PointDipoleList(iterize(
"""AU
3 1 0 1
1  0.000  0.000  0.698 -0.703 -0.000 0.000 -0.284 4.230
2 -1.481  0.000 -0.349  0.352  0.153 0.000  0.127 1.089
3  1.481  0.000 -0.349  0.352 -0.153 0.000  0.127 1.089
4  0.000  0.000  0.000  0.000  0.000 0.000  0.000 0.000"""
        ))

    def test_empty_list(self):
        empty_list = PointDipoleList()
        self.assertEqual(len(empty_list), 0)

    def test_append_list(self):
        initial_list = PointDipoleList()
        initial_list.append(PointDipole())
        self.assertEqual(len(initial_list), 1)

    def test_append_wroing(self):
        initial_list = PointDipoleList()
        def myappend(input_list, arg):
            input_list.append(arg)
        self.assertRaises(TypeError, myappend, initial_list, None)

    def test_he2(self):
        alpha_he2 = self.He2.alpha()
        ref_alpha = np.diag(
            [1.285972432811e+00, 1.285972432811e+00,1.285975043401e+00]
            )
        np.allclose(alpha_he2, ref_alpha)

    def test_h2o_number(self):
        self.assertEqual(len(self.h2o), 3)

    def test_h2o_charge(self):
        #round-off error in this example
        self.assertAlmostEqual(self.h2o.total_charge(), 0., places=2)

    def test_h2o_dipole_tensor_zero(self):
        Tij = self.h2o.dipole_coupling_tensor()
        zeromat = np.zeros((3,3))
        self.assertTrue (np.allclose(Tij[0, :, 0, :], zeromat))
        self.assertTrue (np.allclose(Tij[1, :, 1, :], zeromat))
        self.assertTrue (np.allclose(Tij[2, :, 2, :], zeromat))
        self.assertFalse(np.allclose(Tij[0, :, 1, :], zeromat))
        self.assertFalse(np.allclose(Tij[0, :, 2, :], zeromat))
        self.assertFalse(np.allclose(Tij[1, :, 2, :], zeromat))

    def test_dipole_tensor_values_01(self):
        x = 1.481
        y = 0
        z = 0.698 + 0.349
        r_5 = (x*x + y*y + z*z)**2.5
        T01 = self.h2o.dipole_coupling_tensor()[0, :, 1, :]
        T01xx =  (2*x*x - y*y - z*z) / r_5
        self.assertAlmostEqual(T01xx, T01[0,0])
        T01xy =  0.0
        self.assertAlmostEqual(T01xy, T01[0,1])
        T01xz =  3*x*z  / r_5
        self.assertAlmostEqual(T01xz, T01[0,2])
        T01yy = (2*y*y - x*x - z*z) / r_5
        self.assertAlmostEqual(T01yy, T01[1,1])
        T01yz =  0.0
        self.assertAlmostEqual(T01yz, T01[1,2])
        T01zz = (2*z*z - x*x - y*y) / r_5
        self.assertAlmostEqual(T01zz, T01[2,2])

    def test_dipole_tensor_values_02(self):
        x = -1.481
        y = 0
        z = 0.698 + 0.349
        r_5 = (x*x + y*y + z*z)**2.5
        T02 = self.h2o.dipole_coupling_tensor()[0, :, 2, :]
        T02xx =  (2*x*x - y*y - z*z) / r_5
        self.assertAlmostEqual(T02xx, T02[0,0])
        T02xy =  0.0
        self.assertAlmostEqual(T02xy, T02[0,1])
        T02xz =  3*x*z  / r_5
        self.assertAlmostEqual(T02xz, T02[0,2])
        T02yy = (2*y*y - x*x - z*z) / r_5
        self.assertAlmostEqual(T02yy, T02[1,1])
        T02yz =  0.0
        self.assertAlmostEqual(T02yz, T02[1,2])
        T02zz = (2*z*z - x*x - y*y) / r_5
        self.assertAlmostEqual(T02zz, T02[2,2])

    def test_dipole_tensor_values_12(self):
        x = - 2.962
        y = 0
        z = 0
        r_5 = (x*x + y*y + z*z)**2.5
        T12 = self.h2o.dipole_coupling_tensor()[1, :, 2, :]
        T12xx =  (2*x*x - y*y - z*z) / r_5
        self.assertAlmostEqual(T12xx, T12[0,0])
        T12xy =  0.0
        self.assertAlmostEqual(T12xy, T12[0,1])
        T12xz =  3*x*z  / r_5
        self.assertAlmostEqual(T12xz, T12[0,2])
        T12yy = (2*y*y - x*x - z*z) / r_5
        self.assertAlmostEqual(T12yy, T12[1,1])
        T12yz =  0.0
        self.assertAlmostEqual(T12yz, T12[1,2])
        T12zz = (2*z*z - x*x - y*y) / r_5
        self.assertAlmostEqual(T12zz, T12[2,2])

    def test_static_charge_energy(self):
        charges = PointDipoleList.from_string("""AU
2 0 0
1 0 0 0 1.0
2 0 0 1 1.0
"""
)
        charges.update_local_fields()
        E = charges.total_energy()
        self.assertEqual(E, 1.)

    def test_static_dipole_energy(self):
        dipoles = PointDipoleList.from_string("""AU
2 1 0
1 0 0 0 0.0 .0 .0 .3
2 0 0 1 0.0 .0 .0 .3
"""
)

    def test_static_charge_dipole_energy(self):
        charged_dipoles = PointDipoleList.from_string("""AU
2 1 0
1 0 0 0 4.0 .0 .0 .0
2 0 0 1 0.0 .1 .2 .3
"""
)

        E_ref = - 4.0*0.3
        charged_dipoles.update_local_fields()
        E = charged_dipoles.total_energy()
        self.assertAlmostEqual(E, E_ref)

    def test_static_dipole_moment(self):
        h2o_dimer = PointDipoleList.from_string("""AU
2 1 0 0
1 0.0 0.0 -0.2249058930 0. 0. 0. -0.81457755
2 0.0 0.0  4.775094107  0. 0. 0. -0.81457755
""")
        np.testing.assert_almost_equal(
            h2o_dimer.total_static_dipole_moment(), (0,0,-0.81457755*2)
            )

    def test_induced_dipole_moment_for_nonpolarizable_system(self):
        h2o_dimer = PointDipoleList.from_string("""AU
2 1 0 0
1 0.0 0.0 -0.2249058930 0. 0. 0. -0.81457755
2 0.0 0.0  4.775094107  0. 0. 0. -0.81457755
""")
        np.testing.assert_almost_equal(
            h2o_dimer.total_induced_dipole_moment(), (0,0,0)
            )

    def test_total_dipole_moment_for_nonpoliarizable_system(self):
        h2o_dimer = PointDipoleList.from_string("""AU
2 1 0 0
1 0.0 0.0 -0.2249058930 0. 0. 0. -0.81457755
2 0.0 0.0  4.775094107  0. 0. 0. -0.81457755
""")
        np.testing.assert_almost_equal(
            h2o_dimer.total_dipole_moment(), (0,0,-0.81457755*2)
            )

    def test_static_dipole_moment_for_polarizable_system(self):
        h2o_dimer = PointDipoleList.from_string("""AU
2 1 2 0
1 0.0 0.0 -0.2249058930 0. 0. 0. -0.81457755 0 0 0 0 0 5.22710462524
2 0.0 0.0  4.775094107  0. 0. 0. -0.81457755 0 0 0 0 0 5.22710462524
""")
        h2o_dimer.solve_scf()
        np.testing.assert_almost_equal(
            h2o_dimer.total_static_dipole_moment(), (0,0,-0.81457755*2)
            )

    def test_induced_dipole_moment_for_polarizable_system(self):
        h2o_dimer = PointDipoleList.from_string("""AU
2 1 2 0
1 0.0 0.0 -0.2249058930 0. 0. 0. -0.81457755 0 0 0 0 0 5.22710462524
2 0.0 0.0  4.775094107  0. 0. 0. -0.81457755 0 0 0 0 0 5.22710462524
""")
        h2o_dimer.solve_scf()
        np.testing.assert_almost_equal(
            h2o_dimer.total_induced_dipole_moment(), (0,0,-0.1486869)
            )


def get_input():
    with open("input/15.txt", "r") as f:
        lines = f.readlines()
    return [c[:-1] for c in lines]

def solve(data):
    sensors = []
    beacons = []
    for line in data:
        _, s, b = line.split("at ")
        s_x, s_y = s.split(": ")[0].split(", ")
        sensor = int(s_x.split("=")[-1]), int(int(s_y.split("=")[-1]))
        sensors.append(sensor)
        b_x, b_y = b.split(", ")
        beacon = int(b_x.split("=")[-1]), int(int(b_y.split("=")[-1]))
        beacons.append(beacon)

    upper = 4000000
    for y in range(upper):
        x = 0
        while x < (upper):
            changed = False
            for s, b in zip(sensors, beacons):
                dist = abs(s[0] - b[0]) + abs(s[1] - b[1])
                if abs(s[0]-x) + abs(s[1]-y) < dist:
                    x += (dist - abs(s[1]-y) - abs(s[0]-x))
                    changed = True
                elif abs(s[0]-x) + abs(s[1]-y) == dist:
                    x += 1
                    changed = True
            if not changed:
                print("Part 2:", x * 4000000 + y)
                return

if __name__ == "__main__":
    import time

    start = time.time()
    solve(get_input())
    print("Time:", time.time() - start)


from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse, reverse_lazy
from django.views import generic
from django.utils import timezone
from django.db.models import Count
from django.db import transaction

from .models import Choice, Question, Company
from .forms import CreateForm, CHOICE_FORM_SET
from .tasks import survey_submit_email_task, process_form_task
import json

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        '''
        Return the last five published questions.
        (not including future questions)
        '''
        return Question.objects.annotate(
            choice_count=Count('choice')).filter(
                choice_count__gt=0,
                pub_date__lte=timezone.now()
                ).order_by('-pub_date')[:5]

class CreateQuestionView(generic.edit.CreateView):
    '''
    Some code from this tutorial to aid in adding choices to question view
    https://dev.to/zxenia/django-inline-formsets-with-class-based-views-and-crispy-forms-14o6
    Additional elements adapted in:
        - forms.py
        - create.html
        - custom_layout.py
        - formset.html
    as well as imported jquery.formset.js for dynamic choice additions
    '''
    model = Question
    template_name = 'polls/create.html'
    # fields = '__all__'
    form_class = CreateForm
    success_url = reverse_lazy('polls:index')

    def get_context_data(self, **kwargs):
        data = super(CreateQuestionView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['choices'] = CHOICE_FORM_SET(self.request.POST)
        else:
            data['choices'] = CHOICE_FORM_SET()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        choices = context['choices']
        if choices.is_valid():
            with transaction.atomic():
                self.object = form.save()
                choices.instance = self.object
                choices.save()
        else:
            return super(CreateQuestionView, self).form_invalid(form)
        survey_submit_email_task.delay(form.cleaned_data['question_text'],
                                       form.cleaned_data['company'].name)
        process_form_task.delay(self.object.id)
        return super(CreateQuestionView, self).form_valid(form)

class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

    def get_queryset(self):
        '''
        Excludes any questions not published
        '''
        return Question.objects.filter(pub_date__lte=timezone.now())

class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'

def graph_view(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    choice = []
    for ch in question.choice_set.all():
        choice.append(ch)
    return render(request, 'polls/graph.html', {'question': question,
                                                'choices': choice})

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice."
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse(
            'polls:results', args=(question.id,)))

def autocomplete_model(request):
    if request.is_ajax():
        co = request.GET.get('query', '')
        search_cos = Company.objects.filter(name__istartswith=co)
        results = []
        for company in search_cos:
            inp = {}
            inp['value'] = company.name
            inp['data'] = company.id
            results.append(inp)
        resp = {"suggestions": results}
        data = json.dumps(resp)
    else:
        data = 'fail'
    mimetype = 'json'
    return HttpResponse(data, mimetype)

def ajax_refresh(request):
    if request.is_ajax():
        resp = []
        question_set = Question.objects.annotate(
                    choice_count=Count('choice')).filter(
                        choice_count__gt=0,
                        pub_date__lte=timezone.now()
                        ).order_by('-pub_date')[:5]
        for q in question_set:
            qstn = {
                'text': q.question_text,
                'id': q.id,
                'processed': q.processed,
            }
            resp.append(qstn)
        data = json.dumps(resp)
    else:
        data = 'fail'
    mimetype = 'application/json'
    return HttpResponse(data, mimetype)


from functools import wraps
import time
import json
from pathlib import Path

from settings import CFG_DIR, CFG_File

def get_config(config=None):
    config_file = None
    config_key = None
    if config is None:
        config_file = CFG_File
    else:
        config_list = config.split('#')
        if len(config_list) < 1:
            raise Exception('config is empty!')

        first = config_list[0]
        if len(config_list) == 1:
            first = Path(first)
            if first.exists():
                config_file = first
            elif Path(CFG_DIR, first).exists():
                config_file = Path(CFG_DIR, first)
            else:
                config_file = CFG_File
                config_key = first
        else:
            first = Path(first)
            if first.exists():
                config_file = first

            elif Path(CFG_DIR, first).exists():
                config_file = Path(CFG_DIR, first)
            else:
                raise Exception('config file not exists')
            config_key = config_list[1]
    with open(str(config_file), 'r') as fp:
        c = json.load(fp)

    if config_key:
        try:
            c = c[str(config_key)]
        except (KeyError):
            raise Exception('config not found')
    task = c.get('task')
    if task is None:
        for k, v in c.items():
            task = v.get('task')
            if task is not None:
                config_key = k
                c = v
                break
        if task is None:
            raise Exception('config not found')

    if config_key:
        c['config'] = '%s@%s' % (config_file.name, config_key)
    else:
        c['config'] = config_file.name
    return c

def retry(ExceptionToCheck=Exception, tries=3, delay=2, backoff=2, logger=None, hook=None, allfailcb=None):
    """Retry calling the decorated function using an exponential backoff.

    http://www.saltycrane.com/blog/2009/11/trying-out-retry-decorator-python/
    original from: http://wiki.python.org/moin/PythonDecoratorLibrary#Retry

    :param ExceptionToCheck: the exception to check. may be a tuple of
        exceptions to check
    :type ExceptionToCheck: Exception or tuple
    :param tries: number of times to try (not retry) before giving up
    :type tries: int
    :param delay: initial delay between retries in seconds
    :type delay: int
    :param backoff: backoff multiplier e.g. value of 2 will double the delay
        each retry
    :type backoff: int
    :param logger: logger to use. If None, print
    :type logger: logging.Logger instance
    """
    if backoff < 1:
        raise ValueError("backoff must be greater than 0")
    tries = int(tries)
    if tries < 0:
        raise ValueError("tries must be 0 or greater")
    if delay <= 0:
        raise ValueError("delay must be greater than 0")

    def deco_retry(f):

        @wraps(f)
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            while mtries > 0:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck as e:
                    msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
                    if logger:
                        logger.warning(msg)
                    else:
                        print(msg)
                    time.sleep(mdelay)
                    if callable(hook):
                        hook()
                    mtries -= 1
                    mdelay *= backoff
                    if mtries == 0:
                        if allfailcb is None:
                            raise
                        if not callable(allfailcb):
                            raise TypeError('check must be callable.')
                        allfailcb()
            # return f(*args, **kwargs)

        return f_retry  # true decorator

    return deco_retry


# train sentence-BERT model with triplet data
# save the model to ./sbert_stair

import argparse
from sentence_transformers import SentenceTransformer, models, InputExample
from sentence_transformers.losses import TripletDistanceMetric, TripletLoss
from sentence_transformers.evaluation import TripletEvaluator
from sentence_transformers.readers import TripletReader
from sentence_transformers.datasets import SentencesDataset
from torch.utils.data import DataLoader
from sklearn.model_selection import train_test_split
import logging

class TrainTriplet:
    def __init__(self, args):
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.INFO)
        self.logger.addHandler(logging.StreamHandler())
        self.output_path = args.output_path
        self.brands = args.brands
        self.tlds = args.tlds

    def load_data(self, filepath):
        """
        load triplet data from a tsv file which is separated by tab e.g., "anchor_domain\tpositive_domain\tnegative_domain"
        data split into train, dev, test data are saved to ./sample_data/triplet_train.tsv, ./sample_data/triplet_dev.tsv, ./sample_data/triplet_test.tsv

        Parameters:
        ----------
        filepath: str
            path to a tsv file
        """
        self.logger.info("load data from %s" % filepath)

        triplets = []
        # read triplet data from a tsv file which is separated by tab e.g., "anchor_domain\tpositive_domain\tnegative_domain"
        with open(filepath) as f:
            for l in f:
                l = l.rstrip("\n")
                triplet = l.split("\t")
                triplets.append(triplet)

        self.train, dev_test = train_test_split(
            triplets, train_size=0.8, random_state=1)
        self.dev, self.test = train_test_split(
            dev_test, train_size=0.5, random_state=2)

        def _to_tsv(fname, triplet_data):
            with open(fname, "w") as f:
                lines = ["%s\t%s\t%s" % (data[0], data[1], data[2])
                         for data in triplet_data]
                f.write("\n".join(lines)+"\n")

        _to_tsv("./sample_data/triplet_train.tsv", self.train)
        _to_tsv("./sample_data/triplet_dev.tsv", self.dev)
        _to_tsv("./sample_data/triplet_test.tsv", self.test)

    def train_model(self, output_path=""):
        """
        train sentence-BERT model with triplet data

        Parameters:
        ----------
        output_path: str
            path to save the model

        """
        self.logger.info(
            "Start training sentence-BERT model with triplet data")

        BATCH_SIZE = 16
        NUM_EPOCHS = 15
        EVAL_STEPS = 100
        train_len = len(self.train)
        WARMUP_STEPS = int(train_len // BATCH_SIZE * 0.1)

        if output_path == "":
            output_path = self.output_path

        word_embedding_model = models.Transformer(
            'sentence-transformers/all-mpnet-base-v2')

        # load brand name to add tokens
        with open(self.brands) as f:
            brands = f.read().splitlines()
        with open(self.tlds) as f:
            tlds = f.read().splitlines()

        tokens = tlds+brands
        word_embedding_model.tokenizer.add_tokens(tokens, special_tokens=True)
        word_embedding_model.auto_model.resize_token_embeddings(
            len(word_embedding_model.tokenizer))

        pooling = models.Pooling(
            word_embedding_model.get_word_embedding_dimension(),
            pooling_mode_mean_tokens=True,
            pooling_mode_cls_token=False,
            pooling_mode_max_tokens=False
        )

        model = SentenceTransformer(modules=[word_embedding_model, pooling])

        triplet_reader = TripletReader(".")
        train = []
        for i, (a, p, n) in enumerate(self.train):
            train.append(InputExample(guid=str(i), texts=[a, p, n]))
        train_data = SentencesDataset(train, model=model)
        train_dataloader = DataLoader(
            train_data, shuffle=True, batch_size=BATCH_SIZE)

        train_loss = TripletLoss(
            model=model, distance_metric=TripletDistanceMetric.EUCLIDEAN, triplet_margin=1)

        model.fit(train_objectives=[(train_dataloader, train_loss)],
                  epochs=NUM_EPOCHS,
                  evaluation_steps=EVAL_STEPS,
                  warmup_steps=WARMUP_STEPS,
                  output_path=output_path
                  )

        self.logger.info(
            "Finish training sentence-BERT model with triplet data")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description='train sentence-BERT model with triplet data')
    parser.add_argument('--triplet', type=str, required=True,
                        help='path to a tsv file which contains triplet data')
    parser.add_argument('--output_path', type=str,
                        default='./sbert_stair', help='path to save the model')
    parser.add_argument(
        '--tlds', type=str, default='./sample_data/tlds.txt', help='path to a tlds file')
    parser.add_argument(
        '--brands', type=str, default='./sample_data/brands.txt', help='path to a brands file')

    args = parser.parse_args()

    trainer = TrainTriplet(args)
    trainer.load_data(args.triplet)
    trainer.train_model()


from z3 import *

def isValid(P):
    s = Solver()
    s.add(Not(P))  # replace True with required declarative spec
    return (s.check() == unsat)

# Declare X to be a Z3 Bool variable
X = Bool('X')
# Print the result of testing (X Or Not X) for validity
print(isValid(Or(X, Not(X))))
# Print the result of testing (X And Not X) for validity
print(isValid(And(X, Not(X))))


class TwoStacks:
    # Initialize the two stacks here
    def __init__(self, size):
        self.size = size
        self.items = [0] * size
        self.top1 = -1
        self.top2 = self.size

    # Insert Value in First Stack
    def push1(self, value):
        if self.top1 < self.top2 - 1:
            self.top1 += 1
            self.items[self.top1] = value
        else:
            print("Stack Overflow")

    # Insert Value in Second Stack
    def push2(self, value):
        if self.top1 < self.top2 - 1:
            self.top2 -= 1
            self.items[self.top2] = value
        else:
            print("Stack Overflow")

    # Return and remove top Value from First Stack
    def pop1(self):
        if self.top1 >= 0:
            value = self.items[self.top1]
            self.top1 -= 1
            return value
        else:
            print("Stack Underflow")

    # Return and remove top Value from Second Stack
    def pop2(self):
        if self.top2 < self.size:
            value = self.items[self.top2]
            self.top2 += 1
            return value
        else:
            print("Stack Underflow")

    def print_list(self):
        val = "["
        for item in self.items:
            val += str(item)
            val += ", "
        val += "]"
        return val

if __name__ == "__main__" :
    stack = TwoStacks(10)
    stack.push1(20)
    stack.push2(10)
    print(stack.pop1())
    stack.push1(100)
    print(stack.pop2())


import os
import pickle
import numpy as np
import cv2
import face_recognition
import cvzone
import firebase_admin
from firebase_admin import credentials, db, storage
import numpy as np
from datetime import datetime

# Initialize Firebase Admin SDK
cred = credentials.Certificate("FaceRecognition.json")
firebase_admin.initialize_app(cred, {
    'databaseURL': "https://attendanceusingfacerecog-default-rtdb.firebaseio.com/",
    'storageBucket': "attendanceusingfacerecog.appspot.com"
})

bucket = storage.bucket()

# Capture video from webcam
cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)

# Load background image
imgBackground = cv2.imread('Resources/background.png')

# Load mode images into a list
folderModePath = 'Resources/Modes'
modePathList = os.listdir(folderModePath)
imgModeList = [cv2.imread(os.path.join(folderModePath, path)) for path in modePathList]

# Load encoding file
print("Loading File ...")
with open('EncodeFile.p', 'rb') as file:
    encodeListKnownWithIds = pickle.load(file)
encodeListKnown, studentIds = encodeListKnownWithIds
print("Encode File Loaded")

modeType = 0
counter = 0
id = -1
imgStudent = []

while True:
    success, img = cap.read()

    imgS = cv2.resize(img, (0, 0), None, 0.25, 0.25)
    imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    faceCurFrame = face_recognition.face_locations(imgS)
    encodeCurFrame = face_recognition.face_encodings(imgS, faceCurFrame)

    imgBackground[162:162 + 480, 55:55 + 640] = img
    imgBackground[44:44 + 633, 808:808 + 414] = imgModeList[modeType]

    if faceCurFrame:
        for encodeFace, faceLoc in zip(encodeCurFrame, faceCurFrame):
            matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
            faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)

            matchIndex = np.argmin(faceDis)

            if matches[matchIndex]:
                y1, x2, y2, x1 = [coord * 4 for coord in faceLoc]
                bbox = 55 + x1, 162 + y1, x2 - x1, y2 - y1
                imgBackground = cvzone.cornerRect(imgBackground, bbox, rt=0)
                id = studentIds[matchIndex]
                if counter == 0:
                    cvzone.putTextRect(imgBackground, "Loading", (275, 400))
                    cv2.imshow("Face Attendance", imgBackground)
                    cv2.waitKey(1)
                    counter = 1
                    modeType = 1

        if counter != 0:
            if counter == 1:
                # Get the Data
                studentInfo = db.reference(f'Students/{id}').get()
                print(studentInfo)
                # Get the Image from the storage
                blob = bucket.get_blob(f'Images/{id}.png')
                array = np.frombuffer(blob.download_as_string(), np.uint8)
                imgStudent = cv2.imdecode(array, cv2.COLOR_BGRA2BGR)
                # Update attendance data
                datetimeObject = datetime.strptime(studentInfo['last_attendance_time'], "%Y-%m-%d %H:%M:%S")
                secondsElapsed = (datetime.now() - datetimeObject).total_seconds()
                print(secondsElapsed)
                if secondsElapsed > 30:
                    ref = db.reference(f'Students/{id}')
                    studentInfo['total_attendance'] += 1
                    ref.update({'total_attendance': studentInfo['total_attendance'],
                                'last_attendance_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
                else:
                    modeType = 3
                    counter = 0
                    imgBackground[44:44 + 633, 808:808 + 414] = imgModeList[modeType]

            if modeType != 3:
                if 10 < counter < 20:
                    modeType = 2

                imgBackground[44:44 + 633, 808:808 + 414] = imgModeList[modeType]

                if counter <= 10:
                    cv2.putText(imgBackground, str(studentInfo['total_attendance']), (861, 125),
                                cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 1)
                    cv2.putText(imgBackground, str(studentInfo['major']), (1006, 550),
                                cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255), 1)
                    cv2.putText(imgBackground, str(id), (1006, 493),
                                cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255), 1)
                    cv2.putText(imgBackground, str(studentInfo['standing']), (910, 625),
                                cv2.FONT_HERSHEY_COMPLEX, 0.6, (100, 100, 100), 1)
                    cv2.putText(imgBackground, str(studentInfo['year']), (1025, 625),
                                cv2.FONT_HERSHEY_COMPLEX, 0.6, (100, 100, 100), 1)
                    cv2.putText(imgBackground, str(studentInfo['starting_year']), (1125, 625),
                                cv2.FONT_HERSHEY_COMPLEX, 0.6, (100, 100, 100), 1)

                    (w, h), _ = cv2.getTextSize(studentInfo['name'], cv2.FONT_HERSHEY_COMPLEX, 1, 1)
                    offset = (414 - w) // 2
                    cv2.putText(imgBackground, str(studentInfo['name']), (808 + offset, 445),
                                cv2.FONT_HERSHEY_COMPLEX, 1, (50, 50, 50), 1)

                    imgBackground[175:175 + 216, 909:909 + 216] = imgStudent

                counter += 1

                if counter >= 20:
                    counter = 0
                    modeType = 0
                    studentInfo = []
                    imgStudent = []
                    imgBackground[44:44 + 633, 808:808 + 414] = imgModeList[modeType]
    else:
        modeType = 0
        counter = 0

    cv2.imshow("Face Attendance", imgBackground)
    cv2.waitKey(1)


ur_pool = ["Bamboo Rice", "Foie Gras", "Peking Duck", "B-52", "Gingerbread", "Crab Long Bao", "Dragon's Beard Candy", "Rum", "Bibimbap", "Double Scoop", "Boston Lobster"]
sr_pool = ["Soft Serve Cone", "Pineapple Bun", "Fried Chicken", "Pineapple Cake", "Eggette", "Laba Congee", "Milk Tea", "Yunnan Noodles", "Escargot", "Hotdog", "Hamburger", "Steak", "Tangyuan", "Sanma", "Sukiyaki", "Brownie", "Napoleon Cake", "Salad", "Pastel de nata", "Yuxiang", "Tiramisu", "Mango Pudding", "Red Wine", "Gyoza", "Chocolate", "Udon", "Sweet Tofu", "Ddeokbokki", "Kimchi"]
r_pool = ["Long Bao", "Coffee", "Sashimi", "Cold Rice Shrimp", "Macaron", "Zongzi", "Sakuramochi", "Tom Yum", "Taiyaki", "Milk", "Dorayaki", "Sake", "Tempura", "Spicy Gluten", "Jiuniang", "Omurice", "Orange Juice", "Ume Ochazuke", "Miso Soup", "Yellow Wine", "Eclair"]
m_pool = ["Skewer", "Jello", "Pancake", "Popcorn"]
summon_pool = ur_pool + sr_pool + r_pool + m_pool

nur_pool = ["White Truffle", "Turducken", "Oyster", "Fruit Tart", "Matsutake Dobinmushi", "Cloud Tea", "Canele", "Pizza", "Apple Pie", "Nagashi Somen", "Mapo Tofu"]
nsr_pool = ["Pretzel", "Marshmallow", "Soba", "Margarita", "Borscht", "Black Tea", "Lion's Head", "American Corn Bread", "Eggnog", "Zitui Bun", "Salty Tofu", "Spaghetti", "Donut", "Tortoise Jelly", "Sweet & Sour Fish", "Beggar's Chicken", "Bloody Mary", "Vodka", "Wonton", "Yogurt", "Surstromming"]
nr_pool = ["Nasi Lemak", "Cola", "Plum Juice", "Crepe", "Yakitori", "Double-Ninth Cake"]
nm_pool = ["Hawthorne Ball", "Rice", "Cheese", "Toast", "Takoyaki"]
none_pool = nur_pool + nsr_pool + nr_pool + nm_pool

eur_pool = ["Whisky", "Dragon & Phoenix", "Stargazy Pie", "Osechi", "Buddha's Temptation", "Turkey", "Butter Tea", "Huangshan Maofeng Tea", "Champagne", "Sichuan Hotpot", "Toso", "Raindrop Cake", "Milt", "Caviar"]
esr_pool = ["Waffle", "Realgar Wine", "Qingtuan", "Mung Bean Soup", "Black Pudding", "Unadon", "Mandarin Squirrel Fish", "Green Curry", "Cassata", "Bonito Rice", "Seaweed Soup", "Beer", "Moon Cake", "Sushi", "Osmanthus Cake", "Fondant Cake"]
em_pool = ["Pudding", "Sandwich", "Strawberry Daifuku"]
event_pool = eur_pool + esr_pool + em_pool

unre_pool = []

all_pool = summon_pool + none_pool + event_pool
all_ur = ur_pool + nur_pool + eur_pool
all_sr = sr_pool + nsr_pool + esr_pool
all_r = r_pool + nr_pool
all_m = m_pool + nm_pool + em_pool


import configparser
import pathlib
import sys

APP_NAME = 'Cometa'
APP_VERSION = '0.0.4'
RELEASE_DATE = 'Unreleased'

def get_data_paths() -> tuple:
    """Return roaming and local user data paths"""
    portable_path = pathlib.Path('portable')
    if portable_path.is_dir():
        return (
            portable_path.joinpath('user'),
            portable_path.joinpath('host', 'local'),
        )
    return (
        pathlib.Path.home().joinpath('.cometa'),
        pathlib.Path.home().joinpath('.cometa', '.local'),
    )

def get_profile_from_input():
    print(
        """
Enter the paths to the directories that contain the music. First, input path
line, then press Enter, then input the next path line, Enter, and so on.
In the end just press Enter again, with no symbols.
""".strip()
    )
    music_dirs = []
    while True:
        text = input('μ: ')
        if not text:
            break
        music_dir = pathlib.Path(text)
        if not music_dir.is_dir():
            print('Folder not found at this path. Please input again.')
            continue
        music_dirs.append(music_dir)

    print('In which folder to save track data?')
    while True:
        music_data_dir = pathlib.Path(input('>>> '))
        if music_data_dir.is_dir():
            break
        print('Folder not found at this path. Please input again.')
    return music_dirs, music_data_dir

def get_profile_from_config(config_path, collection_name):
    config = configparser.ConfigParser()
    config.read(config_path)
    music_data_dir = pathlib.Path(
        config[collection_name].pop('music_data_dir')
    )

    music_dirs = []
    for key in config[collection_name].keys():
        if key.startswith('music_dir_'):
            music_dirs.append(
                pathlib.Path(config[collection_name].pop(key))
            )
    return music_dirs, music_data_dir

def get_config_dir():
    return get_data_paths()[0] / 'config'

def get_config():
    config_dir = get_config_dir()
    if not config_dir.exists():
        config_dir.mkdir(parents=True)
    config_path = config_dir / 'main.ini'

    if not config_path.exists():
        print('Here is no saved configuration. Let us create an actual one.')
        print('Enter the name of your music collection')
        print('(or your favorite username, nickname or full name).')
        collection_name = input('μ: ')
        music_dirs, music_data_dir = get_profile_from_input()
        update_config(config_path, collection_name, music_dirs, music_data_dir)
    else:
        config = configparser.ConfigParser()
        config.read(config_path)
        collection_names = config.sections()
        displayed_collection_names = [f'"{name}"' for name in collection_names]
        print(f'Known collections: {", ".join(displayed_collection_names)}.')
        print('Input the name of the collection to be processed. If you want\n'
              'to create a new profile, enter new name.'
              ' Or type Enter to exit.')
        collection_name = input('μ: ')
        if collection_name == '':
            print('No name typed. Bye!')
            sys.exit()
        elif collection_name not in collection_names:
            print('This name is a new one. Do you want to describe '
                  'a new collection (Y/n)?')
            decision_new = input('μ: ')
            while True:
                if decision_new.lower() in ['y', 'yes']:
                    music_dirs, music_data_dir = get_profile_from_input()
                    update_config(config_path,
                                  collection_name,
                                  music_dirs,
                                  music_data_dir)
                    break
                elif decision_new.lower() in ['n', 'no']:
                    print('Okay, let you decide what exactly do you want '
                          'to do and then start again.')
                    sys.exit()
                print('So yes or no (y/n)?')
                decision_new = input('μ: ')
    return get_profile_from_config(config_path, collection_name)

def update_config(config_path, collection_name, music_dirs, music_data_dir):
    config = configparser.ConfigParser()
    if config_path.exists():
        config.read(config_path)
    config[collection_name] = {'music_data_dir': str(music_data_dir)}
    mdirs = {f'music_dir_{i}': str(d) for i, d in enumerate(music_dirs)}
    config[collection_name].update(mdirs)
    with open(config_path, 'w') as configfile:
        config.write(configfile)
    return config


'''
expEYES program
Developed as a part of GSoC Project "Plugins-for-ExpEYES"

'''
import gettext
gettext.bindtextdomain("expeyes")
gettext.textdomain('expeyes')
_ = gettext.gettext

import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('srf.dat')  # uses data from srf.dat
x1 = data[:,0]
y1 = data[:,1]
plt.plot(x1, y1)
plt.show()


import time
import pygame
import math
import PythonExtended.Pygame as pyg
import TwitchAPI as twitch
import threading
import random

def overlap(a, b, size=20):
    x1 = a[0]
    y1 = a[1]
    x2 = b[0]
    y2 = b[1]

    return math.pow((x1 - x2), 2) + math.pow((y1 - y2), 2) < math.pow(size, 2)

#region classes
class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.rot = 0

        self.moveF = False
        self.moveB = False
        self.rotL = False
        self.rotR = False

        self.radius = 15
        self.health = 5

    def draw(self, screen):
        pygame.draw.circle(screen, (0,0,255), (self.x, self.y), self.radius)
        pygame.draw.line(screen, (0,0,0), (self.x, self.y), (self.x + math.sin(math.radians(self.rot)) * self.radius,
                        (self.y + math.cos(math.radians(self.rot + 180)) * self.radius)), width=3)

    def moveAndRotate(self, screen):
        if self.rotR:
            self.rot += 3
        if self.rotL:
            self.rot -= 3
        moveDir = 0
        if self.moveF:
            moveDir += 3
        if self.moveB:
            moveDir -= 3

        oldx = self.x
        oldy = self.y
        self.x += moveDir * math.sin(math.radians(self.rot))
        self.y += moveDir * math.cos(math.radians(self.rot + 180))
        if self.x < 0 or self.y < 0 or self.y > screen.get_rect().height or self.x > screen.get_rect().width:
            self.x = oldx
            self.y = oldy

    def shootBullet(self):
        bullet = Bullet(self.x + 25 * math.sin(math.radians(self.rot)),
                        self.y + 25 * math.cos(math.radians(self.rot + 180)),
                        self.rot)
        return bullet

    def checkOverlaps(self, bullets):
        for bullet in bullets:
            if overlap((bullet.x, bullet.y), (self.x, self.y)):
                self.health -= 1

    def bulletSpam(self, bullets):
        for rot in range(0, 360, 90):
            bullets.append(Bullet(self.x + 25 * math.sin(math.radians(rot + 45)),
                            self.y + 25 * math.cos(math.radians(rot + 45 + 180)), rot + 45))

class Bullet:
    def __init__(self, x, y, rot, boss=False):
        self.x = x
        self.y = y
        self.rot = rot

        self.bounces = 0
        self.timer = 0
        self.boss = boss

    def updatePos(self, screen):
        self.x += 4 * math.sin(math.radians(self.rot))
        self.y += 4 * math.cos(math.radians(self.rot + 180))

        self.rot = self.rot%360

        if self.y < 0:
            self.rot = 180 - self.rot
            self.bounces += 1

        if self.y > screen.get_rect().height:
            self.rot = 180 - self.rot
            self.bounces += 1

        if self.x < 0:
            self.rot = 360 - self.rot
            self.bounces += 1

        if self.x > screen.get_rect().width:
            self.rot = 360 - self.rot
            self.bounces += 1

        if self.bounces > 2:
            self.timer += 1
            self.bounces = 3

    def draw(self, screen):
        pygame.draw.circle(screen, (200 - self.bounces*50,self.boss*100,0), (self.x, self.y), 10)

    def shouldDelete(self, playerx, playery):
        return self.timer > 20 or overlap((playerx, playery), (self.x, self.y))

class Enemy:
    def __init__(self, x, y, boss):
        self.x = x
        self.y = y
        self.boss = boss
        self.bcounter = 100
        self.health = boss * 4 + 1

    def draw(self, screen):
        if not self.boss:
            pygame.draw.circle(screen, (0, 0, 0), (self.x, self.y), 20)
        else:
            pygame.draw.circle(screen, (200,200,200), (self.x, self.y), 25)

    def checkOverlaps(self, bullets):
        for bullet in bullets:
            if overlap((bullet.x, bullet.y), (self.x, self.y), 30) and not bullet.boss:
                self.health -= 1
                return bullet
        return None

    def bulletSpam(self, bullets):
        self.bcounter += 1
        if self.bcounter >= 100:
            self.bcounter = 0
            for rot in range(0, 360, 45):
                bullets.append(Bullet(self.x + 25 * math.sin(math.radians(rot)),
                                self.y + 25 * math.cos(math.radians(rot + 180)), rot, boss=True))
#endregion

def spawnEnemy(screen, boss):
    return Enemy(random.randint(20, screen.get_rect().width - 20),
                 random.randint(20, screen.get_rect().height - 20), boss)

def run():
    print("Connecting to twitch servers...")
    s = twitch.connect()
    twitch.sendMessage(s, "#robertjn_dev", "[BOT] Connected to twitch servers! This is an interactive game.")
    twitch.sendMessage(s, "#robertjn_dev", "[BOT] Try using !enemy, !boss, !health, !powerup.")

    #region Reset + Init
    pygame.init()
    screen = pygame.display.set_mode((600, 600), pygame.RESIZABLE)
    pygame.display.set_caption("PyTwitch Arcade")
    clock = pygame.time.Clock()

    # region threads
    d = {}
    thread = threading.Thread(target=twitch.checkChat, args=(s, d,))
    thread.start()
    lastmessage = "Waiting for message...."
    lastsender = "Twitch chat"
    # endregion

    close = False
    while not close:
        player = Player(screen.get_rect().centerx, screen.get_rect().centery)
        bullets = []
        bulletspamcounter = 0
        score = 0
        enemies = []
        #endregion

        done = False
        while not done:
            #region threads
            if not thread.is_alive():
                if d != {}:
                    lastmessage = d["message"]
                    lastsender = d["sender"]
                    if lastmessage == "!enemy":
                        enemies.append(spawnEnemy(screen, False))
                    elif lastmessage == "!boss":
                        enemies.append(spawnEnemy(screen, True))
                    elif lastmessage == "!powerup":
                        bulletspamcounter = 200
                    elif lastmessage == "!health" and player.health < 5:
                        player.health += 1

                d = {}
                thread = threading.Thread(target=twitch.checkChat, args=(s, d,))
                thread.start()
            #endregion

            if len(enemies) == 0:
                enemies.append(spawnEnemy(screen, False))

            screen.fill((50,50,50))
            pyg.message_display(screen, "FPS: " + str(round(clock.get_fps())), (screen.get_rect().width-30,20), size=15)
            pyg.message_display(screen, "Score: " + str(round(score)), (screen.get_rect().width - 40, 40),
                                size=15)
            pyg.message_display(screen, str(lastsender) + ": " + str(lastmessage),
                                (screen.get_rect().width/2, screen.get_rect().height-20), color = (200,200,200), size=20)
            pygame.draw.rect(screen, (200,0,0), (0,0,screen.get_rect().width/5 * player.health,10))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    close = True
                    done = True

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_w:
                        player.moveF = True
                    elif event.key == pygame.K_s:
                        player.moveB = True
                    elif event.key == pygame.K_a:
                        player.rotL = True
                    elif event.key == pygame.K_d:
                        player.rotR = True
                    elif event.key == pygame.K_SPACE:
                        bullets.append(player.shootBullet())

                elif event.type == pygame.KEYUP:
                    if event.key == pygame.K_w:
                        player.moveF = False
                    elif event.key == pygame.K_s:
                        player.moveB = False
                    elif event.key == pygame.K_a:
                        player.rotL = False
                    elif event.key == pygame.K_d:
                        player.rotR = False

            if bulletspamcounter > 0:
                if bulletspamcounter%25 == 0:
                    player.bulletSpam(bullets)
                bulletspamcounter -= 1

            player.draw(screen)
            player.moveAndRotate(screen)
            for enemie in enemies:
                enemie.draw(screen)
                if enemie.boss:
                    enemie.bulletSpam(bullets)
            for bullet in bullets:
                bullet.updatePos(screen)
                bullet.draw(screen)

            player.checkOverlaps(bullets)

            for i in range(len(bullets) -1, -1, -1):
                if bullets[i].shouldDelete(player.x, player.y):
                    bullets.pop(i)

            for i in range(len(enemies) -1, -1, -1):
                bullet = enemies[i].checkOverlaps(bullets)
                if bullet is not None:
                    bullets.remove(bullet)
                    if enemies[i].health == 0:
                        if player.health < 5:
                            if enemies[i].boss:
                                score += 9
                                player.health = 5
                            elif random.randint(0, 1) == 0:
                                player.health += 1
                        enemies.pop(i)
                        score += 1

            if player.health <= 0:
                pyg.message_display(screen, "GAME OVER!", (screen.get_rect().width/2, screen.get_rect().height/2), (0,0,0),
                                    size=50)
                pygame.display.flip()
                time.sleep(2)
                done = True

            pygame.display.flip()
            clock.tick(50)

    s.close()


# In correspondence to the instability observed by splitting_orderplot.py for different weights we here test
# the dependence on the weight by estimating the CFL number. Should be the same for different N, but because estimation
# is different (and not always equally accurate as these are heuristics) they do not completely fit on top of each oth
from itertools import repeat

import matplotlib.pyplot as plt
import numpy as np

import demo.chapter1.splitting as ds
import diff_equation.klein_gordon as kg
from diff_equation.splitting import Splitting
from util.analysis import error_l2_relative

dimension = 1
grid_size_Ns = [256, 512, 1024, 2048, 2048*2]
plt.figure()
plt.title("Abhängigkeit der CFL Zahl $\\tilde{c}$ vom Gewicht $w$")
plt.xlabel("Gewicht $w$")
plt.ylabel("CFL Zahl $\\tilde{c}$")
for grid_size_N in grid_size_Ns:
    print(grid_size_N)
    domain = list(repeat([-np.pi, np.pi], dimension))
    trial = ds.trial_frog2

    start_time = 0.
    dt = 0.0001
    delta_times = np.arange(0.0002, 0.1, dt)
    stop_time = 1.

    dw = 0.05
    weights = np.arange(0., 1. + dw, dw)
    xs_mesh = None
    cfl_constants = []

    for weight in weights:
        def make_wave_linhyp_configs():
            return kg.make_klein_gordon_wave_linhyp_configs(domain, [grid_size_N], trial.alpha, trial.beta, weight)

        prev_error, prev_delta_time = -1, -1
        for delta_time in delta_times:
            splitting = Splitting.make_strang(*make_wave_linhyp_configs(), "Strang",
                                              start_time, trial.start_position, trial.start_velocity)
            splitting.progress(splitting.approx_steps_to_end_time(stop_time, delta_time), delta_time, 0)
            if xs_mesh is None:
                xs_mesh = splitting.get_xs_mesh()

            trial.error_function = error_l2_relative
            error = trial.error(xs_mesh, splitting.times()[-1], splitting.solutions()[-1])
            print("dt=", delta_time, "error=", error)
            if error > prev_error > 0:
                steigung = np.abs(np.log(error - prev_error) / np.log(delta_time - prev_delta_time))
                print("Steigung=", steigung)
                if error > 1 or steigung > 3. or steigung < 1.:
                    print("BREAKING, next would be:", error)
                    cfl_constants.append((2*np.pi / grid_size_N) / prev_delta_time)
                    break

            prev_error = error
            prev_delta_time = delta_time

        else:
            cfl_constants.append(0)
    print(cfl_constants)
    plt.plot(weights, cfl_constants, label="$N={}$".format(grid_size_N))
plt.legend()
plt.show()


from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import re
from pyquery import PyQuery as pq
import json

browser=webdriver.Chrome()
browser.get('http://www.51job.com/')
wait=WebDriverWait(browser,10)

def search():
    try:
        input=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#kwdselectid')))
        submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'body > div.content > div > div.fltr.radius_5 > div > button')))
        input.send_keys('爬虫')
        submit.click()
        total=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'body > div.dw_wp > div.dw_page > div > div > div > span:nth-child(2)')))
        for item in get_products():
            save_to_file(item)
        return total.text
    except TimeoutException:
        search()

def next_page(page_numb):
    try:
        input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#jump_page')))
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, 'body > div.dw_wp > div.dw_page > div > div > div > span.og_but')))
        input.clear()
        input.send_keys(page_numb)
        submit.click()
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'body > div.dw_wp > div.dw_page > div > div > div > ul > li.on'),str(page_numb)))
        for item in get_products():
            save_to_file(item)
    except TimeoutException:
        next_page(page_numb)

def get_products():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#resultList .el')))
    html=browser.page_source
    doc=pq(html)
    items=doc('#resultList .el').items()
    for item in items:
        yield {
            'position':item.find('.t1').text(),
            'company':item.find('.t2').text(),
            'location':item.find('.t3').text(),
            'pay':item.find('.t4').text(),
            'update':item.find('.t5').text()
        }

def save_to_file(item):
    with open('result.txt','a',encoding='utf-8') as f:
        f.write(json.dumps(item,ensure_ascii=False)+'\n')
        f.close()

def main():
    total=search()
    total=int(re.compile('(\d+)').search(total).group(1))
    for i in range(1,total + 1):
         next_page(i)

if __name__=='__main__':
    main()


import random
from Visual import Visual

class Metrics:
    def traverse_path(self, goal_node, start_node):
        path = [goal_node]
        currentNode = goal_node
        while currentNode is not start_node:
            currentNode = currentNode.parent
            path.append(currentNode)
        path.reverse()
        return path

    def generate_random_start_and_goal_nodes(self, actual_maze, size):
        while True:
            start_node_actual = actual_maze[random.randint(0, size-1)][random.randint(0, size-1)]
            goal_node_actual = actual_maze[random.randint(0, size-1)][random.randint(0, size-1)]
            if (start_node_actual.cost == 1) & (goal_node_actual.cost == 1) & (start_node_actual != goal_node_actual):
                break
        return start_node_actual, goal_node_actual

    def blockage_status_of_children(self, start_node, start_node_actual, w):
        for i in range(0,4):
            child_actual = start_node_actual.traverse_children(i)
            if child_actual is not None:
                child = start_node.traverse_children(i)
                child.cost = child_actual.cost
                w.blocked(child)
        w.master.update()
        w.master.after(200)

    def initializeVisuals(self, start_node, goal_node, size, actual_maze, agent_maze):
        w = Visual(start_node, goal_node, size)
        w.showMaze(actual_maze)
        w.showMaze(agent_maze)
        return w


import sys
from typing import List, Optional, Tuple

Input = List[Tuple[str, ...]]

def speculate_inputs(instructions: Input, digits: List[int]) -> bool:
    digits = list(digits)

    possible_values = {
        "w": {0},
        "x": {0},
        "y": {0},
        "z": {0},
    }

    def get_reg_values(key: str):
        if key in possible_values:
            return possible_values[key]
        else:
            return {int(key)}

    def cross_op(lhs_reg, rhs_reg, f):
        new_possible_values = set()
        for lhs in possible_values[lhs_reg]:
            for rhs in get_reg_values(rhs_reg):
                new_possible_values.add(f(lhs, rhs))
        possible_values[lhs_reg] = new_possible_values

    def mod(lhs, rhs):
        lhs %= rhs
        while lhs < 0:
            lhs += rhs
        return lhs

    for (i, instr) in enumerate(instructions):
        cmd = instr[0]
        if cmd == "inp":
            if digits:
                possible_values[instr[1]] = {digits.pop(0)}
            else:
                possible_values[instr[1]] = set(range(9, 0, -1))
        elif cmd == "add":
            cross_op(instr[1], instr[2], lambda x, y: x + y)
        elif cmd == "mul":
            cross_op(instr[1], instr[2], lambda x, y: x * y)
        elif cmd == "sub":
            cross_op(instr[1], instr[2], lambda x, y: x - y)
        elif cmd == "div":
            cross_op(instr[1], instr[2], lambda x, y: x // y)
        elif cmd == "mod":
            cross_op(instr[1], instr[2], mod)
        elif cmd == "eql":
            cross_op(instr[1], instr[2], lambda x, y: int(x == y))

        if any(len(x) == 0 for x in possible_values.values()):
            raise ValueError(f"Unsatisfiable: {possible_values}")

    return 0 in possible_values["z"]

def test_speculate_inputs() -> None:
    assert speculate_inputs(
        [
            ("inp", "w"),
        ],
        digits=[0],
    )
    assert not speculate_inputs(
        [
            ("inp", "w"),
            ("add", "z", "w"),
        ],
        digits=[1],
    )
    assert not speculate_inputs(
        [
            ("inp", "w"),
            ("inp", "x"),
            ("add", "z", "x"),
        ],
        digits=[1],
    )
    assert speculate_inputs(
        [
            ("inp", "w"),
            ("inp", "x"),
            ("add", "z", "-1"),
            ("add", "z", "x"),
        ],
        digits=[1],
    )

def search(instructions: Input, digits: List[int]) -> Optional[List[int]]:
    print("Trying with digits:", "".join(str(d) for d in digits))
    if len(digits) >= 14:
        return digits

    for i in range(9, 0, -1):
        if not speculate_inputs(instructions, digits=digits + [i]):
            continue
        result = search(instructions, digits=digits + [i])
        if result is not None:
            return result
    return None

def search2(instructions: Input, digits: List[int]) -> Optional[List[int]]:
    if len(digits) == 5:
        print("Trying with digits:", "".join(str(d) for d in digits))
    if len(digits) >= 14:
        return digits

    for i in range(1, 10):
        if not speculate_inputs(instructions, digits=digits + [i]):
            continue
        result = search2(instructions, digits=digits + [i])
        if result is not None:
            return result
    return None

def main() -> None:
    instructions = []
    for line in sys.stdin:
        words = line.split()
        instructions.append(tuple(words))

    # Very slow, could be multithreaded, but a better solution would probably
    # just be faster.
    print(search(instructions, digits=[]))
    print(search2(instructions, digits=[]))

if __name__ == "__main__":
    main()


from django.contrib import admin
from django.urls import path
from snippets import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('studentapi/', views.student_api),
    path('studentapi/<int:id>', views.student_api),
    path('stuapiclass/', views.StudentAPI.as_view()),
    path('stuapiclass/<int:id>', views.StudentAPI.as_view()),
]


import os
import csv

election_data_csv = os.path.join("Resources", "election_data.csv")

with open(election_data_csv, 'r') as csvfile:
    csv_reader = csv.reader(csvfile, delimiter=",")

# Print the header
    print("Election Results")
    print("----------------------------------------------------")

# Skip the header row
    next(csv_reader, None)

# Initialize variables
    total_votes=0
    candidates_votes={}

    # Loop through all the data in a file
    for row in csv_reader:
        # Count the total number of votes
        total_votes+=1

        #Add candidates to the dictionary
        candidate = row[2]
        if candidate in candidates_votes:
            candidates_votes[candidate]+=1
        else:
            candidates_votes[candidate]=1
    print(f"Total Votes: {total_votes}")
    print("----------------------------------------------------")

    #calculate the percentage of votes each candidate won and who is the winner
    winner = ""
    winner_votes = 0
    for candidate, votes in candidates_votes.items():
        percent_votes = round((votes/total_votes)*100,3)
        print(f"{candidate}: {percent_votes}% ({votes})")
        if votes>winner_votes:
            winner = candidate
            winner_votes=votes

    print("----------------------------------------------------")
    print(f"Winner: {winner}")
    print("----------------------------------------------------")

     # Create a text file to write the results
    output_file = os.path.join("analysis", "PyPoll_results.txt")
    with open(output_file, 'w') as textfile:
        textfile.write("Election Results\n")
        textfile.write("----------------------------------------------------\n")
        textfile.write(f"Total Votes: {total_votes}\n")
        textfile.write("----------------------------------------------------\n")
        for candidate, votes in candidates_votes.items():
            textfile.write(f"{candidate}: {round((votes/total_votes)*100,3)}% ({votes})\n")
        textfile.write("----------------------------------------------------\n")
        textfile.write(f"Winner: {winner}\n")
        textfile.write("----------------------------------------------------\n")


import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

from astropy import units as u
from astropy.coordinates import SkyCoord, EarthLocation, AltAz
from astropy.io.misc import yaml
from astropy.time import Time
# from IPython.display import Image

# from urllib.parse import urlencode
# from urllib.request import urlretrieve

class Observatories():
    """

    """

    def __init__(self):
        with open('obs.yaml', 'r') as file:
            self.loc = yaml.load(file)
        self.df = pd.read_csv('observatories.csv')
        self.regions = list(self.df.region.unique())
        self.curr_region = 'NorthAmerica'

    def get_region(self):
        self.curr_region = st.sidebar.radio("Choose a region", self.regions)
        st.sidebar.markdown(
            "There is currently a [bug in streamlit]" +
            "(https://github.com/streamlit/streamlit/issues/475) " +
            "which prevents the map scrolling automatically to the new region")
        st.sidebar.markdown("For now, use the mouse to pan and zoom - sorry")
        self.get_site()

    def get_site(self):
        st.markdown(self.curr_region)
        self.sites = list(self.df[self.df.region == self.curr_region].name)
        self.curr_site = st.sidebar.selectbox("Sites in this region", self.sites)
        self.show_loc()

    def get_midpoint(self):
        # Adding code so we can have map default to the center of the data
        # Currently viewport only set on initial load: accepted as bug
        region_df = self.df[self.df.region == self.curr_region]
        return (np.average(region_df['lat']), np.average(region_df['lon']))

    def show_chart(self):
        midpoint = self.get_midpoint()
        st.deck_gl_chart(
                    viewport={
                        'latitude': midpoint[0],
                        'longitude':  midpoint[1],
                        'zoom': 2,
                    },
                    layers=[{
                        'type': 'ScatterplotLayer',
                        'data': self.df,
                        'radiusScale': 150,
                        'radiusMinPixels': 5,
                        'getFillColor': [248, 24, 148],
                        'pickable': True,
                    },
                        {
                        "type": "TextLayer",
                        "data": self.df,
                        "getText": "name",
                        "getColor": [0, 0, 200, 200],
                        "getSize": 15,
                    },
                ]
            )

    def show_loc(self):
        st.markdown(f"## {self.curr_site}")
        self.observing_location = self.loc[self.curr_site]
        here = self.df.loc[self.df['name'] == self.curr_site].iloc[0]
        st.markdown(f"Latitude: {self.observing_location.lat:.2f}, " +
                    f"Longitude: {self.observing_location.lon:.2f}, " +
                    f"Height: {self.observing_location.height:.0f}")

    def show_sky_coord(self, obs_time=Time.now()):
        aa_now = AltAz(location=self.observing_location, obstime=obs_time)

        sky_coords = {}
        obj_names = st.sidebar.text_input('Sky object names (comma separated)', 'm31, vega')
        st.markdown(f'### Current sky positions from {self.curr_site}')
        for obj_name in obj_names.split(','):
            try:
                obj = SkyCoord.from_name(obj_name)
            except:
                st.markdown(f'**{obj_name}:** not found in Sesame')
                continue
            sky_coords[obj_name] = obj.transform_to(aa_now)
            st.markdown(f"**{obj_name}:** Alt = {sky_coords[obj_name].alt:.2f}, " +
                                        f"Az = {sky_coords[obj_name].az:.2f}")

    def show_interface(self):
        self.get_region()
        self.show_chart()
        self.show_sky_coord()

if __name__ == "__main__":
    obs = Observatories()
    obs.show_interface()


#!/usr/bin/env python3
# -*- coding: utf-8, vim: expandtab:ts=4 -*-

import glob
import os
from os import makedirs
from io import StringIO
from xml.etree.ElementTree import ElementTree

from bs4 import BeautifulSoup
from os.path import basename, join as os_path_join

from io import StringIO
from xml.etree import ElementTree
from xml.dom import minidom
# from xml_irreg_finder import print_mist, get_listwit

def print_mist(out, mistakes):
    for m in mistakes:
        print('\t'.join(m))
        print('\t'.join(m), file=out)

def get_listwit(soup):
    wit = soup.find('listWit')
    listwit = ['#'+w['xml:id'] for w in wit.find_all('witness', {'xml:id': True})]
    return sorted(listwit)

def prettify_beta(xml_string):
    f = StringIO(xml_string)  # io.StringIO volt
    tree = ElementTree.parse(f)
    root = tree.getroot()
    teixml_as_string = ElementTree.tostring(root, encoding="unicode")
    xmlstr = minidom.parseString(teixml_as_string).toprettyxml(newl='\n', encoding='utf-8')
    xmlstr = os.linesep.join(s for s in xmlstr.decode("utf-8").splitlines() if s.strip())
    return xmlstr

def tei_writer(xml_string, origi_filename):
    misi_xml = prettify_beta(str(xml_string))
    pretty_new = '\n'.join([b.replace('ns0:', '') for b in misi_xml.split('\n')])
    odir = origi_filename.split('/')[0]
    newdir = f'{odir}_corrected'
    new_filename = origi_filename.split('/')[1]
    final_name = os_path_join(newdir, f'{new_filename}')
    makedirs(newdir, exist_ok=True)
    with open(final_name, 'w', encoding='utf-8') as open_file:
        open_file.write(str(pretty_new))

def find_parentid(tag):
    parent_tag = tag.parent
    while parent_tag is not None:
        if 'xml:id' or 's' in parent_tag.attrs.keys():
            # print(parent_tag)
            return parent_tag.name, parent_tag.attrs
        parent_tag = parent_tag.parent
    return None

def get_idlist(tag):
    if 'wit' in tag.attrs:
        return sorted(tag['wit'].split())
    return None

def first_fix(m_list, file_name, soup):
    id_list = []
    for tag in soup.find_all(['lem', 'rdg']):
        tag_loc = find_parentid(tag)
        if tag.attrs == {}:
            m_list.append(
                (file_name, str(tag_loc), 'WARNING / MISSING ATTRIBUTE!', tag.name, tag.text.replace('\n', '')[0:30]))
        else:
            id_list = tag['wit'].split()
            corr_id_list = []
            for i in id_list:
                if i.startswith('#') is False:
                    m_list.append((file_name, str(tag_loc), 'FIX / # IS MISSING BEFORE THE VALUE:', i,
                                   tag.text.replace('\n', '')[0:30]))
                    i = f'#{i}'
                elif not i[-1].isalnum():
                    m_list.append((file_name, str(tag_loc), 'WARNING / NOT VALID CHARACTER IN THE VALUE:', i,
                                   tag.text.replace('\n', '')[0:30]))
                corr_id_list.append(i)
            tag.attrs = {'wit': ' '.join(set(corr_id_list))}

def is_up_level(tag):
    haslem = tag.find(['lem', 'rdg'])
    if haslem is not None and haslem.find(['lem', 'rdg']) is not None:
        return True
    return False

def find_curr_target_set(tag):
    parent_tag = tag.parent
    while parent_tag is not None:
        if 'wit' in parent_tag.attrs.keys() and parent_tag.name in {'lem', 'rdg'}:
            return sorted(parent_tag['wit'].split())
        parent_tag = parent_tag.parent
    return None

def value_remover(dupl, error, f_name, loc, mist, sum_wit_set_app, wit_sets_per_app_dict):
    # egyesével kiveszem azokat, amik pluszban vannak benne
    for witval in dupl:
        if witval in wit_sets_per_app_dict[0][1]:
            wit_sets_per_app_dict[0][1].remove(witval)
            sum_wit_set_app.remove(witval)
            wit_sets_per_app_dict[0][0].attrs = {'wit': ' '.join(wit_sets_per_app_dict[0][1])}
        else:
            mist.append(
                (f_name, str(loc), error, witval))

def find_mistakes(bs, main_wit_list, mist, f_name):
    """Fő funkció: Ellenőrzi, hogy az egyes <app> részfákban a <lem> és <rdg>-kben "wit" attribútumában található
    id halmazok match-elnek-e az <app> legközelebbi szülő <lem>/<rdg>-jében vagy a legfelső szint esetén a header-ben
    felsorolt witness halmazzal
    Hibák lehetnek: 1) egyszerű duplikáció(k)
                    2) olyan id, amelynek azon az ágon már nem szabadna felbukkania
                    3) hiányzó id(k):a közvetlen szülő id halmazához képest hiányzik
    Automatikus korrekció:
        id-k törlése: akkor van megengedve, ha a <lem>-ből tudja kivennei a felesleget  (ha nem, akkor WARNING)
        id hozzáadása: mindig a <lem>-hez
        (ha van lem, akkor ahhoz,. ha csak redg, akkor a legelső rdg-hez)
    # TODO: fájlban maradt kommentek előszűrése: dobja vissza a fájlt rögtön
    # TODO: tudjon rdg-ből is kivenni felesleget, amennyiben az attribútuma nem marad teljesen érték nélkül
                                    (problémás, hogy melyik rdg-ből, ha választani kell!)
                    """

    bs_body = bs.find('body')
    """1) alap bakik"""
    first_fix(mist, f_name, bs)

    """2)"""
    for app in bs_body.find_all('app'):
        curr_target_witness_set = find_curr_target_set(app)
        if curr_target_witness_set is None:
            curr_target_witness_set = main_wit_list
        loc = find_parentid(app)
        wit_sets_per_app_dict = {}
        sum_wit_set_app = []

        for i, lem_or_rdg in enumerate(app.find_all(['lem', 'rdg'], recursive=False)):
            wits = get_idlist(lem_or_rdg)
            if wits is not None:
                wit_sets_per_app_dict[i] = (lem_or_rdg, wits)
                sum_wit_set_app.extend(wits)

        sum_wit_set_app = sorted(sum_wit_set_app)
        if sum_wit_set_app != curr_target_witness_set:
            diff_extra = set(sum_wit_set_app) - set(curr_target_witness_set)
            # azért if-ek következnek, mert egy résszel több probléma lehet, ebben a sorrendben kell megoldani,
            # a korrigált megy a kövi szűrőbe
            if len(diff_extra) > 4:
                # csak jelzés, ha sokkal több érték van az alsóbb szinten, mint amit a gyökere megenged
                mist.append((f_name, str(loc), 'WARNING / TOO MUCH EXTRA (LOWER-LEVEL) VALUES',
                             str(curr_target_witness_set), str(sum_wit_set_app)))
            if sorted(sum_wit_set_app) != sorted(list(set(sum_wit_set_app))):
                dupl = set([d for d in sum_wit_set_app if sum_wit_set_app.count(d) > 1])
                mist.append((f_name, str(loc), 'FIX / ONE OR MORE DUPLICATION IN:', str(sum_wit_set_app),
                             app.text.replace('\n', ' ')[0:30]))
                error = 'WARNING / ONE OR MORE DUPLICATION <--- NOT SOLVED'
                value_remover(dupl, error, f_name, loc, mist, sum_wit_set_app, wit_sets_per_app_dict)

            diff_extra = set(sum_wit_set_app) - set(curr_target_witness_set)
            if len(diff_extra) > 0:
                diff_extra = set(sum_wit_set_app) - set(curr_target_witness_set)
                mist.append((f_name, str(loc), 'FIX / ONE OR MORE EXTRA WITNESS IN SET:', str(diff_extra),
                             app.text.replace('\n', ' ')[0:30]))
                error = 'WARNING / "ONE OR MORE EXTRA WITNESS IN SET <--- NOT SOLVED'
                for extra in diff_extra:
                    # egyesével kiveszem azokat, amik pluszban vannak benne
                    value_remover(extra, error, f_name, loc, mist, sum_wit_set_app, wit_sets_per_app_dict)

            diff_set = set(curr_target_witness_set) - set(sum_wit_set_app)
            if len(diff_set) > 0:
                mist.append((f_name, str(loc), 'FIX / INCOMPLETE WITNESS SET! MISSING:', str(diff_set),
                             app.text.replace('\n', ' ')[0:30]))
                tag_to_correct = wit_sets_per_app_dict[0][0]
                corrected_set = set(wit_sets_per_app_dict[0][1]).union(diff_set)
                tag_to_correct.attrs = {'wit': ' '.join(corrected_set)}

    return bs, mist

if __name__ == '__main__':
    # xml_folder = 'ransanus_check'
    xml_folder = 'ransanus'
    output_filename = f'{xml_folder}_FIX_log.txt'
    mist_list = []
    with open(output_filename, 'a') as outf:
        for filepath in glob.iglob(f'{xml_folder}/*.xml'):
            with open(filepath, 'r') as xml_file:
                bs_xml = BeautifulSoup(xml_file, 'xml')
                curr_listwit = get_listwit(bs_xml)
                corrected_bs, mist_list = find_mistakes(bs_xml, curr_listwit, mist_list, filepath)
                tei_writer(corrected_bs, filepath)
        print_mist(outf, mist_list)


#!/usr/bin/env python
#coding=utf-8

import cyclone.auth
import cyclone.escape
import cyclone.web
import decimal
import datetime
from tablib import Dataset
from toughradius.manage import models
from toughradius.manage.base import BaseHandler
from toughradius.manage.customer import customer_forms
from toughlib.permit import permit
from toughlib import utils
from toughradius.manage.settings import *

class CustomerHandler(BaseHandler):

    detail_url_fmt = "/admin/customer/detail?account_number={0}".format

@permit.route(r"/admin/customer", u"用户信息管理",MenuUser, order=1.0000, is_menu=True)
class CustomerListHandler(CustomerHandler):

    @cyclone.web.authenticated
    def get(self):
        self.post()

    @cyclone.web.authenticated
    def post(self):
        node_id = self.get_argument('node_id', None)
        realname = self.get_argument('realname', None)
        idcard = self.get_argument('idcard', None)
        mobile = self.get_argument('mobile', None)
        user_name = self.get_argument('user_name', None)
        status = self.get_argument('status', None)
        product_id = self.get_argument('product_id', None)
        address = self.get_argument('address', None)
        expire_days = self.get_argument('expire_days', None)
        opr_nodes = self.get_opr_nodes()
        _query = self.db.query(
            models.TrCustomer,
            models.TrAccount,
            models.TrProduct.product_name,
            models.TrNode.node_desc
        ).filter(
            models.TrProduct.id == models.TrAccount.product_id,
            models.TrCustomer.customer_id == models.TrAccount.customer_id,
            models.TrNode.id == models.TrCustomer.node_id
        )

        _now = datetime.datetime.now()

        if idcard:
            _query = _query.filter(models.TrCustomer.idcard == idcard)
        if mobile:
            _query = _query.filter(models.TrCustomer.mobile == mobile)
        if node_id:
            _query = _query.filter(models.TrCustomer.node_id == node_id)
        else:
            _query = _query.filter(models.TrCustomer.node_id.in_([i.id for i in opr_nodes]))
        if realname:
            _query = _query.filter(models.TrCustomer.realname.like('%' + realname + '%'))
        if user_name:
            _query = _query.filter(models.TrAccount.account_number.like('%' + user_name + '%'))

        #用户状态判断
        if status:
            if status == '4':
                _query = _query.filter(models.TrAccount.expire_date <= _now.strftime("%Y-%m-%d"))
            elif status == '1':
                _query = _query.filter(
                    models.TrAccount.status == status,
                    models.TrAccount.expire_date >= _now.strftime("%Y-%m-%d")
                )
            else:
                _query = _query.filter(models.TrAccount.status == status)

        if product_id:
            _query = _query.filter(models.TrAccount.product_id == product_id)
        if address:
            _query = _query.filter(models.TrCustomer.address.like('%' + address + '%'))
        if expire_days:
            _days = int(expire_days)
            td = datetime.timedelta(days=_days)
            edate = (_now + td).strftime("%Y-%m-%d")
            _query = _query.filter(models.TrAccount.expire_date <= edate)
            _query = _query.filter(models.TrAccount.expire_date >= _now.strftime("%Y-%m-%d"))

        if self.request.path == '/admin/customer':
            return self.render("customer_list.html",
                          page_data=self.get_page_data(_query),
                          node_list=opr_nodes,
                          products=self.db.query(models.TrProduct),
                          **self.get_params())
        elif self.request.path == "/admin/customer/export":
            data = Dataset()
            data.append((
                u'区域', u'姓名', u'证件号', u'邮箱', u'联系电话', u'地址',
                u'用户账号', u'密码', u'资费', u'过期时间', u'余额(元)',
                u'时长(小时)', u'流量(MB)', u'并发数', u'ip地址', u'状态', u'创建时间'
            ))
            for i, j, _product_name, _node_desc in _query:
                data.append((
                    _node_desc, i.realname, i.idcard, i.email, i.mobile, i.address,
                    j.account_number, self.aes.decrypt(j.password), _product_name,
                    j.expire_date, utils.fen2yuan(j.balance),
                    utils.sec2hour(j.time_length), utils.kb2mb(j.flow_length), j.user_concur_number, j.ip_address,
                    customer_forms.user_state[j.status], j.create_time
                ))
            name = u"RADIUS-USER-" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + ".xls"
            self.export_file(name, data)

@permit.route(r"/admin/customer/export", u"用户导出",MenuUser, order=1.0001)
class CustomerExportHandler(CustomerListHandler):
    pass


from .models import Profile
from django.forms import ModelForm, TextInput

class ProfileCityForm(ModelForm):
    class Meta:
        model = Profile
        fields = ['user_city']
        widgets = {'user_city': TextInput(attrs={
            'class': 'form-control',
            'name': 'city',
            'id': 'city',
            'placeholder': 'Choose your city'
        })}