from flask import Blueprint, request, g
from werkzeug.exceptions import NotFound, MethodNotAllowed, BadRequest

from access_guards import only_worker
from utils import datetime_from_json

from models.db import db
from models.trainings import Training
from models.courses import Course
from models.users import User, Role
from models.courses_utils import Tag, Place

bp = Blueprint('trainings', __name__, url_prefix='/trainings')

@bp.route('/<int:id>')
def get_training(id):
    training = Training.query.filter_by(id=id).first()
    if training is None:
        raise NotFound('Training with that id does not exist!')
    return training.to_dict()

@bp.route('/')
def get_trainings():
    json_body = request.get_json()
    trainings_pages = Training.query
    page = 1
    per_page = 20

    if json_body is not None:
        tags = json_body.get('tags')
        if tags:
            trainings_pages = trainings_pages.join(Training.course).join(
                Course.tags).filter(Tag.id.in_(tags))

        name = json_body.get('name')
        if name:
            trainings_pages = trainings_pages.join(
                Training.course).filter(Course.name.ilike('%{}%'.format(name)))

        cities = json_body.get('cities')
        if cities:
            trainings_pages = trainings_pages.join(
                Training.place).filter(Place.city_id.in_(cities))

        page = json_body.get('page', 1)
        per_page = json_body.get('per_page', 20)

    trainings_pages = trainings_pages.order_by(Training.id).paginate(
        page, per_page,
        error_out=False, max_per_page=9999)

    return {
        'trainings': [
            training.to_dict()
            for training in trainings_pages.items
        ],
        'items': len(trainings_pages.items),
        'pages': trainings_pages.pages,
        'page': trainings_pages.page,
        'page_size': trainings_pages.per_page,
        'is_last': not trainings_pages.has_next
    }

def get_instructor(instructor_id):
    instructor = User.query.filter_by(id=instructor_id).join(
        User.role).filter(Role.name == "worker").first()
    if instructor is None:
        raise BadRequest(
            "User with that id does not exist or is not a worker!")
    return instructor

@bp.route('/', methods=['POST'])
@only_worker
def create_training():
    request_body = request.form
    attrs = [
        request_body.get('price'), request_body.get('places_amount'),
        request_body.get('begin_date'), request_body.get('end_date'),
        request_body.get('enrolment_begin_date'), request_body.get(
            'enrolment_end_date'),
        request_body.get('course_id'), request_body.get('place_id'),
        request_body.get('instructor_id')
    ]
    if None in attrs:
        raise BadRequest("Give me all necessary data to create training!")
    course = Course.query.filter_by(id=attrs[6]).first()
    place = Place.query.filter_by(id=attrs[7]).first()
    instructor = get_instructor(attrs[8])
    if None in [course, place]:
        raise BadRequest("course or place with given id does not exist!")
    training = Training(
        attrs[0], attrs[1], attrs[1],
        datetime_from_json(attrs[2]), datetime_from_json(attrs[3]),
        datetime_from_json(attrs[4]), datetime_from_json(attrs[5]),
        course, place, g.user, instructor
    )
    db.session.add(training)
    db.session.commit()
    return training.to_dict()

@bp.route('/<int:id>', methods=['PATCH'])
@only_worker
def edit_training(id):
    request_body = request.form
    training = Training.query.filter_by(id=id).first()
    if training is None:
        raise NotFound("Training with that id does not exist")

    if len(training.participants) > 0:
        raise MethodNotAllowed(
            'Course Cannot have any participants to edit it!')

    price = request_body.get('price')
    if price is not None:
        training.price = float(price)

    places_amount = request_body.get('places_amount')
    if places_amount is not None:
        training.places_amount = int(places_amount)
        training.free_places_amount = int(places_amount)

    begin_date = request_body.get('begin_date')
    if begin_date is not None:
        training.begin_date = datetime_from_json(begin_date)

    end_date = request_body.get('end_date')
    if end_date is not None:
        training.end_date = datetime_from_json(end_date)

    enrolment_begin_date = request_body.get('enrolment_begin_date')
    if enrolment_begin_date is not None:
        training.enrolment_begin_date = datetime_from_json(
            enrolment_begin_date)

    enrolment_end_date = request_body.get('enrolment_end_date')
    if enrolment_end_date is not None:
        training.enrolment_end_date = datetime_from_json(enrolment_end_date)

    place_id = request_body.get('place_id')
    if place_id is not None:
        place = Place.query.filter_by(id=place_id).first()
        if place is None:
            raise BadRequest("Place with that id does not exist!")
        training.place = place

    instructor_id = request_body.get('instructor_id')
    if instructor_id is not None:
        instructor = get_instructor(instructor_id)
        training.instructor = instructor

    db.session.commit()
    return training.to_dict()


import pdfplumber
import re
from datetime import datetime
from decimal import Decimal as D
import collections

from typing import Iterable

from ofxstatement.plugin import Plugin
from ofxstatement.parser import StatementParser
from ofxstatement.statement import Statement, StatementLine

SEPARATOR = ";;;;----;;;;"

class SparkassePlugin(Plugin):
    """Sparkasse plugin (Germany)"""

    def get_parser(self, filename: str) -> "SparkasseParser":
        return SparkasseParser(filename)

class SparkasseParser(StatementParser[str]):
    def __init__(self, filename: str) -> None:
        super().__init__()
        self.filename = filename
        self.ids = {}

    def parse(self) -> Statement:
        """Main entry point for parsers

        super() implementation will call to split_records and parse_record to
        process the file.
        """
        with pdfplumber.open(self.filename) as pdf:
            self.pdf = pdf
            stmt = super().parse()
            stmt.bank_id = "Sparkasse"
            stmt.account_id = self.account_no
            stmt.currency = "EUR" # assume based on country
            return stmt

    def split_records(self) -> Iterable[str]:
        """Return iterable object consisting of a line per transaction"""
        txns = []
        for page in self.pdf.pages:
            state = None
            date = None
            type = None
            sender = None # or receiver
            desc = None
            amount_num = None
            amount_sign = None
            in_transactions = False
            for line in lines(page):
                # TODO: read initial and final balance
                #print(line, ";")
                regex_account_id = r"Girokonto (?P<acct_no>\d+)"
                m = re.search(regex_account_id, line)
                if m is not None:
                    self.account_no = m.group("acct_no")
                    continue
                regex_summary = r"^ ? ?Kontostand am +\d{2}.\d{2}.\d{4} um +\d{2}:\d{2} Uhr"
                if re.search(regex_summary, line) is not None:
                    if date is not None:
                        if amount_sign == "-":
                            amount_num = -amount_num
                        if sender is None:
                                sender = "None"
                        txns.append(date + SEPARATOR + desc + SEPARATOR + sender + SEPARATOR + type + SEPARATOR + str(amount_num))
                        date = None
                    continue
                # transactions look like:
                # 02.03.2020 02.03.2020 Gutschrift e. Überw.
                #                50,00+
                # Sender                       Info/memo
                # 123456ABCD
                # newer format:
                # 01.08.2023 Lastschrift               -32,49
                regex_tx1 = r"^ ?(?P<date>\d{2}\.\d{2}\.\d{4}) \d{2}\.\d{2}\.\d{4} (?P<type>[^+]+) +(?P<amount_num>\d+,\d{2})(?P<amount_sign>[+-])$"
                m = re.search(regex_tx1, line)
                if m is None:
                    regex_tx1c = r"^ ?(?P<date>\d{2}\.\d{2}\.\d{4}) \d{2}\.\d{2}\.\d{4} (?P<type>[^+]+)$"
                    m = re.search(regex_tx1c, line)
                if m is None:
                    regex_tx1b = r"^(?P<date>\d{2}\.\d{2}\.\d{4}) (?P<type>.+) +(?P<amount_sign>[ -])(?P<amount_num>\d+,\d{2})$"
                    m = re.search(regex_tx1b, line)
                if m is not None:
                    #print("NEW TRANSACTION", m, m.groups())
                    # check for previous transaction
                    if date is not None:
                        if amount_sign == "-":
                            amount_num = -amount_num
                        if sender is None:
                            sender = "None"
                        #print(date, desc, sender, type, amount_num)
                        txns.append(date + SEPARATOR + desc + SEPARATOR + sender + SEPARATOR + type + SEPARATOR + str(amount_num))
                        date = None
                    date = m.group("date")
                    type = m.group("type")
                    if "amount_sign" in m.groupdict():
                        amount_num = D(m.group("amount_num").replace(",", "."))
                        amount_sign = m.group("amount_sign")
                        #print(" and", amount_num, amount_sign)
                        desc = None
                        state = "expect_sender"
                    else:
                        state = "expect_amount"
                    continue
                regex_tx2 = r" +(?P<amount_num>\d+,\d{2})(?P<amount_sign>[+-])"
                m = re.search(regex_tx2, line)
                if m is not None:
                    if state != "expect_amount":
                        # check for previous transaction
                        if date is not None:
                            if amount_sign == "-":
                                amount_num = -amount_num
                            if sender is None:
                                sender = "None"
                            txns.append(date + SEPARATOR + desc + SEPARATOR + sender + SEPARATOR + type + SEPARATOR + str(amount_num))
                            date = None
                        continue
                    amount_num = D(m.group("amount_num").replace(",", "."))
                    amount_sign = m.group("amount_sign")
                    state = "expect_sender"
                    continue
                if state == "expect_sender" and not type.startswith("Abrechnung"):
                    # find longest space sequence (two-column layout)
                    found = False
                    for i in range(4, 50):
                        spaces = " " * i
                        if spaces not in line and " " * (i-1) in line:
                            parts = line.split(" " * (i-1))
                            sender = parts[0]
                            desc = parts[1]
                            found = True
                            #print("sd", sender, desc)
                            break
                    if not found:
                        # has to be the one-column layout
                        # (where the sender cannot be determined)
                        sender = None
                        desc = line
                    state = "expect_memo"
                    continue
                if state == "expect_sender" and type.startswith("Abrechnung"):
                    sender = "Sparkasse"
                    desc = line
                    state = "expect_memo"
                    continue
                if state == "expect_memo":
                    # find longest space sequence
                    found = False
                    for i in range(4, 50):
                        spaces = " " * i
                        if spaces not in line and " " * (i-1) in line:
                            parts = line.split(" " * (i-1))
                            if desc is None:
                                desc = parts[0] + " " + parts[1]
                            else:
                                desc = desc + " " + parts[0] + " " + parts[1]
                            found = True
                            break
                    if not found:
                        if desc is None:
                            desc = line
                        else:
                            desc = desc + " " + line
                    continue
            if date is not None:
                if amount_sign == "-":
                    amount_num = -amount_num
                if sender is None:
                    sender = "None"
                txns.append(date + SEPARATOR + desc + SEPARATOR + sender + SEPARATOR + type + SEPARATOR + str(amount_num))
                date = None
        return txns

    def parse_record(self, line: str) -> StatementLine:
        """Parse given transaction line and return StatementLine object"""
        parts = line.split(SEPARATOR)
        date = datetime.strptime(parts[0], "%d.%m.%Y")
        desc = parts[1]
        sender = parts[2]
        type = parts[3]
        m = re.search(r"(?P<type>.+) / Wert: \d{2}.\d{2}.\d{4}", type)
        if m is not None:
            type = m.group("type")
        amount = D(parts[4])
        # ID is simply date + counter
        if parts[0] not in self.ids:
            self.ids[parts[0]] = 0
        id = parts[0] + "-" + str(self.ids[parts[0]] + 1)
        self.ids[parts[0]] = self.ids[parts[0]] + 1
        s = StatementLine(id, date=date, memo=desc, amount=amount)
        if sender != "None":
            s.payee = sender
        s.trntype = "DEBIT"
        if type.startswith("Gutschrift e. Überw.") or type == "Überw. beleglos":
            s.trntype = "XFER"
        elif type.startswith("Abrechnung"):
            s.trntype = "FEE"
        elif type == "Lastschrift":
            s.trntype = "DIRECTDEBIT"
        elif type == "Lohn, Gehalt, Rente":
            # TODO: is there a type for income?
            s.trntype = "XFER"
        elif type == "Kartenzahlung":
            s.trntype = "POS"
        elif type.startswith("Bargeldeinzahlung"):
            s.trntype = "ATM"
        #print(date)
        #print(desc)
        #print(amount)
        return s

def lines(page):
    chars = []
    for obj in page.chars:
        if obj["fontname"] == "Wingdings-Regular" or obj["fontname"] == "ArialMT":
            continue
        if obj["y0"] <= 58:
            continue
        #print(obj["text"], obj["y0"])
        chars.append((-round(obj["y0"]), obj["x0"], obj["text"]))
    chars.sort()
    lines = collections.OrderedDict()
    lastx = 0
    for c in chars:
        y = c[0]
        if y not in lines:
            lines[y] = ""
        if c[1] - lastx > 9.4 or (len(lines[y]) >= 10 and lines[y][-1].isdigit() and c[1] - lastx > 7.6):
            lines[y] = lines[y] + " "
        lines[y] = lines[y] + c[2]
        lastx = c[1]
        #print(y, lines[y])
    return [lines[x] for x in lines]


import pytest
import pandas as pd
import numpy as np
from faker import Faker
from sklearn.datasets import load_iris, fetch_20newsgroups

from feet import pipeline_from_config

iris_predictive_columns = ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
target_column = 'target'

def get_iris_dataframe():
    iris = load_iris()
    df = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                      columns= iris['feature_names'] + ['target'])\
           .assign(target=lambda y: y.target.apply(lambda x: 0 if x == 0 else 1))

    return df[iris["feature_names"]], df['target']

def artificial_text(records=5000):
    fake = Faker()
    data = [{
        "text": fake.text(),
        "name": fake.name(),
        "addy": fake.address(),

    } for i in range(records)]

    return pd.DataFrame(data)

def fetch_20ngs():
    ngs = fetch_20newsgroups(remove=("headers", "footers", "quotes"),
                             categories=['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med'],)
    df = pd.DataFrame([{"text": d[0], "target": d[1]} for d in zip(ngs["data"], ngs["target"])]).dropna()

    return df

def test_text_handling():
    records = 5000
    df = artificial_text(records)

    tfidf_config = {
        "transforms": [
            {
                "type": "featurizer",
                "field": ["text"],
                "transforms": [{"name": "tfidf", "config": {"max_features": 5000}}]
            }
        ]
    }

    tokenizer_config = {
        "transforms": [
            {
                "type": "featurizer",
                "field": ["text"],
                "transforms": [{"name": "tokenizer", "config": {"max_features": 5000}}]
            }
        ]
    }

    hashing_config = {
        "transforms": [
            {
                "type": "featurizer",
                "field": ["text"],
                "transforms": [{"name": "hashing", "config": {"n_features": 5000}}]
            }
        ]
    }

    for config in [tfidf_config, tokenizer_config, hashing_config]:
        pipeline = pipeline_from_config(config)
        X = pipeline.fit_transform(df)

        assert (X.shape[0] == df.shape[0])
        assert (X.shape[0] == records)
        assert (X.shape[1] == 5000)
        assert (X.sum() > 0)

def test_lda_transform():
    records = 5000
    df = artificial_text(records)
    lda_config = {
        "transforms": [
            {
                "type": "featurizer",
                "field": ["text"],
                "transforms": [{"name": "tfidf", "config": {"max_features": 5000}}]
            }
        ],
        "post_process": [
            {"name": "lda", "config": {"rank": 50}}
        ]
    }
    lda_pipeline = pipeline_from_config(lda_config)
    X = lda_pipeline.fit_transform(df)

    assert (X.shape[0] == df.shape[0])
    assert (X.shape[1] == 50)

def test_lda_convenience_transform():
    records = 5000
    df = artificial_text(records)
    lda_config = {
        "transforms": [
            {
                "type": "featurizer",
                "field": ["text"],
                "transforms": [{"name": "lda", "config": {"rank": 50}}]
            }
        ],
    }
    lda_pipeline = pipeline_from_config(lda_config)
    X = lda_pipeline.fit_transform(df)

    assert (X.shape[0] == df.shape[0])
    assert (X.shape[1] == 50)

def test_standard_numeric_transformer():
    df, y = get_iris_dataframe()
    config = {
        "transforms": [
            {
                "type"       : "featurizer",
                "transforms" : [{"name": "standard_numeric"}],
                "field"      : iris_predictive_columns
            }
        ]
    }

    pipeline = pipeline_from_config(config)
    X = pipeline.fit_transform(df)

    assert (X.shape[1] == df.shape[1])
    assert (X.shape[0] == df.shape[0])

    for i in range(X.shape[1]):
        m = X[:, i].mean()
        s = X[:, i].std()

        assert (abs(m) < .1) # close to 0
        assert (abs(s) < 1.1) # close to 1

def test_gaussian_mixture_transformer():
    df, y = get_iris_dataframe()
    config = {
        "post_process": [
            {"name": "gmm", "config": {"clusters": 50}}
        ]
    }

    pipeline = pipeline_from_config(config)
    X = pipeline.fit_transform(df)

    assert (X.shape[1] == 50)
    assert (X.shape[0] == df.shape[0])

def test_kernel_pca():

    df, y = get_iris_dataframe()
    for kernel in ["linear", "poly", "rbf", "sigmoid", "cosine"]:
        config = {
            "post_process": [
                {"name": "kpca", "config": {"n_components": 10, "kernel": kernel}}
            ]
        }

        pipeline = pipeline_from_config(config)
        X = pipeline.fit_transform(df)

        assert (X.shape[1] == 10)
        assert (X.shape[0] == df.shape[0])

def test_handles_process_steps_individually():

    df, target = get_iris_dataframe()

    """ dont throw value error if a config with just a pre_process is passed"""
    pre_process_only_config = {
        "pre_process": [
            {
                "name": "fillna",
                "field": iris_predictive_columns
            }
        ],
    }

    pre_process_only_pipeline = pipeline_from_config(pre_process_only_config)

    pre_process_X = pre_process_only_pipeline.fit_transform(df)
    assert (pre_process_X.shape == df.shape)
    assert (np.isnan(pre_process_X).sum() == 0)

    """ dont throw value error if a config with just transforms are passed"""
    transform_only_config = {
        "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field": iris_predictive_columns}]
    }

    transform_only_pipeline = pipeline_from_config(transform_only_config)

    transform_X = transform_only_pipeline.fit_transform(df)
    assert (transform_X.shape[1] == 101*df.shape[1])

    """ dont throw value error if a config with just a post_process is passed"""
    post_process_only_config = {
        "post_process": [{"name": "svd", "config": {"rank": 2}}]
    }

    post_process_only_pipeline = pipeline_from_config(post_process_only_config)

    post_process_X = post_process_only_pipeline.fit_transform(df)
    assert (post_process_X.shape[1] == 2)

def test_handles_individual_pipeline_components():

    """ dont throw value error if a config with just a pre_process is passed"""
    pre_process_only_config = {
        "pre_process": [
            {
                "name": "fillna",
                "field": iris_predictive_columns,
            }
        ],
    }

    pre_process_only_pipeline = pipeline_from_config(pre_process_only_config)

    """ dont throw value error if a config with just transforms are passed"""
    transform_only_config = {
        "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field": iris_predictive_columns}]
    }

    transform_only_pipeline = pipeline_from_config(transform_only_config)

    """ dont throw value error if a config with just a post_process is passed"""
    post_process_only_config = {
        "post_process": [{"name": "svd", "config": {"rank": 20}}]
    }

    post_process_only_pipeline = pipeline_from_config(post_process_only_config)

def test_throws_exception_on_invalid_inputs():
    with pytest.raises(ValueError):
        config = {
            "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field":None}]
        }
        pipeline = pipeline_from_config(config)

    with pytest.raises(ValueError):
        config = {
            "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field":[]}]
        }
        pipeline = pipeline_from_config(config)

    with pytest.raises(ValueError):
        config = {
            "pre_process": [
            {
                "name": "fillna",
                "field": None
            }
            ],
            "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field": iris_predictive_columns}]
        }
        pipeline = pipeline_from_config(config)

    with pytest.raises(ValueError):
        config = {
            "pre_process": [
            {
                "name": "fillna",
                "field": []
            }
            ],
            "transforms": [{"type":"featurizer", "transforms": [{"name":"quantile_numeric"}], "field": iris_predictive_columns}]
        }
        pipeline = pipeline_from_config(config)

    with pytest.raises(ValueError):
        config = {
            "foo": {
                "bar": "baz"
            }
        }
        pipeline = pipeline_from_config(config)


import json
from pathlib import Path
import mimetypes
from pprint import pprint
from http import HTTPStatus
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseForbidden, FileResponse, Http404
from django.contrib.auth import get_user
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
from django.contrib.messages import success, error
from django.utils.translation import gettext_lazy as _
from django.forms.models import model_to_dict
from django.utils.text import slugify
from django.utils import timezone
from django.urls import reverse_lazy
from django.shortcuts import get_object_or_404
from django_celery_beat.models import CrontabSchedule, PeriodicTask, ClockedSchedule

class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

class ChannelCreateMixin:
    model = None
    form_class = None
    template_name = ''
    redirect_url_namesapce =''
    initial = {}
    context_object_name = None

    def get(self, request, *args, **kwargs):
        channel_form = self.form_class()
        context = {'form': channel_form}

        return render(request, self.template_name, context)

    @method_decorator(csrf_protect)
    def post(self, request, *args, **kwargs):

        if request.user.is_authenticated:

            channel_form = self.form_class(request.POST, request.FILES)

            if channel_form.is_valid():
                channel_form.save(request=request)
                success(request, _('Channel Created'))
                return redirect(self.get_success_url(request))
            else:
                context = {'form': channel_form}
                error(request, _("Please make corrections to the error(s) below"))
                return render(request, self.template_name, context)

    def get_success_url(self, request):
        username = request.POST['username']
        self.success_url = reverse_lazy(
            f'{self.redirect_url_namesapce}:{self.model.__name__.lower()}_detail',
            kwargs={'slug':slugify(username)}
        )
        return self.success_url

class ChannelUpdateMixin:
    model = None
    form_class = None
    template_name = ''
    redirect_url_namespace = ''
    initial  = {}
    context_object_name = None

    def get(self, request, slug, *args, **kwargs):
        channel = get_object_or_404(self.model, slug__iexact=slug)
        user = get_user(request)
        co_host = ', '.join(
            [host.username for host in channel.hosts.all() if not host == user])

        self.initial = model_to_dict(channel)
        self.initial['co_host']  = co_host

        channel_form = self.form_class(instance=channel, initial=self.initial)
        context = {
            'form': channel_form,
            self.context_object_name : channel
        }

        return render(request, self.template_name, context)

    @method_decorator(csrf_protect)
    def post(self, request, slug, *args, **kwargs):

        channel = get_object_or_404(self.model, slug__iexact=self.kwargs.get('slug'))

        hosts = channel.hosts.all()
        if request.user.is_authenticated and request.user in hosts:
            channel_form = self.form_class(request.POST, request.FILES,
                                           instance=channel, initial=self.initial)

            if channel_form.is_valid():
                channel_form.save(request)
                success(request, _("Channel Updated!!"))
                return redirect(self.get_success_url(request))
            else:
                context = {
                    'form': channel_form,
                    self.context_object_name: channel
                }
                error(request, _("Please make corrections to the error(s) below"))
                return render(request, self.template_name, context)

    def get_success_url(self, request):
        username = request.POST['username']
        self.success_url = reverse_lazy(
            f'{self.redirect_url_namesapce}:{self.model.__name__.lower()}_detail',
            kwargs={'slug': slugify(username)}
        )
        return self.success_url

class ChannelSubscribeMixin:
    model = None

    def get(self, request, *args, **kwargs):
        return HttpResponseForbidden("this Page is Forbidden")

    def post(self, request, *args, **kwargs):
        channel = self.model.objects.get(slug__iexact=self.kwargs.get('slug'))

        user = get_user(request)
        if user in channel.subscribers.all():
            channel.subscribers.remove(user)
        else:
            channel.subscribers.add(user, through_defaults={'subscribed': True})

        return render(request, "podcasts/partials/channel_subscribe.html",
                      {'channel': channel})

class EpisodeCreateMixin:
    model = None
    channel_model =None
    form_class = None
    template_name = ''
    redirect_url_namesapce =''
    initial = {}
    context_object_name = None

    def get(self, request, slug, *args, **kwargs):
        channel = get_object_or_404(self.channel_model, slug__iexact=slug)
        episode_form = self.form_class()
        context = {'form': episode_form,
                   'channel': channel}

        return render(request, self.template_name, context)

    @method_decorator(csrf_protect)
    def post(self, request, *args, **kwargs):

        channel = get_object_or_404(self.channel_model, slug__iexact=self.kwargs.get('slug'))

        hosts = channel.hosts.all()
        if request.user.is_authenticated and request.user in hosts:

            if request.htmx:
                if request.POST.get("episode_uuid", ''):
                    episode = self.model.objects.get(id__iexact=request.POST.get("episode_uuid"))

                    self.initial = model_to_dict(episode)
                    episode_form = self.form_class(request.POST, request.FILES,
                                                   instance=episode, initial=self.initial)

                else:
                    episode_form = self.form_class(request.POST, request.FILES)

                if episode_form.is_valid():
                    hx = False

                    ep = episode_form.save(request, channel, hx)

                    context = {'episode': ep}

                    return render(request, 'podcasts/partials/episode_create_partial.html', context)

                else:
                    context = {'form': episode_form}
                    error(request, _("Please make corrections to the error(s) below"))
                    return HttpResponseNoContent(_("Please make corrections to the error(s) below"))

            else:
                episode = self.model.objects.get(id__iexact=request.POST.get('episode_uuid'))

                self.initial = model_to_dict(episode)
                # episode_file = request.FILES.pop('episode')
                episode_form = self.form_class(request.POST, request.FILES,
                                            instance=episode, initial=self.initial)
                if episode_form.is_valid():
                    episode_form.save()

                    success(request, _('Episode Created'))
                    return redirect(self.get_success_url(request))
                else:
                    context = {'form': episode_form}
                    error(request, _("Please make corrections to the error(s) below"))
                    return render(request, self.template_name, context)

    def get_success_url(self, request):
        return reverse_lazy('channel_urls:channel_episodes', kwargs={'slug':self.kwargs.get('slug')})

class EpisodeUpdateMixin:
    model = None
    channel_model = None
    form_class = None
    template_name = ''
    redirect_url_namespace = ''
    initial  = {}
    context_object_name = ''

    def get(self, request, *args, **kwargs):
        channel = get_object_or_404(self.channel_model, slug__iexact=kwargs.get('slug'))
        episode = self.get_object()
        user = get_user(request)
        # co_host = ', '.join(
        #     [host.username for host in channel.hosts.all() if not host == user])

        self.initial = model_to_dict(episode)
        # self.initial['co_host']  = co_host

        episode_form = self.form_class(instance=episode, initial=self.initial)
        context = {
            'form': episode_form,
            self.context_object_name : episode
        }

        return render(request, self.template_name, context)

    @method_decorator(csrf_protect)
    def post(self, request, *args, **kwargs):
        channel = get_object_or_404(self.channel_model, slug__iexact=kwargs.get('slug'))

        hosts = channel.hosts.all()
        if request.user.is_authenticated and request.user in hosts:
            if request.htmx:

                episode = self.get_object()

                self.initial = model_to_dict(episode)
                episode_form = self.form_class(request.POST or None, request.FILES or None,
                                               instance=episode, initial=self.initial)

                if episode_form.is_valid():
                    hx = False

                    ep = episode_form.save(request, channel, hx)

                    context = {'episode': ep}

                    return render(request, 'podcasts/partials/episode_create_partial.html', context)

                else:
                    context = {'form': episode_form}
                    error(request, _("Please make corrections to the error(s) below"))
                    return HttpResponseNoContent(_("Please make corrections to the error(s) below"))

            else:
                episode = self.get_object()

                self.initial = model_to_dict(episode)
                # episode_file = request.FILES.pop('episode')
                episode_form = self.form_class(request.POST or None, request.FILES or None,
                                            instance=episode, initial=self.initial)
                if episode_form.is_valid():
                    episode_form.save()

                    success(request, _('Episode Updated'))
                    return redirect(self.get_success_url(request))
                else:
                    context = {'form': episode_form}
                    error(request, _("Please make corrections to the error(s) below"))
                    return render(request, self.template_name, context)

    def get_success_url(self, request):
        # username = request.POST['username']
        # self.success_url = reverse_lazy(
        #     f'{self.redirect_url_namesapce}:{self.model.__name__.lower()}_detail',
        #     kwargs={'slug': slugify(username)}
        # )
        print(self.kwargs)
        return reverse_lazy('channel_urls:channel_episodes', kwargs={
                                                            'slug': self.kwargs.get('slug')})

    def get_object(self):
        episode = get_object_or_404(self.model, id__iexact=str(self.kwargs.get('id')))
        return episode

class EpisodeLikeMixin:
    model = None

    def get(self, request, *args, **kwargs):
        return HttpResponseForbidden("this Page is Forbidden")

    def post(self, request, *args, **kwargs):
        episode = self.model.objects.get(id__iexact=str(self.kwargs.get('id')))

        user = get_user(request)
        if user in episode.likes.all():
            episode.likes.remove(user)
        else:
            if user in episode.dislikes.all():
                episode.dislikes.remove(user)
            episode.likes.add(user, through_defaults={'liked': True})

        return render(request, "podcasts/partials/episode_like_dislike.html",
                      {'episode': episode})

class EpisodeDislikeMixin:
    model = None

    def get(self, request, *args, **kwargs):
        return HttpResponseForbidden("
this Page is Forbidden
")

    def post(self, request, *args, **kwargs):
        episode = self.model.objects.get(id__iexact=str(self.kwargs.get('id')))

        user = get_user(request)
        if user in episode.dislikes.all():
            episode.dislikes.remove(user)
        else:
            if user in episode.likes.all():

                episode.likes.remove(user)

            episode.dislikes.add(user, through_defaults={'disliked': True})

        return render(request, "podcasts/partials/episode_like_dislike.html",
                      {'episode': episode})

class EpisodePublishNowMixin:
    model  = None

    def post(self, request, *args, **kwargs):
        episode = get_object_or_404(self.model, id__iexact=str(self.kwargs.get('id')))
        # episode = self.model.objects.get(id__iexact=str(self.kwargs.get('id')))

        if episode.publish_date:
            episode.status = 'Withdrawn'
            episode.publish_date = None
            try:
                task = PeriodicTask.objects.get(name=f'publish_{episode.id}_at_{episode.publish_date.day}/{episode.publish_date.month}/{episode.publish_date.year}:{episode.publish_date.hour}:{episode.publish_date.minute}:{episode.publish_date.second}')
                print(task)
                task.delete()
            except:
                print('ignored')

        else:
            episode.publish_date = timezone.now()
            episode.status = 'Published'
        episode.save()

        return render(request, "podcasts/partials/episode_status.html",
                      {'episode': episode})

class EpisodePublishLaterMixin:
    model = None
    form_class = None

    def get(self, request, *args, **kwargs):
        episode = get_object_or_404(self.model, id__iexact=str(self.kwargs.get('id')))
        self.initial = model_to_dict(episode)
        episode_form = self.form_class(instance=episode, initial=self.initial)
        context = {
            'episode': episode,
            'form': episode_form,
        }
        return render(request,
                      "podcasts/partials/episode_publish_later.html",
                      context)

    def post(self, request, *args, **kwargs):
        episode = get_object_or_404(self.model, id__iexact=str(self.kwargs.get('id')))

        episode_form = self.form_class(request.POST or None,
                                               instance=episode)

        if episode_form.is_valid():
            episode = episode_form.save()

            pub_date = episode.publish_date
            success(request, _(f'Episode will be available on {pub_date.day}/{pub_date.month}'
            f'/{pub_date.year} at {pub_date.hour}:{pub_date.minute}'))
            return render(request, "podcasts/partials/episode_status.html",
                          {'episode': episode})
        else:
            context = {'form': episode_form,
                       'episode': episode}
            error(request, _("Please make corrections to the error(s) below"))
            return render(request,
                          "podcasts/partials/episode_publish_later.html",
                          context)

class EpisodeListenerMixin:
    model = None

    def get(self, request, *args, **kwargs):
        return HttpResponseForbidden("
this Page is Forbidden
")

    def post(self, request, *args, **kwargs):
        episode = self.model.objects.get(id__iexact=str(self.kwargs.get('id')))

        print(request.POST)
        user = get_user(request)
        print(user)
        pprint(request.META)
        print(type(request.META))
        self.time_listened = float(request.META.get('HTTP_CURRENT', 0))
        self.start_time = float(request.META.get('HTTP_START', 0))
        self.start = request.META.get('HTTP_PLAYING', 'no')
        print('self.start', self.start)
        print(self.time_listened)
        print('start time', self.start_time)
        print('start again', self.start)
        self.time_streamed_percent = 0.3 * episode.duration
        self.time_listened_percent = 0.95 * episode.duration
        self.start_time_percent = 0.05 * episode.duration
        print(self.time_listened_percent)
        print(episode.duration)

        if user in episode.listeners.all():
            print('I CAME HERE IS ALL CAPS')
            listener = episode.listeners.through.objects.get(user=user, episode=episode)
            if self.start == 'yes':
                'this will be from a play button'
                listener.start_time = self.start_time
                listener.save()
                print('start time after save ', listener.start_time)
                return HttpResponse('Playing')

            else:
                #this will be from a pause button"
                self.start_time = listener.start_time
                listener.time_listened = self.time_listened
                if self.start_time < self.start_time_percent and self.time_listened >= self.time_streamed_percent:
                    listener.streams += 1
                if self.start_time < self.start_time_percent and self.time_listened >= self.time_listened_percent:
                    listener.streams += 1
                    listener.completed_count += 1
                    if not listener.listened:
                        listener.listened = True
                listener.save()
                print('start time after save pause ', listener.start_time)
                print('current time after save pause', listener.time_listened)
                return HttpResponse('Paused')

        else:
            print('I CAME HERE IS ALL CAPS 2!!!')
            episode.listeners.add(user, through_defaults={'start_time': self.start_time})

            return HttpResponse('Playing')

class DownloadEpisodeMixin:

    model  = None

    def get(self, request, *args, **kwargs):
        episode = self.model.objects.get(id__iexact=str(self.kwargs.get('id')))

        path = episode.episode.path
        fullpath = Path(path)
        if fullpath.is_dir():
            raise Http404(_("Direcotry indexes are not allowed here."))

        if not fullpath.exists():
            raise Http404(_('“%(path)s” does not exist') % {'path': fullpath})

        statobj = fullpath.stat()

        content_type, encoding = mimetypes.guess_type(str(fullpath))
        content_type = content_type or 'application/octet-stream'
        response = FileResponse(fullpath.open('rb'), as_attachment=True)
        response.headers['Content-Length'] = statobj.st_size
        response.headers['Accept-Ranges'] = 'bytes'
        response.headers['Content-Type'] = content_type
        if encoding:
            response.headers['Content-Encoding'] = encoding

        return response


from tempfile import TemporaryDirectory
from typing import List

import torch

from robot_demo.utils.image import visualize_joint_prediction
from robot_demo.utils.movie import combine_gifs, save_movie_gif

from .utils import plot_spatial_softmax, setup

@torch.inference_mode()
def open_loop(model_name: str, batch_indices: List[int]) -> None:
    report_dir, model, datamodule = setup(model_name, "open_loop")

    model.init_hidden(batch_size=datamodule.actions.shape[0])
    output = model(
        actions=datamodule.actions,
        observations=datamodule.observations,
        goals=datamodule.goals,
    )
    for batch_idx in batch_indices:
        visualize_joint_prediction(
            target_data=datamodule.actions[batch_idx],
            pred_data=output["action_prediction"][batch_idx],
            save_path=f"{report_dir}/action_{batch_idx}.png",
        )
        with TemporaryDirectory() as tmp_dir:
            paths = [f"{tmp_dir}/obs.gif", f"{tmp_dir}/pred.gif"]
            save_movie_gif(
                movie=datamodule.observations[batch_idx],
                label="observation",
                output_path=paths[0],
            )
            save_movie_gif(
                movie=output["observation_prediction"][batch_idx],
                label="prediction",
                output_path=paths[1],
            )
            output_path = f"{report_dir}/obs_pred_{batch_idx}.gif"
            combine_gifs(*paths, rows=2, output_path=output_path)

@torch.inference_mode()
def feature_points(model_name: str, batch_indices: List[int]) -> None:
    report_dir, model, datamodule = setup(model_name, "open_loop")
    with TemporaryDirectory() as tmp_dir:
        paths = []
        for batch_index in batch_indices:
            observation = plot_spatial_softmax(
                observation=datamodule.observations[batch_index],
                encoder=model.spatial_encoder._conv,
            )
            path = f"{tmp_dir}/feature_points_{batch_index}.gif"
            paths.append(path)
            save_movie_gif(
                movie=observation,
                label=str(batch_index),
                output_path=path,
            )
        output_path = f"{report_dir}/feature_points.gif"
        combine_gifs(*paths, rows=2, output_path=output_path)


import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

img = cv.imread('C:/Users/HASEE/Desktop/Pycharm_Project/images/landscape_2.jpeg', 1)
img_B = img.copy()
img_G = img.copy()
img_R = img.copy()

# set channel of R to 0
img_R[81:110, 108:147, 0] = 0
ax1 = plt.subplot(221)
ax1.set_title('R')
plt.axis('off')
plt.imshow(img_R)

# set channel of G to 0
img_G[81:110, 108:147, 1] = 0
ax2 = plt.subplot(222)
ax2.set_title('G')
plt.axis('off')
plt.imshow(img_G)

# set channel of B to 0
img_B[81:110, 108:147, 2] = 0
ax3 = plt.subplot(223)
ax3.set_title('B')
plt.axis('off')
plt.imshow(img_B)

# display the raw image
ax4 = plt.subplot(224)
ax4.set_title('raw image')
plt.axis('off')
plt.imshow(img)
plt.show()


'''
API kurs mata uang
'''

import requests
kode = input('ketik bank: ')
data = requests.get(f'https://kurs.web.id/api/v1/{kode}')
data1 = requests.get('https://blockchain.info/ticker')
error_code = data.json()['error']

if error_code == 'true':
    print('bank tidak ada')
else:
    print('1.USD>IDR\n2.IDR>USD\n3.USD>Bitcoin\n4.Bitcoin>USD\n5.IDR>Bitcoin\n6.Bitcoin>IDR')
    quest = int(input('masukan 1/2/3/4/5/6: '))
    kurs_jual = float(data.json()['jual'])
    kurs_beli = float(data.json()['beli'])
    value = data1.json()['USD']['buy']
    if quest == 1:
        nominal = float(input('masukan nominal USD: '))
        convert_result = (nominal * kurs_jual)
        print(f'{nominal} USD = Rp {round(convert_result,2)}')
        print(f'{kode.upper()}: kurs jual = {kurs_jual} dan kurs beli = {kurs_beli}')
    elif quest == 2:
        nominal = float(input('masukan nominal Rp: '))
        convert_result = (nominal / kurs_beli)
        print(f'{nominal} Rp = USD {round(convert_result,2)}')
        print(f'{kode.upper()}: kurs jual = {kurs_jual} dan kurs beli = {kurs_beli}')
    elif quest == 3:
        nominal = float(input('masukan nominal USD: '))
        convert_result = (nominal / value)
        print(f'{nominal} USD = Bitcoin {convert_result}')
    elif quest == 4:
        nominal = float(input('masukan nominal Bitcoin: '))
        convert_result = (nominal * value)
        print(f'{nominal} Bitcoin = USD {convert_result}')
    elif quest == 5:
        nominal = float(input('masukan nominal IDR: '))
        idr_to_usd = (nominal/kurs_beli)
        convert_result = (idr_to_usd/value)
        print(f'{nominal} IDR = Bitcoin {convert_result}')
    elif quest == 6:
        nominal = float(input('masukan nominal Bitcoin: '))
        bit_to_usd = (nominal*kurs_jual)
        convert_result = (bit_to_usd*value)
        print(f'{nominal} Bitcoin = IDR {convert_result}')
    else:
        print('tidak ada menu pilihan')


""" An example ICAP service that modifies response content.

Try visiting:

    $ export http_proxy=http://localhost:3128
    $ curl http://www.example.net/

And look for '
Modifed Example Domain
'

"""

import logging
from icapservice import ICAPService, OK

class Modify(ICAPService):

    abs_path = '/respmod'

    def RESPMOD(self, icap_request):
        http_response, chunks = icap_request.modify_http_response()
        return OK(http_response=http_response, chunks=self.modify_chunks(chunks))

    def modify_chunks(self, chunks):
        before  = 'Example Domain'
        after = before.replace('Example', 'Modified Example')
        for chunk in chunks:
            if before in chunk:
                chunk = chunk.replace(before, after)
            yield chunk

def main():
    logging.basicConfig(level=logging.INFO)
    Modify().icap_handler_class().server().serve_forever()

if __name__ == '__main__':
    main()


import tensorflow as tf
import numpy as np
import cv2 as cv

class DataGenerator(tf.keras.utils.Sequence):
    def __init__(self, ids, mask, image_dir='./', batch_size=2, img_h=256, img_w=256, shuffle=True):

        self.ids = ids
        self.mask = mask
        self.image_dir = image_dir
        self.batch_size = batch_size
        self.img_h = img_h
        self.img_w = img_w
        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        return int(np.floor(len(self.ids)) / self.batch_size)

    def __getitem__(self, index):
        indexes = self.indexes[index * self.batch_size: (index + 1) * self.batch_size]
        list_ids = [self.ids[i] for i in indexes]
        list_mask = [self.mask[i] for i in indexes]
        X, y = self.__data_generation(list_ids, list_mask)

        return X, y

    def on_epoch_end(self):
        self.indexes = np.arange(len(self.ids))

        if self.shuffle:
            np.random.shuffle(self.indexes)

    def __data_generation(self, list_ids, list_mask):
        X = np.empty((self.batch_size, self.img_h, self.img_w, 3))
        y = np.empty((self.batch_size, self.img_h, self.img_w, 1))

        for i in range(len(list_ids)):
            img_path = str(list_ids[i])

            mask_path = str(list_mask[i])

            img = cv.cvtColor(cv.imread(img_path), cv.COLOR_BGR2RGB)
            mask = cv.cvtColor(cv.imread(mask_path), cv.COLOR_BGR2GRAY)

            img = cv.resize(img, (self.img_h, self.img_w))
            img = np.array(img, dtype=np.float64)

            mask = cv.resize(mask, (self.img_h, self.img_w))
            mask = np.array(mask, dtype=np.float64)

            img -= img.mean()
            img /= img.std()

            mask -= mask.mean()
            mask /= mask.std()

            X[i,] = img
            y[i,] = np.expand_dims(mask, axis=2)

        y = (y > 0).astype(int)

        return X, y


import dimod
import numpy as np

from src.linear_regression import build_precision_matrix, build_precision_two_complement_fixed_point, build_Q
from src.utils import load_dict, save_dict

def get_precision(num_bits: int, num_weights: int, point_position: float) -> None:
    save_dict(
        to_save={
            'precision': build_precision_matrix(
                num_weights=num_weights,
                precision=build_precision_two_complement_fixed_point(
                    num_bits=num_bits,
                    point_position=point_position
                )
            ).tolist()
        },
        output_file='precision_matrix.json'
    )

def get_problem_matrix(precision_matrix, preprocessed_dataset) -> None:
    precision = load_dict(precision_matrix)['precision']
    dataset = load_dict(preprocessed_dataset)
    precision = np.asarray(precision)
    x = np.asarray(dataset['x'])
    y = np.asarray(dataset['y'])

    save_dict(
        to_save={
            'q': build_Q(
                precision_matrix=precision,
                feature_matrix=x,
                target_matrix=y
            ).tolist()
        },
        output_file='q.json'
    )

def anneal(q, precision_matrix) -> None:
    q = np.asarray(
        load_dict(q)['q']
    )

    precision = load_dict(precision_matrix)['precision']
    precision = np.asarray(precision)

    array_bqm = dimod.AdjArrayBQM(q, 'BINARY')

    sample_set = dimod.SimulatedAnnealingSampler().sample(array_bqm)

    w_binary = np.asarray(list(sample_set.first.sample.values()))

    w_approx = precision.dot(w_binary)

    save_dict(
        {
            'solution': w_approx.tolist()
        },
        'solution.json'
    )


from PIL import Image
import PIL.ImageOps
from torchvision import transforms

tran = transforms.ToTensor()

images = ['1.jpeg', '2.jpeg', '3.jpeg', '4.jpeg',
          '5.jpeg', '6.jpeg', '7.jpeg', '8.jpeg', '9.jpeg']

# Para transformar la imagen a una escala de un solo color
rgb_weights = [0.2989, 0.5870, 0.1140]

# pred = np.argmax(model.predict(test))
# print('Predicted {}'.format(pred))

fig, axs = plt.subplots(nrows=3, ncols=3, figsize=(12, 4))
preds = []
for i, ax in enumerate(axs.flatten()):

  # Abrimos la imagen
  image1 = Image.open(images[i]).resize((28, 28), Image.ANTIALIAS)
  image1 = PIL.ImageOps.invert(image1)
  image_np = np.array(image1)
  image_np = np.dot(image_np[..., :3], rgb_weights)

  # Lo ponemos en formato para que lo entienda la red
  test = np.array([image_np]*128)
  test = tf.expand_dims(test, 3)
  plt.sca(ax)

  preds.append(model.predict(test)[0])
  plt.imshow(test[0].reshape(28, 28))
  plt.title('Predicted: {}'.format(np.argmax(preds[i])))

plt.suptitle('Predicciones')
plt.show()


import itertools
import logging
import os
import plistlib
import re
import subprocess
import time

from webkitpy.benchmark_runner.utils import timeout
from webkitpy.common.host import Host

_log = logging.getLogger(__name__)

"""
Minimally wraps CoreSimulator functionality through simctl.

If possible, use real CoreSimulator.framework functionality by linking to the framework itself.
Do not use PyObjC to dlopen the framework.
"""

class DeviceType(object):
    """
    Represents a CoreSimulator device type.
    """
    def __init__(self, name, identifier):
        """
        :param name: The device type's human-readable name
        :type name: str
        :param identifier: The CoreSimulator identifier.
        :type identifier: str
        """
        self.name = name
        self.identifier = identifier

    @classmethod
    def from_name(cls, name):
        """
        :param name: The name for the desired device type.
        :type name: str
        :returns: A `DeviceType` object with the specified identifier or throws a TypeError if it doesn't exist.
        :rtype: DeviceType
        """
        identifier = None
        for device_type in Simulator().device_types:
            if device_type.name == name:
                identifier = device_type.identifier
                break

        if identifier is None:
            raise TypeError('A device type with name "{name}" does not exist.'.format(name=name))

        return DeviceType(name, identifier)

    @classmethod
    def from_identifier(cls, identifier):
        """
        :param identifier: The CoreSimulator identifier for the desired runtime.
        :type identifier: str
        :returns: A `Runtime` object witht the specified identifier or throws a TypeError if it doesn't exist.
        :rtype: DeviceType
        """
        name = None
        for device_type in Simulator().device_types:
            if device_type.identifier == identifier:
                name = device_type.name
                break

        if name is None:
            raise TypeError('A device type with identifier "{identifier}" does not exist.'.format(
                identifier=identifier))

        return DeviceType(name, identifier)

    def __eq__(self, other):
        return (self.name == other.name) and (self.identifier == other.identifier)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __repr__(self):
        return '<DeviceType "{name}": {identifier}>'.format(name=self.name, identifier=self.identifier)

class Runtime(object):
    """
    Represents a CoreSimulator runtime associated with an iOS SDK.
    """

    def __init__(self, version, identifier, available, devices=None, is_internal_runtime=False):
        """
        :param version: The iOS SDK version
        :type version: tuple
        :param identifier: The CoreSimulator runtime identifier
        :type identifier: str
        :param availability: Whether the runtime is available for use.
        :type availability: bool
        :param devices: A list of devices under this runtime
        :type devices: list or None
        :param is_internal_runtime: Whether the runtime is an Apple internal runtime
        :type is_internal_runtime: bool
        """
        self.version = version
        self.identifier = identifier
        self.available = available
        self.devices = devices or []
        self.is_internal_runtime = is_internal_runtime

    @classmethod
    def from_version_string(cls, version):
        return cls.from_identifier('com.apple.CoreSimulator.SimRuntime.iOS-' + version.replace('.', '-'))

    @classmethod
    def from_identifier(cls, identifier):
        """
        :param identifier: The identifier for the desired CoreSimulator runtime.
        :type identifier: str
        :returns: A `Runtime` object with the specified identifier or throws a TypeError if it doesn't exist.
        :rtype: Runtime
        """
        for runtime in Simulator().runtimes:
            if runtime.identifier == identifier:
                return runtime
        raise TypeError('A runtime with identifier "{identifier}" does not exist.'.format(identifier=identifier))

    def __eq__(self, other):
        return (self.version == other.version) and (self.identifier == other.identifier) and (self.is_internal_runtime == other.is_internal_runtime)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __repr__(self):
        version_suffix = ""
        if self.is_internal_runtime:
            version_suffix = " Internal"
        return '<Runtime {version}: {identifier}. Available: {available}, {num_devices} devices>'.format(
            version='.'.join(map(str, self.version)) + version_suffix,
            identifier=self.identifier,
            available=self.available,
            num_devices=len(self.devices))

# FIXME: This class is fragile because it parses the output of the simctl command line utility, which may change.
#        We should find a better way to query for simulator device state and capabilities. Maybe take a similiar
#        approach as in webkitdirs.pm and utilize the parsed output from the device.plist files in the sub-
#        directories of ~/Library/Developer/CoreSimulator/Devices?
#        Also, simctl has the option to output in JSON format (xcrun simctl list --json).
class Simulator(object):
    """
    Represents the iOS Simulator infrastructure under the currently select Xcode.app bundle.
    """
    device_type_re = re.compile('(?P<name>.+)\((?P<identifier>[^)]+)\)')
    # FIXME: runtime_re parses the version from the runtime name, but that does not contain the full version number
    # (it can omit the revision). We should instead parse the version from the number contained in parentheses.
    runtime_re = re.compile(
        '(i|watch|tv)OS (?P<version>\d+\.\d)(?P<internal> Internal)? \(\d+\.\d+(\.\d+)? - (?P<build_version>[^)]+)\) \((?P<identifier>[^)]+)\)( \((?P<availability>[^)]+)\))?')
    unavailable_version_re = re.compile('-- Unavailable: (?P<identifier>[^ ]+) --')
    version_re = re.compile('-- (i|watch|tv)OS (?P<version>\d+\.\d+)(?P<internal> Internal)? --')
    devices_re = re.compile(
        '\s*(?P<name>.+) \((?P<udid>[^)]+)\) \((?P<state>[^)]+)\)( \((?P<availability>[^)]+)\))?')

    managed_devices = {}
    Device = None

    def __init__(self, host=None):
        # FIXME: This circular import should be resolved.
        if not Simulator.Device:
            from webkitpy.xcode.simulated_device import SimulatedDevice
            Simulator.Device = SimulatedDevice

        self._host = host or Host()
        self.runtimes = []
        self.device_types = []
        self.refresh()

    # Keep these constants synchronized with the SimDeviceState constants in CoreSimulator/SimDevice.h.
    class DeviceState:
        DOES_NOT_EXIST = -1
        CREATING = 0
        SHUTDOWN = 1
        BOOTING = 2
        BOOTED = 3
        SHUTTING_DOWN = 4

    NAME_FOR_STATE = [
        'CREATING',
        'SHUTDOWN',
        'BOOTING',
        'BOOTED',
        'SHUTTING_DOWN'
    ]

    @staticmethod
    def create_device(number, device_type, runtime):
        device = Simulator().lookup_or_create_device(device_type.name + ' WebKit Tester' + str(number), device_type, runtime)
        _log.debug('created device {} {}'.format(number, device))
        assert(len(Simulator.managed_devices) == number)
        Simulator.managed_devices[number] = device

    @staticmethod
    def remove_device(number):
        if not Simulator.managed_devices[number]:
            return
        device_udid = Simulator.managed_devices[number].udid
        _log.debug('removing device {} {}'.format(number, device_udid))
        del Simulator.managed_devices[number]
        Simulator.delete_device(device_udid)

    @staticmethod
    def device_number(number):
        return Simulator.managed_devices[number]

    @staticmethod
    def device_state_description(state):
        if (state == Simulator.DeviceState.DOES_NOT_EXIST):
            return 'DOES_NOT_EXIST'
        return Simulator.NAME_FOR_STATE[state]

    @staticmethod
    def wait_until_device_is_booted(udid, timeout_seconds=60 * 5):
        Simulator.wait_until_device_is_in_state(udid, Simulator.DeviceState.BOOTED, timeout_seconds)
        with timeout(seconds=timeout_seconds):
            while True:
                try:
                    state = subprocess.check_output(['xcrun', 'simctl', 'spawn', udid, 'launchctl', 'print', 'system']).strip()
                    _log.debug('xcrun simctl spawn %s', udid)

                    if re.search("A[\s]+com.apple.springboard.services", state):
                        return
                except subprocess.CalledProcessError:
                    if Simulator.device_state(udid) != Simulator.DeviceState.BOOTED:
                        raise RuntimeError('Simuator device quit unexpectedly.')
                    _log.warn("Error in checking Simulator boot status. Will retry in 1 second.")
                time.sleep(1)

    @staticmethod
    def wait_until_device_is_in_state(udid, wait_until_state, timeout_seconds=60 * 5):
        _log.debug('waiting for device %s to enter state %s with timeout %s', udid, Simulator.device_state_description(wait_until_state), timeout_seconds)
        with timeout(seconds=timeout_seconds):
            device_state = Simulator.device_state(udid)
            while (device_state != wait_until_state):
                device_state = Simulator.device_state(udid)
                _log.debug(' device state %s', Simulator.device_state_description(device_state))
                time.sleep(0.5)

        end_state = Simulator.device_state(udid)
        if (end_state != wait_until_state):
            raise RuntimeError('Timed out waiting for simulator device to enter state {0}; current state is {1}'.format(Simulator.device_state_description(wait_until_state), Simulator.device_state_description(end_state)))

    @staticmethod
    def device_state(udid):
        device_plist = os.path.join(Simulator.device_directory(udid), 'device.plist')
        if not os.path.isfile(device_plist):
            return Simulator.DeviceState.DOES_NOT_EXIST
        return plistlib.readPlist(device_plist)['state']

    @staticmethod
    def device_directory(udid):
        return os.path.realpath(os.path.expanduser(os.path.join('~/Library/Developer/CoreSimulator/Devices', udid)))

    @staticmethod
    def delete_device(udid):
        Simulator.Device.delete(udid)

    @staticmethod
    def reset_device(udid):
        Simulator.Device.reset(udid)

    def refresh(self):
        """
        Refresh runtime and device type information from ``simctl list``.
        """
        lines = self._host.platform.xcode_simctl_list()
        if not lines:
            return
        device_types_header = next(lines)
        if device_types_header != '== Device Types ==':
            raise RuntimeError('Expected == Device Types == header but got: "{}"'.format(device_types_header))
        self._parse_device_types(lines)

    def _parse_device_types(self, lines):
        """
        Parse device types from ``simctl list``.
        :param lines: A generator for the output lines from ``simctl list``.
        :type lines: genexpr
        :return: None
        """
        for line in lines:
            device_type_match = self.device_type_re.match(line)
            if not device_type_match:
                if line != '== Runtimes ==':
                    raise RuntimeError('Expected == Runtimes == header but got: "{}"'.format(line))
                break
            device_type = DeviceType(name=device_type_match.group('name').rstrip(),
                                     identifier=device_type_match.group('identifier'))
            self.device_types.append(device_type)

        self._parse_runtimes(lines)

    def _parse_runtimes(self, lines):
        """
        Continue to parse runtimes from ``simctl list``.
        :param lines: A generator for the output lines from ``simctl list``.
        :type lines: genexpr
        :return: None
        """
        for line in lines:
            runtime_match = self.runtime_re.match(line)
            if not runtime_match:
                if line != '== Devices ==':
                    raise RuntimeError('Expected == Devices == header but got: "{}"'.format(line))
                break
            version = tuple(map(int, runtime_match.group('version').split('.')))
            runtime = Runtime(version=version,
                              identifier=runtime_match.group('identifier'),
                              available=runtime_match.group('availability') is None,
                              is_internal_runtime=bool(runtime_match.group('internal')))
            self.runtimes.append(runtime)
        self._parse_devices(lines)

    def _parse_devices(self, lines):
        """
        Continue to parse devices from ``simctl list``.
        :param lines: A generator for the output lines from ``simctl list``.
        :type lines: genexpr
        :return: None
        """
        current_runtime = None
        for line in lines:
            version_match = self.version_re.match(line)
            if version_match:
                version = tuple(map(int, version_match.group('version').split('.')))
                current_runtime = self.runtime(version=version, is_internal_runtime=bool(version_match.group('internal')))
                assert current_runtime
                continue

            unavailable_version_match = self.unavailable_version_re.match(line)
            if unavailable_version_match:
                current_runtime = None
                continue

            device_match = self.devices_re.match(line)
            if not device_match:
                if line != '== Device Pairs ==':
                    raise RuntimeError('Expected == Device Pairs == header but got: "{}"'.format(line))
                break
            if current_runtime:
                device = Simulator.Device(name=device_match.group('name').rstrip(),
                                udid=device_match.group('udid'),
                                available=device_match.group('availability') is None,
                                runtime=current_runtime,
                                host=self._host)
                current_runtime.devices.append(device)

    def device_type(self, name=None, identifier=None):
        """
        :param name: The short name of the device type.
        :type name: str
        :param identifier: The CoreSimulator identifier of the desired device type.
        :type identifier: str
        :return: A device type with the specified name and/or identifier, or None if one doesn't exist as such.
        :rtype: DeviceType
        """
        for device_type in self.device_types:
            if name and device_type.name != name:
                continue
            if identifier and device_type.identifier != identifier:
                continue
            return device_type
        return None

    def runtime(self, version=None, identifier=None, is_internal_runtime=None):
        """
        :param version: The iOS version of the desired runtime.
        :type version: tuple
        :param identifier: The CoreSimulator identifier of the desired runtime.
        :type identifier: str
        :return: A runtime with the specified version and/or identifier, or None if one doesn't exist as such.
        :rtype: Runtime or None
        """
        if version is None and identifier is None:
            raise TypeError('Must supply version and/or identifier.')

        for runtime in self.runtimes:
            if version and runtime.version != version:
                continue
            if is_internal_runtime and runtime.is_internal_runtime != is_internal_runtime:
                continue
            if identifier and runtime.identifier != identifier:
                continue
            return runtime
        return None

    def find_device_by_udid(self, udid):
        """
        :param udid: The UDID of the device to find.
        :type udid: str
        :return: The `Device` with the specified UDID.
        :rtype: Device
        """
        for device in self.devices:
            if device.udid == udid:
                return device
        return None

    def current_device(self):
        # FIXME: Find the simulator device that was booted by Simulator.app. For now, pick some booted simulator device, which
        # may have been booted using the simctl command line tool.
        for device in self.devices:
            if device.state == Simulator.DeviceState.BOOTED:
                return device
        return None

    # FIXME: We should find an existing device with respect to its name, device type and runtime.
    def device(self, name=None, runtime=None, should_ignore_unavailable_devices=False):
        """
        :param name: The name of the desired device.
        :type name: str
        :param runtime: The runtime of the desired device.
        :type runtime: Runtime
        :return: A device with the specified name and/or runtime, or None if one doesn't exist as such
        :rtype: Device or None
        """
        if name is None and runtime is None:
            raise TypeError('Must supply name and/or runtime.')

        for device in self.devices:
            if should_ignore_unavailable_devices and not device.available:
                continue
            if name and device.name != name:
                continue
            if runtime and device.runtime != runtime:
                continue
            return device
        return None

    @property
    def available_runtimes(self):
        """
        :return: An iterator of all available runtimes.
        :rtype: iter
        """
        return itertools.ifilter(lambda runtime: runtime.available, self.runtimes)

    @property
    def devices(self):
        """
        :return: An iterator of all devices from all runtimes.
        :rtype: iter
        """
        return itertools.chain(*[runtime.devices for runtime in self.runtimes])

    @property
    def latest_available_runtime(self):
        """
        :return: Returns a Runtime object with the highest version.
        :rtype: Runtime or None
        """
        if not self.runtimes:
            return None
        return sorted(self.available_runtimes, key=lambda runtime: runtime.version, reverse=True)[0]

    def lookup_or_create_device(self, name, device_type, runtime):
        """
        Returns an available iOS Simulator device for testing.

        This function will create a new simulator device with the specified name,
        device type and runtime if one does not already exist.

        :param name: The name of the simulator device to lookup or create.
        :type name: str
        :param device_type: The CoreSimulator device type.
        :type device_type: DeviceType
        :param runtime: The CoreSimulator runtime.
        :type runtime: Runtime
        :return: A dictionary describing the device.
        :rtype: Device
        """
        assert(runtime.available)
        testing_device = self.device(name=name, runtime=runtime, should_ignore_unavailable_devices=True)
        if testing_device:
            _log.debug('lookup_or_create_device %s %s %s found %s', name, device_type, runtime, testing_device.name)
            return testing_device
        testing_device = Simulator.Device.create(name, device_type, runtime)
        _log.debug('lookup_or_create_device %s %s %s created %s', name, device_type, runtime, testing_device.name)
        assert(testing_device.available)
        return testing_device

    def __repr__(self):
        return '<iOS Simulator: {num_runtimes} runtimes, {num_device_types} device types>'.format(
            num_runtimes=len(self.runtimes),
            num_device_types=len(self.device_types))

    def __str__(self):
        description = ['iOS Simulator:']
        description += map(str, self.runtimes)
        description += map(str, self.device_types)
        description += map(str, self.devices)
        return '\n'.join(description)


from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_SplashSCreen(object):
    def __init__(self,window):
        super(Ui_SplashSCreen, self).__init__()
        self.setupUi(window)

    def setupUi(self, SplashSCreen):
        SplashSCreen.setObjectName("SplashSCreen")
        SplashSCreen.resize(680, 400)
        self.centralwidget = QtWidgets.QWidget(SplashSCreen)
        self.centralwidget.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.centralwidget.setObjectName("centralwidget")
        self.dropShadowFrame = QtWidgets.QFrame(self.centralwidget)
        self.dropShadowFrame.setGeometry(QtCore.QRect(0, 0, 681, 401))
        self.dropShadowFrame.setStyleSheet("QFrame{\n"
"color: rgb(10, 66, 127);\n"
"background-color:rgb(162, 155, 255);\n"
"border-radius:20px;\n"
"}")
        self.dropShadowFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.dropShadowFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.dropShadowFrame.setObjectName("dropShadowFrame")
        self.main_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.main_label.setGeometry(QtCore.QRect(16, 70, 651, 91))
        font = QtGui.QFont()
        font.setFamily("Yu Gothic UI Semibold")
        font.setPointSize(40)
        self.main_label.setFont(font)
        self.main_label.setStyleSheet("background-color: rgb(216, 255, 221);")
        self.main_label.setAlignment(QtCore.Qt.AlignCenter)
        self.main_label.setObjectName("main_label")
        self.progressBar = QtWidgets.QProgressBar(self.dropShadowFrame)
        self.progressBar.setGeometry(QtCore.QRect(100, 260, 501, 31))
        font = QtGui.QFont()
        font.setFamily("Yu Gothic UI Semilight")
        font.setPointSize(13)
        self.progressBar.setFont(font)
        self.progressBar.setStyleSheet("QProgressBar{\n"
"    background-color: rgb(173, 167, 255);\n"
"    \n"
"    color: rgb(0, 0, 127);\n"
"border-radius:20px;\n"
"text-align:centre;\n"
"\n"
"}\n"
"QProgressBar::chunk{\n"
"border-radius:20px;\n"
"    background-color: rgb(67, 170, 150);\n"
"}")
        self.progressBar.setProperty("value", 24)
        self.progressBar.setAlignment(QtCore.Qt.AlignCenter)
        self.progressBar.setTextVisible(True)
        self.progressBar.setTextDirection(QtWidgets.QProgressBar.BottomToTop)
        self.progressBar.setObjectName("progressBar")
        self.loading_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.loading_label.setGeometry(QtCore.QRect(6, 290, 671, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setItalic(True)
        font.setStrikeOut(False)
        self.loading_label.setFont(font)
        self.loading_label.setAlignment(QtCore.Qt.AlignCenter)
        self.loading_label.setWordWrap(True)
        self.loading_label.setObjectName("loading_label")
        self.createdby_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.createdby_label.setGeometry(QtCore.QRect(20, 350, 651, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(10)
        font.setItalic(False)
        font.setStrikeOut(False)
        self.createdby_label.setFont(font)
        self.createdby_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.createdby_label.setWordWrap(True)
        self.createdby_label.setObjectName("createdby_label")
        SplashSCreen.setCentralWidget(self.centralwidget)

        self.retranslateUi(SplashSCreen)
        QtCore.QMetaObject.connectSlotsByName(SplashSCreen)

    def retranslateUi(self, SplashSCreen):
        _translate = QtCore.QCoreApplication.translate
        SplashSCreen.setWindowTitle(_translate("SplashSCreen", "MainWindow"))
        self.main_label.setText(_translate("SplashSCreen", "Practice Py-QT"))
        self.loading_label.setText(_translate("SplashSCreen", "
Loading
"))
        self.createdby_label.setText(_translate("SplashSCreen", "
Created by: Mushfiq
"))


import random,re
from termcolor import colored

def luck(L='',p='',w='',mesg=''):
    luck_st=colored(f"\n******GOOD LUCK******\n","red")
    places=['Albany','Mt Wellington','Mt Eden','Ponsonby','Auckland-CBD','Handerson','New-lynn','Tapu','NewMarket']

    if w=="lotto":
        print(luck_st)
        for i in range(int(L)):
            a=" ".join(sorted(str(i).zfill(2) for i in random.sample(range(1,41),6)))
            if p=="yes":
                print(colored(f"{a} \t   {str(random.randint(1,10)).zfill(2)}","cyan"))
            else:
                print(colored(f"{a}","blue"))
        print(luck_st)
        print(colored(f"{mesg} \n Your Ticket has been sold at {places[random.randint(0,len(places)-1)]}","red",'on_white'))

    else:
        print(luck_st)
        for i in range(int(L)):
                a=" ".join(str(i).zfill(2) for i in random.sample(range(1,41),4))
                print(colored(a,"blue"))
        print(luck_st)
        print(colored(f"{mesg} \n Your Ticket has been sold at {places[random.randint(0,len(places)-1)]}","red",'on_white'))

def balance(name_user):

    def check_balance(balance_user,balance_user_not_accept=None):
        if 199<balance_user:
            print(colored(f'\nPlease {name_user}. Make sure to not excced the limit $200\n{"Also we dont accept amounts like"+balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            return balance(name_user)

        elif balance_user<6:
            print(colored(f'\nPlease {name_user}. The top up must be higher than $5\n{"Also we do not accept amounts like"+balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            return balance(name_user)

        elif balance_user_not_accept:
            print(colored(f'\nGood Luck {name_user}.But we will only accept {balance_user}$ we do not accept amounts like {balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            print(colored(f"Each line of JackPot cost $2 and 1$ for Strike or Lotto ","red",'on_white'))
            return x(name_user,balance_user)

    balance_user=input(colored('how much would you like to top up your account \n','red')).strip()

    if balance_user=='':
        print(f'\nplease dont leave it blank {name_user}\n ')
        return balance(name_user)

    elif re.findall(r"^[\d]+$",balance_user):
        balance_user=int(balance_user)
        check_balance(balance_user)

    elif balance_user.find('.') !=-1 and balance_user.count('.')==1:
        balance_user_not_accept=balance_user[balance_user.index('.'):]
        balance_user=int(balance_user[:balance_user.index('.')])
        check_balance(balance_user,balance_user_not_accept)

    else:
        print('\nplease onlt type number')
        return balance(name_user)

    print(colored(f"Good Luck {name_user.upper()} - your balance is {balance_user}$",'red','on_white'))
    print(colored(f"Each line of JackPot cost $2 and 1$ for Strike or Lotto ","red",'on_white'))
    return x(name_user,balance_user)

def name_user():
    name_user=input(colored('what is your name \n','red')).strip()
    while name_user=='' or re.findall(r"[\d\W]",name_user):
        if name_user=='':
            print(colored("Please don't leave it blank",'red','on_white'))
        else:
            print(colored("Please type only letters!",'red','on_white'))
        name_user=input(colored('what is your name \n','red',"on_white"))
    return balance(name_user)

def strike(balance):
    which="stike"
    lines= balance
    power=None
    mesg=colored(f"you will #{lines}LINES of STRIKES \n",'red')
    return luck(lines,power,which,mesg)

def lotto(balance):
    which="lotto"
    power=input(colored(f"are you keen for a jakpot ? yes or no \n",'red',"on_white")).lower()
    if power =='yes' or power=='y':
        if balance %2==0:
            lines=int(balance/2)
            mesg=f"you have #{lines} LINES of jackpot draw!"
            return luck(lines,power,which,mesg)
        else:
            balance-=1
            lines=int(balance/2)
            mesg=f'''you have #{lines} LINES of jackpot draw!
            please note that your balance now is 1$'''
            return luck(lines,power,which,mesg)
    else:
        power='no'
        lines= int(balance)
        mesg=f"you have #{lines} LINES of {which} draw!"
        return luck(lines,power,which,mesg)

def x(name,balance):

    which=input(colored('\nDo you want lotto or strike ?\n','red',"on_white").capitalize()).lower()

    while which=='' :
            print(colored(f'please {name.upper()} Either type lotto or strike. thank you :)',"red","on_white"))
            which=input(colored('\n do you want lotto or strike ?\n','red','on_white').capitalize()).lower()

    if which != 'lotto' and which!='strike':
        like_strike=re.search(r"[strike]{,10}",which).group()
        like_lotto=re.search(r"[lto]{,10}",which).group()
        answers=['y','yes','ys']

        if like_strike  or like_lotto :
            ask=input(colored(f"Do you mean {'strike' if like_strike else 'lotto' } ? Yes or No ?\n",'red','on_white')).lower()
            while ask=="":
                    print(f'Dear {name.upper()} please make sure to type Yes or No...')
                    ask=input(colored(f"Do you mean {'strike' if like_strike else 'lotto' } ? Yes or No ?\n",'red',"on_white")).lower()
            else:
                if ask not in answers:
                    print(colored(f'I think you change your mind{name.upper()} ....let us strat from begin!',"red","on_white"))
                    return x(name,balance)
                else:
                    if like_strike:
                        return strike(balance)
                    else:
                        return lotto(balance)
        else:
            print(colored(f'I can not understand that {name.upper()} ....let us strat from begin!',"red","on_white"))
            return x(name,balance)

    else:
        if which=="lotto":
            return lotto(balance)

        else:
            return strike(balance)

name_user()


"""
https://leetcode-cn.com/problems/smallest-rotation-with-highest-score/

给定一个数组 A，我们可以将它按一个非负整数 K 进行轮调，这样可以使数组变为 A[K], A[K+1], A{K+2], ... A[A.length - 1], A[0], A[1], ..., A[K-1] 的形式。此后，任何值小于或等于其索引的项都可以记作一分。

例如，如果数组为 [2, 4, 1, 3, 0]，我们按 K = 2 进行轮调后，它将变成 [1, 3, 0, 2, 4]。这将记作 3 分，因为 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point]。

在所有可能的轮调中，返回我们所能得到的最高分数对应的轮调索引 K。如果有多个答案，返回满足条件的最小的索引 K。

示例 1：
    输入：[2, 3, 1, 4, 0]
    输出：3
    解释：
        下面列出了每个 K 的得分：
        K = 0,  A = [2,3,1,4,0],    score 2
        K = 1,  A = [3,1,4,0,2],    score 3
        K = 2,  A = [1,4,0,2,3],    score 3
        K = 3,  A = [4,0,2,3,1],    score 4
        K = 4,  A = [0,2,3,1,4],    score 3
        所以我们应当选择 K = 3，得分最高。

示例 2：
    输入：[1, 3, 0, 2, 4]
    输出：0
    解释：
        A 无论怎么变化总是有 3 分。
        所以我们将选择最小的 K，即 0。

提示：
    A 的长度最大为 20000。
    A[i] 的取值范围是 [0, A.length]。

"""
from typing import List

""" 方法一：差分数组 """
class Solution:
    def bestRotation(self, nums: List[int]) -> int:
        n = len(nums)
        diffs = [0] * n
        for i, num in enumerate(nums):  # [1,2,3,5]
            low = (i + 1) % n
            high = (i - num + n + 1) % n
            diffs[low] += 1
            diffs[high] -= 1
            if low >= high:
                diffs[0] += 1
        print('diffs: ', diffs)
        score, maxScore, idx = 0, 0, 0
        for i, diff in enumerate(diffs):
            score += diff
            if score > maxScore:
                maxScore, idx = score, i
        return idx

class Solution:
    def bestRotation(self, nums: List[int]) -> int:
        n = len(nums)
        step = [0] * n
        for i, a in enumerate(nums):
            if a <= 0 or a >= n:    # 不满足条件的跳过
                continue
            left = i - (a - 1)
            right = i - (n - 1)
            print(i, a, left, right)
            step[left % n] -= 1
            step[right % n] += 1
        print(step)
        val, max_val, max_index = 0, - n - 1, -1
        for i in range(n):
            s = step[i]
            val += s
            if val > max_val:
                max_val = val
                max_index = i
        return max_index

if __name__ == "__main__":
    nums = [1,2,3,5]
    sol = Solution()
    result = sol.bestRotation(nums)
    print(result)

algorithms/01_数组 & 列表/差分数组/0798_得分最高的最小轮调.py

0798_得分最高的最小轮调.py


from django.shortcuts import render, redirect
from proyecto_6_app.models import Proyecto
from . import forms

# Create your views here.
def index(request):
    return render(request, 'index.html')

def listadoproyecto(request):
    proye = Proyecto.objects.all()
    data = {'proyecto':proye}
    return render(request, 'proyecto.html',data)

def registro(request):
    form = forms.registros()
    if request.method == 'POST':
        form = forms.registros(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return index(request)
        else:
            print('Error en el formulario')
    data = {'formss': form }
    return render(request, 'registro.html',data)

def eliminar(request, id):
    proye = Proyecto.objects.get(id=id)
    proye.delete()
    return redirect('/proyecto')

def modificar(request, id):
    proye = Proyecto.objects.get(id=id)
    form = forms.registros(instance=proye)
    if (request.method == 'POST'):
        form = forms.registros(request.POST, instance=proye)

        if form.is_valid():
            form.save()
        return index(request)

    data = {'formss':form}
    return render(request, 'registro.html', data)


from art import logo

alphabet = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
    'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
]

def caesar(start_text, shift_amount, cipher_direction):
    end_text = ""
    if cipher_direction == "decode":
        shift_amount *= -1
    for char in start_text:
        if char in alphabet:
            position = alphabet.index(char)
            new_position = (position + shift_amount)%26
            end_text += alphabet[new_position]
        else:
            end_text += char
    print(f"Here's the {cipher_direction}d result: {end_text}")

# # # # # # # # # # # # # # # # # # # # # # # # #
print(f"\u001b[33m{logo}\u001b[0m")

restart = True
while restart == True:
    direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    if shift%26 == 0:
      print("-Number must not be multiple of 26 or you're going to get the same message.\n")
    caesar(start_text=text, shift_amount=shift, cipher_direction=direction)
    answer = input("Do you want to restart the program? (y/n) \n")
    if answer == "n":
      restart = False
      print("GoodBye :)")


#!flask/bin/python
import logging
import sys
import json

from flask import Flask
from flask_restplus import Api
from webargs.flaskparser import parser, abort
from flask_cors import CORS

from common.util import parse_config
from common.util import ConfigException

from v1.api.retrieve import RetrieveAPI as RetrieveAPIv1
from adapters.G2Adapter import G2Adapter

ENDPOINTS = {
    "gd2": 'gd2.mlb.com/components/'
}

def setup_adapters(config):
    adapters = dict()
    logging.debug(config['main']['mlb_endpoint'])
    adapters['gamefeed_adapter'] = G2Adapter(ENDPOINTS[config['main']['mlb_endpoint']])

    return adapters

def run_server(config):
    app = Flask(__name__)
    api = Api(app)
    if config['main']['enable_cors']:
        logging.info("Enabling CORS for all routes")
        CORS(app)

    adapters = setup_adapters(config)

    api.add_resource(RetrieveAPIv1, '/v1/retrieve', '/retrieve', endpoint='v1_retrieve',
                     resource_class_kwargs={'gamefeed_adapter': adapters['gamefeed_adapter']})
    app.run(host='0.0.0.0', port=config['main']['port'], debug=config['main']['debug'])

@parser.error_handler
def handle_request_parsing_error(err, req, schema):
    try:
        json.loads(req.data)
    except ValueError:
        abort(422, error="The request parameters or data violated the schema", schema=str(err))
    abort(422, errors=err.messages)

def main():
    logging.basicConfig(level=logging.DEBUG)

    if len(sys.argv) != 2:
        raise ConfigException("You must specify a config file as a command-line argument")

    config_file = sys.argv[1]
    config = parse_config(config_file)

    run_server(config)

if __name__ == "__main__":
    main()


from intercode.envs import (
    BashEnv, IntercodeEnv, AGENT_OBS, REWARD
)
from typing import Dict, Tuple

class CTFEnv(BashEnv):
    """Gym environment for CTF game"""
    name = "ic_ctf"

    def __init__(self, image_name: str, **kwargs):
        IntercodeEnv.__init__(self, image_name, **kwargs)

    def get_reward(self) -> Tuple[float, Dict]:
        self.info = {}

        # Get flag from `submit` action
        last_action = self.trajectory[-1][0]
        flag = last_action.split(" ")[1]

        # Reward of 1 if flag is correct, 0 otherwise
        self.reward = 1 if flag.lower() == self.gold.lower() else 0
        self.info[AGENT_OBS] = flag
        self.info[REWARD] = self.reward

        self.logger.info(f"Info: {self.info}")
        self.logger.info(f"Reward: {self.reward}")
        return self.reward, self.info

    def close(self):
        self.logger.info("Beginning environment shutdown...")
        self.container.stop()
        self.logger.info("Agent container stopped")

    def clean_cmd(self, action: str) -> str:
        if any([action.strip().startswith(x) for x in ["python3 -c", "python -c"]]):
            return action
        def clean_command(command):
            # Escape single quotes and enclose the command in single quotes
            cleaned_command = "/bin/bash -c '" + command.replace("'", "'\\''") + "'"
            return cleaned_command
        return clean_command(action.strip())


# import required packages
import json
import requests
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import linregress
import statsmodels.api as sm

##### - Print price chart for specified asset in linear, or log - #####
def priceChart(symbol, linOrLog):

    # insert API key and asset symbol here
    API_KEY = ''

    # make API requests and print status codes
    res = requests.get('https://api.glassnode.com/v1/metrics/market/price_usd_close', params={'a': symbol, 'api_key': API_KEY})
    print(res.status_code)

    # convert json to a pandas dataframe
    df = pd.read_json(res.text, convert_dates=['t'])
    df.rename(columns={'t':'date'}, inplace=True)
    df.rename(columns={'v':'price'}, inplace=True)
    df['log10_price'] = np.log10(df['price'])
    #print(df)

    # print either linear or log chart based on user input
    if linOrLog == 'linear':
        x = df.date
        y = df.price
        plt.plot(x, y)
        plt.ylabel('Price')
        plt.title(symbol)
        plt.savefig(symbol + '_priceChart_linear.png')
        plt.show()
    elif linOrLog == 'log':
        x = df.date
        y = df.log10_price
        plt.plot(x, y)
        plt.ylabel('Price (log10)')
        plt.title(symbol)
        plt.savefig(symbol + '_priceChart_log10.png')
        plt.show()
    else:
        print('2nd argument in chart() function must be either "linear", or "log"')

##### - Export Glassnode Data to CSV file for processing in gretl - #####
def toGretl(symbol):

    # insert API key and asset symbol here
    API_KEY = ''

    # make API requests and print status codes
    res = requests.get('https://api.glassnode.com/v1/metrics/market/price_usd_close', params={'a': symbol, 'api_key': API_KEY})
    #print(res.status_code)

    # convert json to a pandas dataframe
    df = pd.read_json(res.text, convert_dates=['t'])
    df.rename(columns={'t':'date'}, inplace=True)
    df.rename(columns={'v':'price'}, inplace=True)
    df['log10_price'] = np.log10(df['price'])
    #print(df)

    # Export to CSV for gretl
    df.to_csv(symbol + ".csv")
    print("done")

priceChart("BTC", "log")


import phik
import numpy as np
import pandas as pd
from tqdm import tqdm

from phik.binning import create_correlation_overview_table, hist2d_from_array
from phik.bivariate import phik_from_chi2
from phik.statistics import estimate_simple_ndof

import itertools
from scipy.stats import power_divergence

def phik_from_hist2d(observed: np.ndarray, expected: np.ndarray, noise_correction: bool = True) -> float:
    """
    correlation coefficient of bivariate gaussian derived from chi2-value

    Chi2-value gets converted into correlation coefficient of bivariate gauss
    with correlation value rho, assuming giving binning and number of records.
    Correlation coefficient value is between 0 and 1.

    Bivariate gaussian's range is set to [-5,5] by construction.

    :param observed: 2d-array observed values
    :param expected: 2d-array expected values
    :param bool noise_correction: apply noise correction in phik calculation
    :returns float: correlation coefficient phik
    """
    if isinstance(observed, pd.DataFrame):
        observed = observed.values
    if isinstance(expected, pd.DataFrame):
        expected = expected.values

    # important to ensure that observed and expected have same normalization
    expected = expected * (np.sum(observed) / np.sum(expected))

    # chi2 contingency test
    chi2 = chi_square(observed, expected, lambda_='pearson')

    # noise pedestal
    endof = estimate_simple_ndof(observed) if noise_correction else 0
    pedestal = endof
    if pedestal < 0:
        pedestal = 0

    # phik calculation adds noise pedestal to theoretical chi2
    return phik_from_chi2(chi2, observed.sum(), *observed.shape, pedestal=pedestal)

def chi_square(observed, expected, correction=True, lambda_=None):
    """ Calculate chi square between observed and expected 2d matrix

    :param observed:
    :param expected:
    :param correction:
    :param lambda_:
    :return:
    """
    observed = np.asarray(observed)
    if np.any(observed < 0):
        raise ValueError("All values in `observed` must be nonnegative.")
    if observed.size == 0:
        raise ValueError("No data; `observed` has size 0.")

    expected = np.asarray(expected)

    terms = np.divide((observed.astype(np.float64) - expected) ** 2, expected,
                      out=np.zeros_like(expected), where=expected != 0)
    return np.sum(terms)

def phik_matrix(X_obs, X_exp):
    """ Calculate phik matrix

    :param X_obs: array of observed data points
    :param X_exp: array of expected data points
    :return: phik matrix
    """
    assert X_obs.shape[1] == X_exp.shape[1]

    n_unique = [len(np.unique(X_obs[:, i])) for i in range(X_obs.shape[1])]

    phik_list = []
    for i, j in tqdm(itertools.combinations_with_replacement(range(X_obs.shape[1]), 2)):
        if i == j:
            phik_list.append((i, j, 1.))
            continue
        elif n_unique[i] == 1 or n_unique[j] == 1:
            phik_list.append((i, j, 0.))
            continue
        expected = hist2d_from_array(X_exp[:, i], X_exp[:, j], interval_cols=[])
        observed = hist2d_from_array(X_obs[:, i], X_obs[:, j], interval_cols=[])
        expected = make_equal_shape(observed, expected)
        phik_list.append((i, j, phik_from_hist2d(observed, expected)))

    phik_overview = create_correlation_overview_table(phik_list)
    return phik_overview

def make_equal_shape(observed, expected):
    """ Sometimes expected histogram shape need filling

    :param observed:
    :param expected:
    :return:
    """
    o_cols = observed.columns.tolist()
    e_cols = expected.columns.tolist()
    o_cols_missing = list(set(e_cols) - set(o_cols))
    e_cols_missing = list(set(o_cols) - set(e_cols))

    o_idx = observed.index.tolist()
    e_idx = expected.index.tolist()
    o_idx_missing = list(set(e_idx) - set(o_idx))
    e_idx_missing = list(set(o_idx) - set(e_idx))

    # make expected columns equal to observed
    for c in o_cols_missing:
        observed[c] = 0.0
    for c in e_cols_missing:
        expected[c] = 0.0
    observed.columns = sorted(observed.columns)
    expected.columns = sorted(expected.columns)
    assert len(observed.columns) == len(expected.columns)

    # make expected index equal to observed
    for i in o_idx_missing:
        observed.loc[i] = np.zeros(len(observed.columns))
    for i in e_idx_missing:
        expected.loc[i] = np.zeros(len(expected.columns))
    assert len(observed.index) == len(expected.index)

    return expected