# dense_vae.py: Variational autoencoder with fully-connected layers
#
# (C) 2019, Daniel Mouritzen

from typing import Dict, Optional, Sequence, Type, Union

import gin
import numpy as np
import tensorflow as tf

from project.util.tf import auto_shape
from project.util.tf.losses import kl_divergence, mse

from .basic import SequentialBlock, ShapedDense
from .wrappers import ExtraBatchDim

class DenseVAEEncoder(auto_shape.Layer):
    def __init__(self,
                 latent_shape: Sequence[int],
                 num_units: int = 100,
                 num_layers: int = 1,
                 activation: Union[None, str, Type[tf.keras.layers.Layer]] = auto_shape.ReLU,
                 batch_norm: bool = False,
                 name: str = 'vae_encoder',
                 ) -> None:
        super().__init__()
        self._encoder = SequentialBlock(num_units,
                                        num_layers,
                                        activation,
                                        batch_norm,
                                        initial_layers=[auto_shape.Flatten(name=f'{name}_flatten')],
                                        name=f'{name}_sequential')
        self._encoder.add(ShapedDense([2] + list(latent_shape), name=f'{name}_shaped_dense'))

    def call(self, input: tf.Tensor) -> Dict[str, tf.Tensor]:
        output = self._encoder(input)
        assert output.shape[1] == 2
        mean, log_var = output[:, 0], output[:, 1]
        sample = tf.random.normal(mean.shape) * tf.exp(log_var * .5) + mean
        return {'mean': mean, 'log_var': log_var, 'sample': sample}

class DenseVAEDecoder(auto_shape.Layer):
    def __init__(self,
                 output_shape: Sequence[int],
                 num_units: int = 100,
                 num_layers: int = 1,
                 activation: Union[None, str, Type[tf.keras.layers.Layer]] = auto_shape.ReLU,
                 batch_norm: bool = False,
                 name: str = 'vae_decoder',
                 ) -> None:
        super().__init__()
        self._decoder = SequentialBlock(num_units,
                                        num_layers,
                                        activation,
                                        batch_norm,
                                        initial_layers=[auto_shape.Flatten(name=f'{name}_flatten')],
                                        name=f'{name}_sequential')
        self._decoder.add(ShapedDense(output_shape, name=f'{name}_shaped_dense'))

    def call(self, input: tf.Tensor) -> tf.Tensor:
        return self._decoder(input)

@gin.configurable(whitelist=['num_units', 'num_layers', 'activation'])
class DenseVAE(auto_shape.Layer):
    def __init__(self,
                 input_shape: Sequence[int],
                 latent_shape: Sequence[int],
                 num_units: int = 100,
                 num_layers: int = 1,
                 activation: Union[None, str, Type[tf.keras.layers.Layer]] = auto_shape.ReLU,
                 batch_norm: bool = False,
                 name: str = 'vae',
                 ) -> None:
        self.encoder = ExtraBatchDim(DenseVAEEncoder(latent_shape,
                                                     num_units,
                                                     num_layers,
                                                     activation,
                                                     batch_norm,
                                                     name=f'{name}_encoder'))
        self.decoder = ExtraBatchDim(DenseVAEDecoder(input_shape,
                                                     num_units,
                                                     num_layers,
                                                     activation,
                                                     batch_norm,
                                                     name=f'{name}_decoder'))
        super().__init__(batch_dims=2, name=name)

    def call(self, input: tf.Tensor, mask: Optional[tf.Tensor] = None) -> tf.Tensor:
        z = self.encoder(input)
        input_recon = self.decoder(z['sample'])
        rec_loss = mse(input_recon, input, mask) * np.prod(input.shape[2:])
        kl_loss = kl_divergence(z['mean'], z['log_var'], mask)
        self.add_named_loss(rec_loss, name=f'{self.name}_recon', layer=self)
        self.add_named_loss(kl_loss, name=f'{self.name}_kl', layer=self)
        return z['sample']


from text_to_num import alpha2digit
import json
from tensorflow.keras.preprocessing.sequence import pad_sequences
from pickle import load
import numpy as np
from tensorflow.keras.models import load_model
model = load_model('nonamemodel.h5')
tokenizer = load(open('nonametokenizer.pkl', 'rb'))

#find 3 highest scorers
def get_high_scores(box):
    hi = [0,0,0]
    best=[0,0,0]
    for k in box["PTS"].keys():
        val = box["PTS"][k]
        if val.isnumeric():
            val = int(val)
            for i in range(3):
                if val>=hi[i]:
                    hi.insert(i,val)
                    best.insert(i,k)
                    break
        hi = hi[:3]
        best = best[:3]
    return best

# fill out dictionary with stats of highest scorers
def get_stats(best,box):
    tags_dict = {"FIRST_NAME":[],"SECOND_NAME":[],"PTS":[],"AST":[],"REB":[]}
    for tag in tags_dict:
        for player in best:
            tags_dict[tag].append(box[tag][player])
    return tags_dict

with open('../test.json','r') as fr: #read in test data
        d = fr.read()
        full_dict = json.loads(d)

for game in full_dict: #for game in test
    #generate sentence
    seq_length = 15
    result = list()
    out_word = ''
    in_text = []
    count = 0
    while not (out_word=="." or out_word=="*end*") and count<101:  #while not at end of sentence
            # encode the text as integer
            encodedp = tokenizer.texts_to_sequences([in_text])[0]
            words = encodedp
            # truncate sequences to a fixed length
            words_encoded = pad_sequences([words], maxlen=seq_length, truncating='pre',value=1,padding='post')
            # predict probabilities for each word
            pred = model.predict(words_encoded)
            yhat = np.random.choice(len(pred[0]), p=pred[0]) #pick by distribution
            #yhat = np.argmax(pred, axis=-1) #if you want max
            # map predicted word index to word
            out_word = ''
            for word, index in tokenizer.word_index.items():
                if index == yhat:
                    out_word = word
                    break
            # append to input
            in_text.append(out_word)
            result.append(out_word)
            count+=1

    #Get high scorers
    h = get_high_scores(game["box_score"])

    #get stats of high scorers
    stats_dict = get_stats(h,game["box_score"])

    tags = {"*firsttname*":"FIRST_NAME","*lastname*":"SECOND_NAME","*ptsval*":"PTS","*astval*":"AST","*rebval*":"REB"}
    tags_used = {"*firsttname*":0,"*lastname*":0,"*ptsval*":0,"*astval*":0,"*rebval*":0}

    #replace keys
    for i,tok in enumerate(result):
        if tok in tags.keys():
            result[i]=stats_dict[tags[tok]][tags_used[tok]]
            tags_used[tok]= (tags_used[tok]+1)%3 #use next player next time

    with open('results.txt','a') as fw:
        fw.write(' '.join(result)+ " \r\n") #write to file


from flask import Flask, render_template, flash, request, redirect
from flask_debugtoolbar import DebugToolbarExtension
from forex_python.converter import CurrencyRates, CurrencyCodes

app = Flask(__name__)
app.config['SECRET_KEY'] = "oh-so-secret"
debug = DebugToolbarExtension(app)
app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False

c = CurrencyRates(force_decimal=False)
cc = CurrencyCodes()

@app.route("/")
def homepage():
    """show homepage"""

    return render_template('home.html')

@app.route("/result", methods=["POST"])
def display_result():
    """ displays form for input"""

    input_currency = request.form["inputcurrency"]
    output_currency = request.form["outputcurrency"]

    try:
        input_amount = float(request.form["amount"])

        input_symbol = cc.get_symbol(input_currency)
        output_symbol = cc.get_symbol(output_currency)
        input_name = cc.get_currency_name(input_currency)
        output_name = cc.get_currency_name(output_currency)

        converted = c.convert(input_currency, output_currency, input_amount)
        converted = format(converted, ".2f")
        amount = format(input_amount, ".2f")

        return render_template('results.html', amount=amount,
            converted=converted,
            input_symbol=input_symbol,
            output_symbol=output_symbol,
            input_name=input_name,
            output_name=output_name,)

    except ValueError:
        flash("Error: Please input a number or decimal for the amount", "error")
        return redirect("/")
    except Exception as err:
        print(err)
        err = str(err)
        if err == "Currency Rates Source Not Ready":
            flash("Error: Not an acceptable currency! Please try again", "error")
        return redirect("/")


from transformers import BeitModel
from torch import nn
import torch

import matplotlib.pyplot as plt

from PIL import Image
import requests

"""
Picked at https://github.com/920232796/SETR-pytorch/blob/master/SETR/transformer_seg.py
"""

class BranchedDecoder(nn.Module):

    def __init__(self, in_channels, out_channels, features=[[256, 256], [256, 256], [512, 256, 128, 64]]):
        super().__init__()
        self.decoder_branch_1 = nn.Sequential(
            nn.Conv2d(in_channels, features[0][0], 2, padding=0),
            nn.BatchNorm2d(features[0][0]),
            nn.LeakyReLU(inplace=True),
            nn.Conv2d(features[0][0], features[0][1], 1, padding=0),
            nn.BatchNorm2d(features[0][1]),
            nn.LeakyReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True)
        )

        self.decoder_branch_2 = nn.Sequential(
            nn.Conv2d(in_channels, features[1][0], 2, padding=0),
            nn.BatchNorm2d(features[1][0]),
            nn.LeakyReLU(inplace=True),
            nn.Conv2d(features[0][0], features[0][1], 1, padding=0),
            nn.BatchNorm2d(features[0][1]),
            nn.LeakyReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True),
        )

        self.merge_branch = nn.Sequential(
            nn.Conv2d(features[2][0], features[2][1], 2, padding=0),
            nn.BatchNorm2d(features[2][1]),
            nn.LeakyReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True),
            nn.Conv2d(features[2][1], features[2][2], 2, padding=0),
            nn.BatchNorm2d(features[2][2]),
            nn.LeakyReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True),
            nn.Conv2d(features[2][2], features[2][3], 2, padding=0),
            nn.BatchNorm2d(features[2][3]),
            nn.LeakyReLU(inplace=True),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True),
        )

        self.final_layer = nn.Conv2d(features[2][3], out_channels, 3, padding=0)

    def forward(self, x):
        x1 = self.decoder_branch_1(x)

        x2 = self.decoder_branch_2(x)

        x = torch.cat((x1, x2), 1)

        x = self.merge_branch(x)

        x = self.final_layer(x)

        return x

class Decoder2D(nn.Module):

    # TODO: Maybe add dropout? Not sure if it is needed.

    def __init__(self, in_channels, out_channels, features=[512, 256, 128, 64]):
        super().__init__()

        self.conv1 = nn.Conv2d(in_channels, features[0], 2, padding=0)
        torch.nn.init.kaiming_uniform_(self.conv1.weight, mode="fan_in", nonlinearity="relu")

        self.conv2 = nn.Conv2d(features[0], features[1], 2, padding=0)
        torch.nn.init.kaiming_uniform_(self.conv2.weight, mode="fan_in", nonlinearity="relu")

        self.conv3 = nn.Conv2d(features[1], features[2], 2, padding=0)
        torch.nn.init.kaiming_uniform_(self.conv3.weight, mode="fan_in", nonlinearity="relu")

        self.conv4 = nn.Conv2d(features[2], features[3], 2, padding=0)
        torch.nn.init.kaiming_uniform_(self.conv4.weight, mode="fan_in", nonlinearity="relu")

        self.decoder_1 = nn.Sequential(
            self.conv1,
            nn.BatchNorm2d(features[0]),
            nn.LeakyReLU(inplace=True),
            nn.Dropout(),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True)
        )
        self.decoder_2 = nn.Sequential(
            self.conv2,
            nn.BatchNorm2d(features[1]),
            nn.LeakyReLU(inplace=True),
            nn.Dropout(),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True)
        )
        self.decoder_3 = nn.Sequential(
            self.conv3,
            nn.BatchNorm2d(features[2]),
            nn.LeakyReLU(inplace=True),
            nn.Dropout(),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True)
        )

        self.decoder_4 = nn.Sequential(
            self.conv4,
            nn.BatchNorm2d(features[3]),
            nn.LeakyReLU(inplace=True),
            nn.Dropout(),
            nn.Upsample(scale_factor=2, mode="bilinear", align_corners=True)
        )

        self.final_out = (nn.Conv2d(features[-1], out_channels, 3, padding=0))

    def forward(self, x):
        x = self.decoder_1(x)
        x = self.decoder_2(x)
        x = self.decoder_3(x)
        x = self.decoder_4(x)
        x = self.final_out(x)
        return x

class BeitSegmentationModel(nn.Module):

    def __init__(
        self,
        lr=0.001,
        momentum=0.9,
        img_size=224,
        patch_dim=16,
        num_channels=3,
        num_classes=2,
        batch_size=16,
        pretrained_model="microsoft/beit-base-patch16-224-pt22k"
    ):

        super(BeitSegmentationModel, self).__init__()

        self.lr = lr
        self.momentum = momentum
        self.img_size = img_size
        self.patch_dim = patch_dim
        self.num_channels = num_channels
        self.num_classes = num_classes
        self.batch_size = batch_size

        # BEiT encoder without segmentation head, can use BeitConfig to
        # alter some of the default values used
        self.beit_base = BeitModel.from_pretrained(pretrained_model)

        for param in self.beit_base.parameters():
            param.requires_grad = False

        for param in self.beit_base.pooler.parameters():
            param.requires_grad = True

        self.decoder = Decoder2D(self.num_channels, self.num_classes)

    def encode(self, x):
        """
            Our self.encode should just be the BEiT base model calculating
            its hidden state and returning it. It returns the following
            * last_hidden_state
            * pooler_output
            * hidden_states
            * attentions
        """

        encoder_output = self.beit_base(pixel_values=x)[1].reshape(self.batch_size, self.num_channels, self.patch_dim, self.patch_dim)

        return encoder_output

    def forward(self, x):

        self.batch_size = len(x)

        encoder_pooler = self.encode(x)

        decoder_output = self.decoder(encoder_pooler)

        decoder_output = decoder_output.reshape(self.batch_size, self.img_size, self.img_size, self.num_classes)

        return decoder_output

if __name__ == "__main__":
    p = {
        "img_size": 224,
        "patch_dim": 16,
        "num_channels": 3,
        "num_classes": 2,
        "batch_size": 16,
        "pretrained_model": "microsoft/beit-base-patch16-224-pt22k-ft22k",
    }

    b = BeitSegmentationModel(
            img_size=p["img_size"],
            patch_dim=p["patch_dim"],
            num_channels=p["num_channels"],
            num_classes=p["num_classes"],
            batch_size=p["batch_size"],
            pretrained_model=p["pretrained_model"]
        )

    url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
    url1 = "http://images.cocodataset.org/test-stuff2017/000000000001.jpg"
    image = Image.open(requests.get(url1, stream=True).raw)
    image2 = Image.open(requests.get(url, stream=True).raw)

    images = [image, image2]

    results = b(images)

    for image in images:
        image.show()

    for image in results.detach().numpy():
        plt.imshow(image)
        plt.show()


"""

 scrape_google_images.py  (author: Anson Wong / git: ankonzoid)

 Scrapes the top k images from Google Images for a particular query.

"""
import os, json, time
import requests
import urllib.request as urllibreq
from bs4 import BeautifulSoup

def scrape_google_images(query, k, outDir, dt_stall):
    print("Scraping top k={} Google images for query: '{}'".format(k, query))

    # Create output directory
    if not os.path.exists(outDir):
        os.mkdir(outDir)

    # Construct image url to scrape from
    url = "https://www.google.co.in/search?q=" + \
          '+'.join(query.split()) + "&source=lnms&tbm=isch"
    header = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"}

    # Download html + parse it to get all image urls
    html = urllibreq.urlopen(urllibreq.Request(url, headers=header))
    soup = BeautifulSoup(html,'html.parser')
    urls = [json.loads(x.text)["ou"]
            for x in soup.find_all("div", {"class": "rg_meta"})]
    print("Parsed {} google image urls!".format(len(urls)))

    # Download top-k images
    for i, url in enumerate(urls[:min(k, len(urls))]):
        imgFile = os.path.join(outDir, query + "-" + str(i+1) + ".jpg")
        print("[{}/{}] Downloading image {} to '{}'...".format(i+1, k, url, imgFile))
        try:
            with open(imgFile, 'wb') as handle:
                response = requests.get(url, stream=True)
                if not response.ok:
                    print(response)
                for block in response.iter_content(1024):
                    if not block:
                        break
                    handle.write(block)
            time.sleep(dt_stall)  # force pause
        except:
            raise Exception("  -> Failed downloading: " + url)

query = "drake"  # google images query text
k = 5  # top-k images will be scraped
outDir = os.path.join(os.getcwd(), "output")  # output directory to save images
dt_stall = 2  # number of seconds to stall between image scrapes
scrape_google_images(query=query, k=k, outDir=outDir, dt_stall=dt_stall)


"""Parse SOQL, including subqueries

Subqueries are very restricted by [Force.com SOQL]
(https://resources.docs.salesforce.com/sfdc/pdf/salesforce_soql_sosl.pdf)
(It's lucky for our implementation)
- "only root queries support aggregate expressions"
- Subqueries can not be in "OR" condition, because it is an additional level.

These expressions can be supported here, but currently unimplemented:
    FORMAT(), convertCurrency(), toLabel(),
    Date Functions..., convertTimezone() in Date Functions
    DISTANCE(x, GEOLOCATION(...))
Especially DISTANCE and GEOLOCATION are not trivial because they would
require a combined parser for parentheses and commas.

Unsupported GROUP BY ROLLUP and GROUP BY CUBE (their syntax for reports).
"""
from typing import Any, Callable, Dict, Iterable, List, Optional, overload, Sequence, Type, TypeVar, Tuple, Union
import datetime
import re
import pytz
from salesforce.dbapi.exceptions import ProgrammingError

_TRow = TypeVar('_TRow', Tuple[Any, ...], List[Any], Dict[str, Any])
_T = TypeVar('_T')

def nz(x: Optional[_T]) -> _T:
    """Not Zero type assert"""
    assert x is not None
    return x

# reserved wods can not be used as alias names
RESERVED_WORDS = set((
    'AND, ASC, DESC, EXCLUDES, FIRST, FROM, GROUP, HAVING, '
    'IN, INCLUDES, LAST, LIKE, LIMIT, NOT, NULL, NULLS, '
    'OR, SELECT, WHERE, WITH'
).split(', '))
AGGREGATION_WORDS = set((
    'AVG, COUNT, COUNT_DISTINCT, MIN, MAX, SUM'
).split(', '))
pattern_aggregation = re.compile(r'\b(?:{})(?=\()'.format('|'.join(AGGREGATION_WORDS)), re.I)
pattern_groupby = re.compile(r'\bGROUP BY\b', re.I)

class QQuery:
    """Parse the SOQL query to an object useful to correctly interpret a response.

    public methods:
        parse_rest_response(records, rowcount, row_type=list):

            Parse the response to rows of the tape list or dict
            parameters:
                records: response['records'] or a slice of its iterator
                rowcount: response['totalSize']

            The `cursor` that created the response can be necessary, but currently unused
    """
    # It can be later splitted to more specialized objects, if QQuery become
    # extended and too complicated.
    # type of query: QRootQuery, QFieldSubquery, QWhereSubquery
    # type of field: QField, QAggregation, QFieldSubquery

    # pylint:disable=too-many-instance-attributes

    def __init__(self, soql: Optional[str] = None) -> None:
        self.soql = None                  # type: Optional[str]
        self.fields = []                  # type: List[Union[str, QQuery]]
        # dictionary of chil to parent relationships - lowercase keys
        self.subroots = {}                # type: Dict[str, Any]  # recursive is Any
        self.aliases = []                 # type: List[str]
        self.root_table = None            # type: Optional[str]
        # is_aggregation: only to know if aliases are relevant for output
        self.is_aggregation = False
        self.has_child_rel_field = False
        # extra_soql: everything what is after the root table name (and
        # after optional alias), usually WHERE...
        self.extra_soql = None            # type: Optional[str]
        self.subqueries = None            # type: Optional[List[Tuple[str, Any]]]
        if soql:
            self._from_sql(soql)

    def _from_sql(self, soql: str) -> None:
        """Create Force.com SOQL tree structure from SOQL"""
        # pylint:disable=too-many-branches,too-many-nested-blocks
        assert not self.soql, "Don't use _from_sql method directly"
        self.soql = soql
        soql, self.subqueries = split_subquery(soql)
        match_parse = re.match(r'SELECT (.*) FROM (\w+)\b(.*)$', soql, re.I)
        if not match_parse:
            raise ProgrammingError('Invalid SQL: %s' % self.soql)
        fields_sql, self.root_table, self.extra_soql = match_parse.groups()
        fields = [x.strip() for x in fields_sql.split(',')]
        self.is_aggregation = bool(pattern_groupby.search(self.extra_soql) or
                                   pattern_aggregation.search(fields[0]))
        self.is_plain_count = fields[0].upper() == 'COUNT()'
        consumed_subqueries = 0
        expr_alias_counter = 0
        #
        if not self.is_plain_count:
            out_field = ''  # type: Union[str, QQuery]
            for field in fields:
                if self.is_aggregation:
                    match = re.search(r'\b\w+$', field)
                    if match:
                        alias = match.group()
                        assert alias not in RESERVED_WORDS, "invalid alias name"
                        if match.start() > 0 and field[match.start() - 1] == ' ':
                            out_field = field = field[match.start() - 1]
                    else:
                        alias = 'expr{}'.format(expr_alias_counter)
                        expr_alias_counter += 1
                    assert '&' not in field, "Subquery not expected as field in aggregation query"
                elif '&' in field:
                    assert field == '(&)'  # verify that the subquery was in parentheses
                    subquery = QQuery(self.subqueries[consumed_subqueries][0])
                    consumed_subqueries += 1
                    self.has_child_rel_field = True
                    out_field = subquery
                    # TODO more child relationships to the same table
                    alias = nz(subquery.root_table)
                else:
                    alias = out_field = field
                    if '.' in alias:
                        if alias.split('.', 1)[0].lower() == self.root_table.lower():
                            alias = alias.split('.', 1)[1]
                        if '.' in alias:
                            # prepare paths for possible empty outer joins
                            subroots = self.subroots
                            root_crumbs = alias.lower().split('.')[:-1]
                            for scrumb in root_crumbs:
                                subroots.setdefault(scrumb, {})
                                subroots = subroots[scrumb]
                self.aliases.append(alias)
                self.fields.append(out_field)
        # TODO it is not currently necessary to parse the exta_soql

    def _make_flat(self, row_dict: Dict[str, Any], path: Tuple[str, ...], subroots: Dict[str, Dict[str, Any]]
                   ) -> Dict[str, Any]:
        """Replace the nested dict objects by a flat dict with keys "object.object.name"."""
        # can get a cursor parameter, if introspection should be possible on the fly
        out = {}
        for k, v in row_dict.items():
            klc = k.lower()  # "key lower case"
            if (not (isinstance(v, dict) and 'attributes' in v)
                    or ('done' in v and 'records' in v and 'totalSize' in v)):
                # :
                if klc not in subroots:
                    out[klc] = v
                else:
                    strpath = '.'.join(path + (klc,)) + '.'
                    strip_pos = len(strpath) - len(klc + '.')
                    for alias in self.aliases:
                        if alias.lower().startswith(strpath):
                            out[alias.lower()[strip_pos:]] = None  # empty outer join field names
            else:
                new_subroots = subroots[klc] if k != 'attributes' else {}
                for sub_k, sub_v in self._make_flat(v, path + (klc,), new_subroots).items():
                    out[k.lower() + '.' + sub_k] = sub_v
        return out

    @overload                   # noqa
    def parse_rest_response(self, records: Iterable[Dict[str, Any]], rowcount: int, row_type: Type[_TRow]
                            ) -> Iterable[_TRow]: ...
    @overload                   # noqa
    def parse_rest_response(self, records: Iterable[Dict[str, Any]], rowcount: int,
                            ) -> Iterable[Tuple[Any, ...]]: ...
    def parse_rest_response(self, records: Iterable[Dict[str, Any]], # type: ignore[no-untyped-def] # noqa
                            rowcount: int, row_type=tuple) -> Iterable[Any]:
        """Parse the REST API response to DB API cursor flat response"""
        assert row_type in (dict, list, tuple)
        if self.is_plain_count:
            # result of "SELECT COUNT() FROM ... WHERE ..."
            assert list(records) == []
            if issubclass(row_type, dict):
                yield {'count': rowcount}
            elif issubclass(row_type, list):
                yield [rowcount]  # originally [resp.json()['totalSize']]
            elif issubclass(row_type, tuple):
                yield (rowcount,)
        else:
            for row_deep in records:
                if list(row_deep.keys()) == ['explain']:
                    yield (row_deep['explain'],)
                else:
                    assert self.is_aggregation == (row_deep['attributes']['type'] == 'AggregateResult')
                    row_flat = self._make_flat(row_deep, path=(), subroots=self.subroots)
                    # TODO Will be the expression "or x['done']" really correct also for long subrequests?
                    assert all(not isinstance(x, dict) or x['done'] for x in row_flat)
                    if issubclass(row_type, dict):
                        yield {k: fix_data_type(row_flat[k.lower()]) for k in self.aliases}
                    elif issubclass(row_type, list):
                        yield [fix_data_type(row_flat[k.lower()]) for k in self.aliases]
                    elif issubclass(row_type, tuple):
                        yield tuple(fix_data_type(row_flat[k.lower()]) for k in self.aliases)

SALESFORCE_DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%f+0000'
SF_DATETIME_PATTERN = re.compile(r'[1-3]\d{3}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d.\d{3}\+0000$')

def fix_data_type(data: Any, tzinfo: Optional[datetime.timezone] = None) -> Any:
    # this is a simplified function. The data type should be finally read
    # from some reliable field mapping, not to guess by regexp like here.
    # Only a DateTime field has so specific regexp that the guess is
    # acceptable.
    if isinstance(data, str) and SF_DATETIME_PATTERN.match(data):
        datim = datetime.datetime.strptime(data, SALESFORCE_DATETIME_FORMAT)
        datim = datim.replace(tzinfo=tzinfo or pytz.utc)
        return datim
    return data

def mark_quoted_strings(sql: str) -> Tuple[str, List[str]]:
    """Mark all quoted strings in the SOQL by '@' and get them as params,
    with respect to all escaped backslashes and quotes.
    """
    # pattern of a string parameter (pm), a char escaped by backslash (bs)
    # out_pattern: characters valid in SOQL
    pm_pattern = re.compile(r"'[^\\']*(?:\\[\\'][^\\']*)*'")
    bs_pattern = re.compile(r"\\([\\'])")
    out_pattern = re.compile(r"^(?:[-!()*+,.:<=>\w\s|%s])*$")
    missing_apostrophe = "invalid character in SOQL or a missing apostrophe"
    start = 0
    out = []
    params = []
    for match in pm_pattern.finditer(sql):
        out.append(sql[start:match.start()])
        assert out_pattern.match(sql[start:match.start()]), missing_apostrophe
        params.append(bs_pattern.sub('\\1', sql[match.start() + 1:match.end() - 1]))
        start = match.end()
    out.append(sql[start:])
    assert out_pattern.match(sql[start:]), missing_apostrophe
    return '@'.join(out), params

def subst_quoted_strings(sql: str, params: Sequence[str]) -> str:
    """Reverse operation to mark_quoted_strings - substitutes '@' by params.
    """
    parts = sql.split('@')
    params_dont_match = "number of parameters doesn' match the transformed query"
    assert len(parts) == len(params) + 1, params_dont_match  # would be internal error
    out = []
    for i, param in enumerate(params):
        out.append(parts[i])
        out.append("'%s'" % param.replace('\\', '\\\\').replace("\'", "\\\'"))
    out.append(parts[-1])
    return ''.join(out)

def find_closing_parenthesis(sql: str, startpos: int) -> Optional[Tuple[int, int]]:
    """Find the pair of opening and closing parentheses.

    Starts search at the position startpos.
    Returns tuple of positions (opening, closing) if search succeeds, otherwise None.
    """
    pattern = re.compile(r'[()]')
    level = 0
    opening = []  # type: Union[int, List[None]]
    for match in pattern.finditer(sql, startpos):
        par = match.group()
        if par == '(':
            if level == 0:
                opening = match.start()
            level += 1
        if par == ')':
            assert level > 0, "missing '(' before ')'"
            level -= 1
            if level == 0:
                assert isinstance(opening, int)
                closing = match.end()
                return opening, closing
    return None

def transform_except_subquery(sql: str, func: Callable[[str], str]) -> str:
    """Call a func on every part of SOQL query except nested (SELECT ...)"""
    start = 0
    out = []
    while sql.find('(SELECT', start) > -1:
        pos = sql.find('(SELECT', start)
        out.append(func(sql[start:pos]))
        start, pos = nz(find_closing_parenthesis(sql, pos))
        out.append(sql[start:pos])
        start = pos
    out.append(func(sql[start:len(sql)]))
    return ''.join(out)

def split_subquery(sql: str) -> Tuple[str, List[Tuple[str, Any]]]:
    """Split on subqueries and replace them by '&'."""
    sql, params = mark_quoted_strings(sql)
    sql = simplify_expression(sql)
    _ = params  # NOQA
    start = 0
    out = []
    subqueries = []  # List[Tuple[str, Any]]
    pattern = re.compile(r'\(SELECT\b', re.I)
    match = pattern.search(sql, start)
    while match:
        out.append(sql[start:match.start() + 1] + '&')
        start, pos = nz(find_closing_parenthesis(sql, match.start()))
        start, pos = start + 1, pos - 1
        subqueries.append(split_subquery(sql[start:pos]))
        start = pos
        match = pattern.search(sql, start)
    out.append(sql[start:len(sql)])
    return ''.join(out), subqueries

def simplify_expression(txt: str) -> str:
    """Remove all unecessary whitespace and some very usual space"""
    minimal = re.sub(r'\s', ' ',
                     re.sub(r'\s(?=\W)', '',
                            re.sub(r'(?<=\W)\s', '',
                                   txt.strip())))
    # add space before some "(" and after some ")"
    return re.sub(r'\)(?=\w)', ') ',
                  re.sub(r'(,|\b(?:{}))\('.format('|'.join(RESERVED_WORDS)), '\\1 (', minimal)
                  )


import cv2
import numpy as np

def detect_cash(target_amount):
    # Load YOLOv3 network
    net = cv2.dnn.readNetFromDarknet("/home/jetson/CapstoneGUI/Cash_Detection/yolov3-tiny_testing.cfg", "/home/jetson/CapstoneGUI/Cash_Detection/yolov3-tiny_training_final.weights")

    # Load list of classes
    with open("/home/jetson/CapstoneGUI/Cash_Detection/classes.txt") as f:
        classes = [line.strip() for line in f.readlines()]

    # Initialize variables
    total_amount = 0
    #cap = cv2.VideoCapture(0)
    cap = cv2.VideoCapture("nvarguscamerasrc ! video/x-raw(memory:NVMM),format=NV12,width=640,height=480,framerate=30/1 ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink drop=1", cv2.CAP_GSTREAMER)
    target_reached = False

    while True:
        # Check for keypress
        ret, frame = cap.read()
        key = cv2.waitKey(1)

        # If "q" key is pressed, quit the program and close all windows
        if key == ord("q"):
            break

        # If "d" key is pressed, process a single frame
        elif key == ord("d"):
            detection_running = True
            target_reached = False
            ret, frame = cap.read()

            if ret:
                # Convert frame to a blob to feed into YOLOv3
                blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)

                # Feed the blob into the neural network and get the output predictions
                net.setInput(blob)
                layer_outputs = net.forward(net.getUnconnectedOutLayersNames())

                # Initialize lists for detected cash objects and their corresponding monetary values
                cash_objects = []
                cash_values = []

                # Loop through each output layer and detect cash objects
                for output in layer_outputs:
                    for detection in output:
                        scores = detection[5:]
                        class_id = np.argmax(scores)
                        confidence = scores[class_id]
                        if confidence > 0.5 and (classes[class_id].startswith("dollar_") or classes[class_id].startswith("coin_")):
                            # Extract bounding box coordinates and monetary value of cash object
                            box = detection[:4] * np.array([frame.shape[1], frame.shape[0], frame.shape[1], frame.shape[0]])
                            cash_objects.append(box.astype("int"))
                            if classes[class_id].startswith("dollar_"):
                                cash_values.append(int(classes[class_id].split("_")[1]))
                            else:
                                cash_values.append(0.01 if classes[class_id] == "coin_penny" else 0.05 if classes[class_id] == "coin_nickel" else 0.1 if classes[class_id] == "coin_dime" else 0.25)

            # Loop through each detected cash object and add its monetary value to the total amount
            for value in cash_values:
                total_amount += value

            # Check if target amount has been reached
            if total_amount >= target_amount:
                target_reached = True

                # Display message when target amount is reached
                cv2.putText(frame, "Target amount reached!", (10, 110), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
                break
        # Display the total amount and change required on the frame
        # Display the total amount and change required on the frame
        cv2.putText(frame, "Total amount: ${:.2f}".format(total_amount), (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
        cv2.putText(frame, "Amount needed: ${:.2f}".format(target_amount - total_amount), (10, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
        cv2.putText(frame, "Press 'd' to detect, 'q' to add coins", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

        # Display the frame
        cv2.imshow("Cash Detection", frame)

    # Release the camera and close all windows
    cap.release()
    cv2.destroyAllWindows()
    return total_amount


import random
import matplotlib.pyplot as plt

N = 10
P = 10

fitness_list = []  # All 3 used for plotting
fittest_list = []
average = []

class Individual(object):
    def __init__(self):
        self.gene = [0] * N
        self.fitness = 0

def initialise_pop():

    pop = []
    for i in range(0, P):
        temp = []
        fitness = 0
        for x in range(0, N):
            r = random.randint(0, 1)
            temp.append(r)  # Create binary strings chromosomes
            if r == 1:
                fitness += 1      # Give fitness value

        ind = Individual()
        ind.gene = temp.copy()
        ind.fitness = fitness
        pop.append(ind)   # Create a population
    return pop

population = initialise_pop()    # Initial population

print("Initial population")
for obj in population:
    print(obj.gene, obj.fitness)

def plot_value(pop):
    total_fitness = 0
    fittest = 0

    for i in range(0, len(pop)-1):
        ind = pop[i]                      # Get total fitness of the population
        total_fitness += ind.fitness

        if ind.fitness > fittest:           # Get the fittest individual
            fittest = ind.fitness

    av = total_fitness / len(pop)        # Get the average fitness of the population
    average.append(av)
    fitness_list.append(total_fitness)
    fittest_list.append(fittest)

    print("____________________________________________")
    print("Total fitness of the population: ", total_fitness)
    print(" ")
    print("The average fitness of the population: ", av)
    print(" ")
    print("Fittest individual: ", fittest)
    print("____________________________________________")

plot_value(population)     # Initial population values

def selection(pop):
    offs = []

    for n in range(0, len(pop)):
        p1 = random.randint(0, len(pop)-1)
        off1 = pop[p1]

        p2 = random.randint(0, len(pop)-1)
        off2 = pop[p2]

        if off1.fitness > off2.fitness:
            offs.append(off1)  # Selecting the better individuals from the tournament
        else:
            offs.append(off2)

        print(" ")
        print("Selected individuals for tournament: ")
        print(n, off1.gene, off1.fitness)  # Print competing individuals
        print(n+1, off2.gene, off2.fitness)
    print(" ")
    print("Selected parents: ")  # Print the chosen individuals (temporary offsprings)
    for ind in offs:
        print(ind.gene, " Fitness: ", ind.fitness)
        print("____________________________________________")

    return offs

# offspring = selection()

def crossover(pop):
    offs = []

    p = 0
    while p < len(pop):

        parent1 = pop[p]
        p += 1

        parent2 = pop[p]
        p += 1

        n = random.randint(0, N - 1)  # n is the point where cross over will occur
        i = 0
        child1 = []
        child2 = []
        while i < n:
            child1.append(parent1.gene[i])  # Up until n, the child receives the same genes as its parent
            child2.append(parent2.gene[i])
            i += 1

        child1.append(parent2.gene[n])  # The gene under n position is the first gene on each tail (to be swapped)
        child2.append(parent1.gene[n])

        i = n
        while i < N - 1:
            i += 1
            child2.append(parent1.gene[i])  # Tails being swapped (from parent1 to child2 and etc.)
            child1.append(parent2.gene[i])

        ind = Individual()
        ind.gene = child2        # Populate new generation
        ind.fitness = 0
        offs.append(ind)

        ind2 = Individual()
        ind2.gene = child1
        ind.fitness = 0
        offs.append(ind2)

        print(" ")
        print("Individuals to crossover: ")
        print(" ")
        print(parent1.gene, parent1.fitness)
        print(parent2.gene, parent2.fitness)
        print("Crossing point = ", n + 1)
        print("____________________________________________")
        print(" ")
        print("After crossover: ")
        print(" ")
        print(child1)
        print(child2)
        print("____________________________________________")

    return offs

# recombined = crossover()

def mutation(pop):
    mut_rate = 0.04
    new_pop = []

    print("")
    print("Mutation: ")
    print(" ")
    for p in range(0, len(pop)):
        ind = pop[p]
        for i in range(0, N):
            mut_prob = random.randint(0, 100)
            if mut_prob < (100 * mut_rate):  # MUTATION
                print("Mutation occurred on gene ", i + 1)
                if ind.gene[i] == 1:
                    ind.gene[i] = 0
                else:
                    ind.gene[i] = 1
                print(ind.gene)

        new_pop.append(ind)

    return new_pop

# new_generation = mutation()

def fitness_value(pop):

    for ind in pop:
        gene = ind.gene
        fitness = 0            # Give fitness value to a chosen population
        for i in range(0, N):
            if gene[i] == 1:
                fitness += 1
        ind.fitness = fitness

def best_solution(pop):

    fittest = 0
    for ind in pop:
        if ind.fitness > fittest:
            fittest = ind.fitness
            # best = ind.gene
            best = ind

    print("")
    print("Best solution: ", best.gene)

    return best

def worst_solution(pop):

    worst_ind = pop[0]
    for ind in pop:
        if worst_ind.fitness > ind.fitness:
            worst_ind.gene = ind.gene
            worst_ind.fitness = ind.fitness

    print("")
    print("Worst solution", worst_ind.gene, worst_ind.fitness)

    return worst_ind

def main():
    global population

    best = best_solution(population)

    offspring = selection(population)

    print(" Offspring ")
    for obj in offspring:
        print(obj.gene)

    worst = worst_solution(offspring)

    offspring.remove(worst)
    offspring.append(best)

    print(" NEW offspring: ")
    for obj in offspring:
        print(obj.gene)

    recombined = crossover(offspring)

    new_generation = mutation(recombined)

    fitness_value(new_generation)
    plot_value(new_generation)

    print("NEW GENERATION")
    for obj in new_generation:
        print(obj.gene, obj.fitness)

    population = new_generation.copy()

for m in range(0, 3):
    main()

plt.plot(average)  # Blue line
plt.plot(fittest_list)  # Orange line
plt.show()


'''!    @file       task_controller.py
        @brief      Runs the motor and controller tasks together.
        @details    Implements closed-loop position control on a motor
                    using a task defined as a generator.

        @author     Juan Luna
        @date       2022-03-10 Original file
        @date       2022-12-30 Modified for portfolio update
'''
import controller
import motor

class Task_Controller:
    '''! @brief     Task motor controller class.
    '''
    def __init__(self, encoder_share, gain_share, set_point_share, next_flag, ENA_pin, In1_pin, In2_pin, Timer):
        '''! @brief    Instantiates objects of the Task_Motor_Controller class.
             @param  encoder_share  Passes the present value from the encoder
             @param  gain_share    Share variable for proportional gain value.
             @param  set_point_share   Share variable for setpoint value.
             @param  next_flag  Share variable to indicate that the motor has reached its setpoint.
             @param  ENA_pin            Enable pin object for the motor.
             @param  In1_pin       Control pin 1 associated with motor.
             @param  In2_pin       Control pin 2 associated with motor.
             @param  Timer          Timer object for motor.
        '''
        # Define shares for motor and encoder 1

        ## Passes the present value from the encoder
        self.encoder_share = encoder_share
        ## Share variable for proportional gain value.
        self.gain_share = gain_share
        ## Share variable for setpoint value.
        self.set_point_share = set_point_share
        ## Share variable to say when the motor has reached its setpoint
        self.next_flag = next_flag

        # Define motor-related pin objects

        ## Enable pin object for the motor.
        self.ENA = ENA_pin
        ## Control pin 1 associated with motor.
        self.IN1A_pin = In1_pin
        ## Control pin 2 associated with motor.
        self.IN2A_pin = In2_pin
        ## Timer object for motor.
        self.tim_MOT_A = Timer

        ## Motor object
        self.motor = motor.Motor_Driver(self.ENA, self.IN1A_pin, self.IN2A_pin, self.tim_MOT_A)

    def run(self):
        '''! @brief Runs the controller task and sets new duty cycle
        '''
        ## Controller object
        self.controller = controller.Controller(self.set_point_share, self.gain_share.get())

        while True:

            print(self.set_point_share.get())

            ## Encoder position reading
            true_position = int(self.encoder_share.get())
            print('Encoder value: ', true_position)
            ## Difference between measured and setpoint values
            self.controller.set_point(self.set_point_share.get())
            self.calc_error = self.controller.run(true_position)
            self.motor.set_duty_cycle(float(self.calc_error))

            if  self.set_point_share.get() - self.set_point_share.get()*.05 <= true_position <= self.set_point_share.get() + self.set_point_share.get()*.05:
                self.next_flag.put(1)
                self.motor.set_duty_cycle(0)
            yield (0)


#!/usr/bin/env python3
"""
create a filtered csv version of NCBI's accession2taxid
"""
import argparse
import csv
import gzip
import sys
import ya16sdb

def main():
    p = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    p.add_argument('accession2taxid')
    p.add_argument('accessions', nargs=argparse.REMAINDER)
    p.add_argument(
        '--out',
        default=sys.stdout,
        type=argparse.FileType('w'))
    args = p.parse_args()
    accessions = set(ya16sdb.open_clean(args.accessions))
    a2t = csv.reader(gzip.open(args.accession2taxid, 'rt'), delimiter='\t')
    next(a2t)  # header
    acc, tax_id = 1, 2
    a2t = ((a[acc], a[tax_id]) for a in a2t if a[acc] in accessions)
    out = csv.writer(args.out)
    out.writerow(['version', 'tax_id'])
    out.writerows(a2t)

if __name__ == '__main__':
    main()


from flask_restplus import Resource, Namespace
from flask import jsonify, request
from Models.assessments import Assessment
from Util.dto import AssessmentDto
from Services.assessment_service import get_all_assessments,add_assessment,update_assessment, get_assessment, delete_assessment

api=AssessmentDto.api
model=AssessmentDto.model

# sanity check route
@api.route('/')
class AssessmentList(Resource):
  @api.marshal_with(model)
  @api.doc('List of assessments')
  def get(self):
    return get_all_assessments()

  @api.marshal_with(model)
  @api.expect(model)
  def post(self):
    data = request.json
    return add_assessment(data)

@api.route('/<assessment_id>')
@api.param('assessment_id','Assessment id')
@api.response(404,'Assessment not found')
class Assess(Resource):
  @api.doc('Get Assessment info')
  @api.marshal_with(model)
  def get(self, assessment_id):
    assessment= get_assessment(assessment_id)
    if not assessment:
      api.abort(404)
    else:
      return assessment

  def delete(self, assessment_id):
    return delete_assessment(assessment_id)

  @api.doc('Update Assessment info')
  @api.marshal_with(model)
  def post(self,assessment_id):
    data = request.json
    return update_assessment(assessment_id,data)

@api.route('/healthcheck')
class healthCheck(Resource):
  def get(self):
    return jsonify('Ok!')


"""
Created on Nov 28, 2010
Adaboost is short for Adaptive Boosting
@author: Peter
"""
from numpy import array, ones, shape, mat, inf, zeros, multiply, exp, sign
from math import log
import matplotlib.pyplot as plt

def load_simple_data():
    dat_mat = array([
        [1., 2.1],
        [2., 1.1],
        [1.3, 1.],
        [1., 1.],
        [2., 1.]
    ])
    class_labels = [1.0, 1.0, -1.0, -1.0, 1.0]
    return dat_mat, class_labels

# general function to parse tab -delimited floats
def load_data_set(file_name):
    # get number of fields
    num_feat = len(open(file_name).readline().split('\t'))
    data_mat = []
    label_mat = []
    fr = open(file_name)
    for line in fr.readlines():
        line_arr = []
        cur_line = line.strip().split('\t')
        for i in range(num_feat-1):
            line_arr.append(float(cur_line[i]))
        data_mat.append(line_arr)
        label_mat.append(float(cur_line[-1]))
    return data_mat, label_mat

# just classify the data
def stump_classify(data_matrix, dimension, thresh_val, thresh_inequal):
    ret_array = ones((shape(data_matrix)[0], 1))
    if thresh_inequal == 'lt':
        ret_array[data_matrix[:, dimension] <= thresh_val] = -1.0
    else:
        ret_array[data_matrix[:, dimension] > thresh_val] = -1.0
    return ret_array

def build_stump(dataArr, class_labels, D):
    data_matrix = mat(dataArr)
    label_mat = mat(class_labels).T
    m, n = shape(data_matrix)
    num_steps = 10.0
    best_stump = {}
    best_class_est = mat(zeros((m, 1)))
    # init error sum to +infinity
    min_error = inf
    for i in range(n):  # loop over all dimensions
        range_min = data_matrix[:, i].min()
        range_max = data_matrix[:, i].max()
        step_size = (range_max-range_min)/num_steps
        # loop over all range in current dimension
        for j in range(-1, int(num_steps)+1):
            for inequal in ['lt', 'gt']:    # go over less than and greater than
                thresh_val = range_min + float(j) * step_size
                # call stump classify with i, j, lessThan
                predicted_vals = stump_classify(data_matrix, i, thresh_val, inequal)
                err_arr = mat(ones((m, 1)))
                err_arr[predicted_vals == label_mat] = 0
                weighted_error = D.T*err_arr  # calc total error multiplied by D
                # print("split: dim %d, thresh %.2f, thresh inequal: %s, the weighted error is %.3f"
                #       % (i, thresh_val, inequal, weighted_error))
                if weighted_error < min_error:
                    min_error = weighted_error
                    best_class_est = predicted_vals.copy()
                    best_stump['dim'] = i
                    best_stump['thresh'] = thresh_val
                    best_stump['ineq'] = inequal
    return best_stump, min_error, best_class_est

def ada_boost_train_ds(data_arr, class_labels, num_it=40):
    """
    使用单层决策树作为弱分类器的AdaBoost算法
    :param data_arr:
    :param class_labels:
    :param num_it: 迭代次数
    :return:
    """
    weak_class_arr = []
    m = shape(data_arr)[0]
    D = mat(ones((m, 1))/m)   # init D to all equal
    agg_class_est = mat(zeros((m, 1)))
    for i in range(num_it):
        best_stump, error, class_est = build_stump(data_arr, class_labels, D)   # build Stump
        # print("D:", D.T)
        # calc alpha, throw in max(error,eps) to account for error=0
        alpha = float(0.5*log((1.0-error)/max(error, 1e-16)))
        best_stump['alpha'] = alpha
        # store Stump Params in Array
        weak_class_arr.append(best_stump)
        # print("class_est: ", class_est.T)
        # exponent for D calc, getting messy
        exponent = multiply(-1 * alpha * mat(class_labels).T, class_est)
        # Calc New D for next iteration
        D = multiply(D, exp(exponent))
        D = D/D.sum()
        # calc training error of all classifiers, if this is 0 quit for loop early (use break)
        agg_class_est += alpha*class_est
        # print("agg_class_est: ", agg_class_est.T)
        agg_errors = multiply(sign(agg_class_est) != mat(class_labels).T, ones((m, 1)))
        error_rate = agg_errors.sum()/m
        # print("total error: ", error_rate)
        if error_rate == 0.0:
            break
    return weak_class_arr, agg_class_est

def ada_classify(datToClass, classifierArr):
    # do stuff similar to last aggClassEst in ada_boost_train_ds
    dataMatrix = mat(datToClass)
    m = shape(dataMatrix)[0]
    aggClassEst = mat(zeros((m, 1)))
    for i in range(len(classifierArr)):
        # call stump classify
        classEst = stump_classify(
            dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])
        aggClassEst += classifierArr[i]['alpha']*classEst
        # print(aggClassEst)
    return sign(aggClassEst)

def plot_roc(predStrengths, classLabels):
    # cursor
    cur = (1.0, 1.0)
    # variable to calculate AUC
    ySum = 0.0
    numPosClass = sum(array(classLabels) == 1.0)
    yStep = 1/float(numPosClass)
    xStep = 1/float(len(classLabels)-numPosClass)
    # get sorted index, it's reverse
    sortedIndices = predStrengths.argsort()
    fig = plt.figure()
    fig.clf()
    ax = plt.subplot(111)
    # loop through all the values, drawing a line segment at each point
    for index in sortedIndices.tolist()[0]:
        if classLabels[index] == 1.0:
            delX = 0
            delY = yStep
        else:
            delX = xStep
            delY = 0
            ySum += cur[1]
        # draw line from cur to (cur[0]-delX,cur[1]-delY)
        ax.plot([cur[0], cur[0]-delX], [cur[1], cur[1]-delY], c='b')
        cur = (cur[0]-delX, cur[1]-delY)
    ax.plot([0, 1], [0, 1], 'b--')
    plt.xlabel('False positive rate')
    plt.ylabel('True positive rate')
    plt.title('ROC curve for AdaBoost horse colic detection system')
    ax.axis([0, 1, 0, 1])
    plt.show()
    print("the Area Under the Curve is: ", ySum*xStep)

def test_simple_data():
    my_data_mat, my_class_labels = load_simple_data()
    print("my_class_labels")
    print(my_class_labels)
    my_d = mat(ones((5, 1)) / 5)
    # print(build_stump(my_data_mat, my_class_labels, my_d))
    classifierArray = ada_boost_train_ds(my_data_mat, my_class_labels, 9)
    print("classifierArray")
    print(classifierArray)
    print(ada_classify([0, 0], classifierArray))
    print(ada_classify([[5, 5], [0, 0]], classifierArray))

def test_horse_data():
    datArr, labelArr = load_data_set("horseColicTraining2.txt")
    testArr, testLabelArr = load_data_set("horseColicTest2.txt")
    test_size = len(testLabelArr)
    classifier_count = 50
    classifierArray = ada_boost_train_ds(datArr, labelArr, classifier_count)
    prediction10 = ada_classify(testArr, classifierArray)
    errArr = mat(ones((test_size, 1)))
    errCount = errArr[prediction10 != mat(testLabelArr).T].sum()
    print("classifier count:{}, error count:{}, error rate:{:.2f}".format(
        classifier_count, errCount, errCount/test_size))

if __name__ == '__main__':
    # test_simple_data()
    # test_horse_data()
    datArr, labelArr = load_data_set("horseColicTraining2.txt")
    classifierArray, aggClassEst = ada_boost_train_ds(datArr, labelArr, 10)
    plot_roc(aggClassEst.T, labelArr)
    print("Run adaboost finish")


import numpy as np
from classifier import Classifier

class NaiveClassifier(Classifier):
    """
    just guesses the category that occurs most often in the training set
    """
    def __init__(self, classes):
        super().__init__(classes)
        self.probs = np.zeros(len(classes))

    def train(self, dataset, labels):
        N = labels.shape[0]
        for i, c in enumerate(self.classes):
            count = np.sum(labels == c)
            self.probs[i] = count / N

    def test(self, test_set):
        predictions = []
        for example in test_set:
            post_prob = self.probs
            predictions.append(self.classes[np.argmax(post_prob)])

        return np.array(predictions)

if __name__ == '__main__':
    from sklearn.datasets import fetch_20newsgroups

    categories = ['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med']  # limiting to 4 categories
    newsgroups_train = fetch_20newsgroups(subset='train', categories=categories)

    train_data = np.array(newsgroups_train.data)  # getting all trainign examples
    train_labels = newsgroups_train.target  # getting training labels

    print("Total Number of Training Examples: ", len(train_data))  # Outputs -> Total Number of Training Examples:  2257
    print("Total Number of Training Labels: ", len(train_labels))  # Outputs -> #Total Number of Training Labels:  2257

    c = NaiveClassifier(np.unique(train_labels))  # instantiate a NB class object
    print("---------------- Training In Progress --------------------")

    c.train(train_data, train_labels)  # start tarining by calling the train function
    print('----------------- Training Completed ---------------------')

    newsgroups_test = fetch_20newsgroups(subset='test', categories=categories)  # loading test data
    test_data = newsgroups_test.data  # get test set examples
    test_labels = newsgroups_test.target  # get test set labels

    print("Number of Test Examples: ", len(test_data))  # Output : Number of Test Examples:  1502
    print("Number of Test Labels: ", len(test_labels))  # Output : Number of Test Labels:  1502

    pclasses = c.test(test_data)  # get predcitions for test set

    # check how many predcitions actually match original test labels
    test_acc = np.sum(pclasses == test_labels) / float(test_labels.shape[0])

    print("Test Set Examples: ", test_labels.shape[0])  # Outputs : Test Set Examples:  1502
    print("Test Set Accuracy: ", test_acc * 100, "%")  # Outputs : Test Set Accuracy:  93.8748335553 %


# coding: utf-8
from __future__ import unicode_literals

from .common import InfoExtractor
from ..utils import (
    dict_get,
    int_or_none,
    unified_timestamp,
)

class URPlayIE(InfoExtractor):
    _VALID_URL = r'https?://(?:www\.)?ur(?:play|skola)\.se/(?:program|Produkter)/(?P<id>[0-9]+)'
    _TESTS = [{
        'url': 'https://urplay.se/program/203704-ur-samtiden-livet-universum-och-rymdens-markliga-musik-om-vetenskap-kritiskt-tankande-och-motstand',
        'md5': 'ff5b0c89928f8083c74bbd5099c9292d',
        'info_dict': {
            'id': '203704',
            'ext': 'mp4',
            'title': 'UR Samtiden - Livet, universum och rymdens märkliga musik : Om vetenskap, kritiskt tänkande och motstånd',
            'description': 'md5:5344508a52aa78c1ced6c1b8b9e44e9a',
            'timestamp': 1513292400,
            'upload_date': '20171214',
        },
    }, {
        'url': 'https://urskola.se/Produkter/190031-Tripp-Trapp-Trad-Sovkudde',
        'info_dict': {
            'id': '190031',
            'ext': 'mp4',
            'title': 'Tripp, Trapp, Träd : Sovkudde',
            'description': 'md5:b86bffdae04a7e9379d1d7e5947df1d1',
            'timestamp': 1440086400,
            'upload_date': '20150820',
        },
    }, {
        'url': 'http://urskola.se/Produkter/155794-Smasagor-meankieli-Grodan-i-vida-varlden',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)
        url = url.replace('skola.se/Produkter', 'play.se/program')
        webpage = self._download_webpage(url, video_id)
        urplayer_data = self._parse_json(self._html_search_regex(
            r'data-react-class="components/Player/Player"[^>]+data-react-props="({.+?})"',
            webpage, 'urplayer data'), video_id)['currentProduct']
        episode = urplayer_data['title']

        host = self._download_json('http://streaming-loadbalancer.ur.se/loadbalancer.json', video_id)['redirect']
        formats = []
        urplayer_streams = urplayer_data.get('streamingInfo', {})

        for k, v in urplayer_streams.get('raw', {}).items():
            if not (k in ('sd', 'hd') and isinstance(v, dict)):
                continue
            file_http = v.get('location')
            if file_http:
                formats.extend(self._extract_wowza_formats(
                    'http://%s/%splaylist.m3u8' % (host, file_http),
                    video_id, skip_protocols=['f4m', 'rtmp', 'rtsp']))
        self._sort_formats(formats)

        subtitles = {}
        subs = urplayer_streams.get("sweComplete", {}).get("tt", {}).get("location")
        if subs:
            subtitles.setdefault('Svenska', []).append({
                'url': subs,
            })

        image = urplayer_data.get('image') or {}
        thumbnails = []
        for k, v in image.items():
            t = {
                'id': k,
                'url': v,
            }
            wh = k.split('x')
            if len(wh) == 2:
                t.update({
                    'width': int_or_none(wh[0]),
                    'height': int_or_none(wh[1]),
                })
            thumbnails.append(t)

        series = urplayer_data.get('series') or {}
        series_title = dict_get(series, ('seriesTitle', 'title')) or dict_get(urplayer_data, ('seriesTitle', 'mainTitle'))

        return {
            'id': video_id,
            'subtitles': subtitles,
            'title': '%s : %s' % (series_title, episode) if series_title else episode,
            'description': urplayer_data.get('description'),
            'thumbnails': thumbnails,
            'timestamp': unified_timestamp(urplayer_data.get('publishedAt')),
            'series': series_title,
            'formats': formats,
            'duration': int_or_none(urplayer_data.get('duration')),
            'categories': urplayer_data.get('categories'),
            'tags': urplayer_data.get('keywords'),
            'season': series.get('label'),
            'episode': episode,
            'episode_number': int_or_none(urplayer_data.get('episodeNumber')),
        }


import rasterio, os
import pandas as pd
import numpy as np
import joblib

def band_scorer(path):
    """Get Path to 'Tiff' Folder and Name of Band: b2,b3,b4,b5,b6,b7,b8,b8a
    Return mean
    """
    # read all raster values
    with rasterio.open(path, "r") as ds:
        arr = ds.read()
    target_index_file = arr
    A = np.ravel(target_index_file)
    avg = A[~np.isnan(A)].mean()
    return avg

def classify(path):

    wv_tif = path
    folder = r"media\cropClassification\bands"
    src = rasterio.open(wv_tif)
    print(src.count)
    for band in range(1, src.count + 1):
        single_band = src.read(band)

        # get the output name
        out_name = os.path.basename(wv_tif)
        file, ext = os.path.splitext(out_name)
        name = file + "_" + "B" + str(band) + ".tif"
        out_img = os.path.join(folder, name)

        print(out_img + " done")

        # Copy the metadata
        out_meta = src.meta.copy()

        out_meta.update({"count": 1})

        # save the clipped raster to disk
        with rasterio.open(out_img, "w", **out_meta) as dest:
            dest.write(single_band, 1)

    FID = sorted(os.listdir("media/cropClassification/bands"))
    template_dict = {"B01": [], "B02": [], "B03": [], "B04": [], "NDVI": []}
    df = pd.DataFrame(template_dict)

    bands = ["B01", "B02", "B03", "B04"]
    FID = sorted(os.listdir(folder))
    for band in FID:
        bands = [0, 0, 0, 0, 0]
        for i in range(1, 5):
            l = path.split("/")
            print(l)
            image = (
                "media/cropClassification/bands/" + l[2][:-4] + "_B" + str(i) + ".tif"
            )
            bands[i - 1] = band_scorer(image)
        NDVI = (bands[3] - bands[0]) / (bands[3] + bands[0])
        bands[4] = NDVI
        df.loc[len(df.index)] = [bands[0], bands[1], bands[2], bands[3], bands[4]]

    loaded_rf = joblib.load("static/crop_classification.joblib")

    pred = loaded_rf.predict(df)

    return "Sugarcane" if pred[0] == "S" else "Canola"


import functools
import logging

import numpy as np
from scipy.interpolate import griddata, Rbf
from scipy.spatial import cKDTree, ConvexHull, Delaunay, qhull

from . import geometry, tools
from ..package_tools import Exporter
from ..units import units

exporter = Exporter(globals())

log = logging.getLogger(__name__)

def cressman_point(sq_dist, values, radius):
    r"""Generate a Cressman interpolation value for a point.

    The calculated value is based on the given distances and search radius.

    Parameters
    ----------
    sq_dist: (N, ) numpy.ndarray
        Squared distance between observations and grid point
    values: (N, ) numpy.ndarray
        Observation values in same order as sq_dist
    radius: float
        Maximum distance to search for observations to use for
        interpolation.

    Returns
    -------
    value: float
        Interpolation value for grid point.

    """
    weights = tools.cressman_weights(sq_dist, radius)
    total_weights = np.sum(weights)

    return sum(v * (w / total_weights) for (w, v) in zip(weights, values))

def barnes_point(sq_dist, values, kappa, gamma=None):
    r"""Generate a single pass Barnes interpolation value for a point.

    The calculated value is based on the given distances, kappa and gamma values. This
    is calculated as an inverse distance-weighted average of the points in the neighborhood,
    with weights given as:

    .. math:: w = e ^ \frac{-r^2}{\kappa}

    * :math:`\kappa` is a scaling parameter
    * :math:`r` is the distance to a point.

    For more information see [Barnes1964]_ or [Koch1983]_.

    Parameters
    ----------
    sq_dist: (N, ) numpy.ndarray
        Squared distance between observations and grid point
    values: (N, ) numpy.ndarray
        Observation values in same order as sq_dist
    kappa: float
        Response parameter for barnes interpolation.
    gamma: float
        Adjustable smoothing parameter for the barnes interpolation. Default 1.

    Returns
    -------
    value: float
        Interpolation value for grid point.

    """
    if gamma is None:
        gamma = 1
    weights = tools.barnes_weights(sq_dist, kappa, gamma)
    total_weights = np.sum(weights)

    return sum(v * (w / total_weights) for (w, v) in zip(weights, values))

def natural_neighbor_point(xp, yp, variable, grid_loc, tri, neighbors, circumcenters):
    r"""Generate a natural neighbor interpolation of the observations to the given point.

    This uses the Liang and Hale approach [Liang2010]_. The interpolation will fail if
    the grid point has no natural neighbors.

    Parameters
    ----------
    xp: (N, ) numpy.ndarray
        x-coordinates of observations
    yp: (N, ) numpy.ndarray
        y-coordinates of observations
    variable: (N, ) numpy.ndarray
        observation values associated with (xp, yp) pairs.
        IE, variable[i] is a unique observation at (xp[i], yp[i])
    grid_loc: (float, float)
        Coordinates of the grid point at which to calculate the
        interpolation.
    tri: `scipy.spatial.Delaunay`
        Delaunay triangulation of the observations.
    neighbors: (N, ) numpy.ndarray
        Simplex codes of the grid point's natural neighbors. The codes
        will correspond to codes in the triangulation.
    circumcenters: list
        Pre-calculated triangle circumcenters for quick look ups. Requires
        indices for the list to match the simplices from the Delaunay triangulation.

    Returns
    -------
    value: float
       Interpolated value for the grid location

    """
    edges = geometry.find_local_boundary(tri, neighbors)
    edge_vertices = [segment[0] for segment in geometry.order_edges(edges)]
    num_vertices = len(edge_vertices)

    p1 = edge_vertices[0]
    p2 = edge_vertices[1]

    c1 = geometry.circumcenter(grid_loc, tri.points[p1], tri.points[p2])
    polygon = [c1]

    area_list = []
    total_area = 0.0

    for i in range(num_vertices):

        p3 = edge_vertices[(i + 2) % num_vertices]

        try:

            c2 = geometry.circumcenter(grid_loc, tri.points[p3], tri.points[p2])
            polygon.append(c2)

            for check_tri in neighbors:
                if p2 in tri.simplices[check_tri]:
                    polygon.append(circumcenters[check_tri])

            pts = [polygon[i] for i in ConvexHull(polygon).vertices]
            value = variable[(tri.points[p2][0] == xp) & (tri.points[p2][1] == yp)]

            cur_area = geometry.area(pts)

            total_area += cur_area

            area_list.append(cur_area * value[0])

        except (ZeroDivisionError, qhull.QhullError) as e:
            message = ('Error during processing of a grid. '
                       'Interpolation will continue but be mindful '
                       f'of errors in output. {e}')

            log.warning(message)
            return np.nan

        polygon = [c2]

        p2 = p3

    return sum(x / total_area for x in area_list)

@exporter.export
def natural_neighbor_to_points(points, values, xi):
    r"""Generate a natural neighbor interpolation to the given points.

    This assigns values to the given interpolation points using the Liang and Hale
    [Liang2010]_. approach.

    Parameters
    ----------
    points: array-like, (N, 2)
        Coordinates of the data points.
    values: array-like, (N,)
        Values of the data points.
    xi: array-like, (M, 2)
        Points to interpolate the data onto.

    Returns
    -------
    img: numpy.ndarray, (M,)
        Array representing the interpolated values for each input point in `xi`

    See Also
    --------
    natural_neighbor_to_grid

    """
    tri = Delaunay(points)
    members, circumcenters = geometry.find_natural_neighbors(tri, xi)

    if hasattr(values, 'units'):
        org_units = values.units
        values = values.magnitude
    else:
        org_units = None

    img = np.asarray([natural_neighbor_point(*np.array(points).transpose(),
                                             values, xi[grid], tri, neighbors, circumcenters)
                      if len(neighbors) > 0 else np.nan
                      for grid, neighbors in members.items()])

    if org_units:
        img = units.Quantity(img, org_units)

    return img

@exporter.export
def inverse_distance_to_points(points, values, xi, r, gamma=None, kappa=None, min_neighbors=3,
                               kind='cressman'):
    r"""Generate an inverse distance weighting interpolation to the given points.

    Values are assigned to the given interpolation points based on either [Cressman1959]_ or
    [Barnes1964]_. The Barnes implementation used here is based on [Koch1983]_.

    Parameters
    ----------
    points: array-like, (N, 2)
        Coordinates of the data points.
    values: array-like, (N,)
        Values of the data points.
    xi: array-like, (M, 2)
        Points to interpolate the data onto.
    r: float
        Radius from grid center, within which observations are considered and weighted.
    gamma: float
        Adjustable smoothing parameter for the barnes interpolation. Default None.
    kappa: float
        Response parameter for barnes interpolation. Default None.
    min_neighbors: int
        Minimum number of neighbors needed to perform barnes or cressman interpolation
        for a point. Default is 3.
    kind: str
        Specify what inverse distance weighting interpolation to use.
        Options: 'cressman' or 'barnes'. Default 'cressman'

    Returns
    -------
    img: numpy.ndarray, (M,)
        Array representing the interpolated values for each input point in `xi`

    See Also
    --------
    inverse_distance_to_grid

    """
    if kind == 'cressman':
        interp_func = functools.partial(cressman_point, radius=r)
    elif kind == 'barnes':
        interp_func = functools.partial(barnes_point, kappa=kappa, gamma=gamma)
    else:
        raise ValueError(f'{kind} interpolation not supported.')

    obs_tree = cKDTree(points)
    indices = obs_tree.query_ball_point(xi, r=r)

    if hasattr(values, 'units'):
        org_units = values.units
        values = values.magnitude
    else:
        org_units = None

    img = np.asarray([interp_func(geometry.dist_2(*grid, *obs_tree.data[matches].T),
                                  values[matches]) if len(matches) >= min_neighbors else np.nan
                      for matches, grid in zip(indices, xi)])

    if org_units:
        img = units.Quantity(img, org_units)

    return img

@exporter.export
def interpolate_to_points(points, values, xi, interp_type='linear', minimum_neighbors=3,
                          gamma=0.25, kappa_star=5.052, search_radius=None, rbf_func='linear',
                          rbf_smooth=0):
    r"""Interpolate unstructured point data to the given points.

    This function interpolates the given `values` valid at ``points`` to the points `xi`.
    This is modeled after `scipy.interpolate.griddata`, but acts as a generalization of it by
    including the following types of interpolation:

    - Linear
    - Nearest Neighbor
    - Cubic
    - Radial Basis Function
    - Natural Neighbor (2D Only)
    - Barnes (2D Only)
    - Cressman (2D Only)

    Parameters
    ----------
    points: array-like, (N, P)
        Coordinates of the data points.
    values: array-like, (N,)
        Values of the data points.
    xi: array-like, (M, P)
        Points to interpolate the data onto.
    interp_type: str
        What type of interpolation to use. Available options include:
        1) "linear", "nearest", "cubic", or "rbf" from `scipy.interpolate`.
        2) "natural_neighbor", "barnes", or "cressman" from `metpy.interpolate`.
        Default "linear".
    minimum_neighbors: int
        Minimum number of neighbors needed to perform Barnes or Cressman interpolation for a
        point. Default is 3.
    gamma: float
        Adjustable smoothing parameter for the barnes interpolation. Default 0.25.
    kappa_star: float
        Response parameter for barnes interpolation, specified non-dimensionally
        in terms of the Nyquist. Default 5.052.
    search_radius: float
        A search radius to use for the Barnes and Cressman interpolation schemes.
        If search_radius is not specified, it will default to 5 times the average spacing of
        observations.
    rbf_func: str
        Specifies which function to use for Rbf interpolation.
        Options include: 'multiquadric', 'inverse', 'gaussian', 'linear', 'cubic',
        'quintic', and 'thin_plate'. Default 'linear'. See `scipy.interpolate.Rbf` for more
        information.
    rbf_smooth: float
        Smoothing value applied to rbf interpolation.  Higher values result in more smoothing.

    Returns
    -------
    values_interpolated: ndarray, (M,)
        Array representing the interpolated values for each input point in `xi`.

    See Also
    --------
    interpolate_to_grid

    Notes
    -----
    This function primarily acts as a wrapper for the individual interpolation routines. The
    individual functions are also available for direct use.

    """
    # If this is a type that `griddata` handles, hand it along to `griddata`
    if interp_type in ['linear', 'nearest', 'cubic']:
        if hasattr(values, 'units'):
            org_units = values.units
            values = values.magnitude
        else:
            org_units = None

        ret = griddata(points, values, xi, method=interp_type)

        if org_units:
            ret = units.Quantity(ret, org_units)

        return ret

    # If this is natural neighbor, hand it along to `natural_neighbor`
    elif interp_type == 'natural_neighbor':
        return natural_neighbor_to_points(points, values, xi)

    # If this is Barnes/Cressman, determine search_radius and hand it along to
    # `inverse_distance`
    elif interp_type in ['cressman', 'barnes']:
        ave_spacing = tools.average_spacing(points)
        if search_radius is None:
            search_radius = 5 * ave_spacing

        if interp_type == 'cressman':
            return inverse_distance_to_points(points, values, xi, search_radius,
                                              min_neighbors=minimum_neighbors,
                                              kind=interp_type)
        else:
            kappa = tools.calc_kappa(ave_spacing, kappa_star)
            return inverse_distance_to_points(points, values, xi, search_radius, gamma, kappa,
                                              min_neighbors=minimum_neighbors,
                                              kind=interp_type)

    # If this is radial basis function, make the interpolator and apply it
    elif interp_type == 'rbf':
        points_transposed = np.array(points).transpose()
        xi_transposed = np.array(xi).transpose()

        if hasattr(values, 'units'):
            org_units = values.units
            values = values.magnitude
        else:
            org_units = None

        rbfi = Rbf(points_transposed[0], points_transposed[1], values, function=rbf_func,
                   smooth=rbf_smooth)
        ret = rbfi(xi_transposed[0], xi_transposed[1])

        if org_units:
            ret = units.Quantity(ret, org_units)

        return ret

    else:
        raise ValueError(f'Interpolation option {interp_type} not available. '
                         'Try: linear, nearest, cubic, natural_neighbor, '
                         'barnes, cressman, rbf')


from piccata.constants import *
from piccata import core
from piccata import message
from piccata import resource
from transport import tsocket

from ipaddress import ip_address
import sys

import unittest
import time

SERVER_PORT = 5683

PAYLOAD = b"123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 "

class TextResource(resource.CoapResource):

    def __init__(self):
        resource.CoapResource.__init__(self)
        self.text = PAYLOAD

    def render_GET(self, request):
        response = message.Message(code=CONTENT, payload=self.text)
        return response

class TestClientServerCommunication(unittest.TestCase):

    def setUp(self):
        self.stopWaiting = False
        self.responseReceived = False
        self.responsePayload = ""

        server_root = resource.CoapResource()
        text = TextResource()
        server_root.put_child(b'text', text)
        server_endpoint = resource.CoapEndpoint(server_root)

        self.server_transport = tsocket.SocketTransport(SERVER_PORT)
        self.server_protocol = core.Coap(self.server_transport)
        self.server_request_handler = resource.ResourceManager(server_endpoint)
        self.server_transport.register_receiver(self.server_protocol)
        self.server_protocol.register_request_handler(self.server_request_handler)

        self.client_transport = tsocket.SocketTransport()
        self.client_protocol = core.Coap(self.client_transport)
        self.client_transport.register_receiver(self.client_protocol)

        self.server_transport.open()
        self.client_transport.open()

    def tearDown(self):
        self.server_transport.close()
        self.client_transport.close()

    def _handle_text_response(self, result, request, response):
        if result == RESULT_SUCCESS:
            self.responsePayload = response.payload
            self.responseReceived = True
            self.stopWaiting = True
        else:
            self.stopWaiting = True
            self.assertFalse(True, "No response received.")

    def test_client_server_communication(self):
        request = message.Message(mtype = CON, code=GET)
        request.opt.uri_path = (b"text", )
        request.remote = (ip_address(u"127.0.0.1"), SERVER_PORT)
        request.timeout = ACK_TIMEOUT
        request.payload = b""
        req = self.client_protocol.request(request, self._handle_text_response)

        counter = 0
        while not self.stopWaiting:
            counter += 1
            time.sleep(0.01)
            self.assertLess(counter, 500, "Timeout while waiting for callback from Coap")

        self.assertTrue(self.responseReceived)
        self.assertEqual(self.responsePayload, PAYLOAD)

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


import logging
from typing import TypeVar, Dict, List
from xml.etree.ElementTree import Element as XMLElement

from lxml import etree

from nmap_scan.CompareHelper import compare_lists_equal
from nmap_scan.Exceptions.NmapDictParserException import NmapDictParserException
from nmap_scan.Exceptions.NmapXMLParserException import NmapXMLParserException
from nmap_scan.Host.HostAddress import HostAddress
from nmap_scan.Host.HostName import HostName
from nmap_scan.Stats.Status import Status
from nmap_scan.Validator import validate

T = TypeVar('T', bound='HostHint')

class HostHint:

    def __init__(self, xml: XMLElement, validate_xml: bool = True):
        if validate_xml:
            validate(xml)
        self.__xml: XMLElement = xml
        self.__statuses: List[Status] = []
        self.__addresses: List[HostAddress] = []
        self.__hostnames: List[HostName] = []
        self.__parse_xml()

    def __eq__(self, other: T) -> bool:
        return self.equals(other)

    def __ne__(self, other: T) -> bool:
        return not self.__eq__(other)

    def __iter__(self):
        yield "statuses", [dict(e) for e in self.__statuses]
        yield "addresses", [dict(e) for e in self.__addresses]
        yield "hostnames", [dict(e) for e in self.__hostnames]

    @staticmethod
    def dict_to_xml(d: Dict[str, any], validate_xml: bool = True) -> T:
        xml = etree.Element('hosthint')
        if None is not d.get('statuses', None):
            for status_dict in d['statuses']:
                xml.append(Status.dict_to_xml(status_dict, validate_xml))
        if None is not d.get('addresses', None):
            for address_dict in d['addresses']:
                xml.append(HostAddress.dict_to_xml(address_dict, validate_xml))
        if None is not d.get('hostnames', None):
            hostnames_xml = etree.Element('hostnames')
            for hostname_dict in d['hostnames']:
                hostnames_xml.append(HostName.dict_to_xml(hostname_dict, validate_xml))
            xml.append(hostnames_xml)

        if validate_xml:
            try:
                validate(xml)
            except NmapXMLParserException:
                raise NmapDictParserException()

        return xml

    @staticmethod
    def from_dict(d: Dict[str, any]) -> T:
        try:
            return HostHint(HostHint.dict_to_xml(d, False))
        except NmapXMLParserException:
            raise NmapDictParserException()

    def equals(self, other: T) -> bool:
        return isinstance(other, HostHint) \
            and compare_lists_equal(self.__statuses, other.get_statuses()) \
            and compare_lists_equal(self.__addresses, other.get_addresses()) \
            and compare_lists_equal(self.__hostnames, other.get_hostnames())

    def get_xml(self) -> XMLElement:
        return self.__xml

    def get_statuses(self) -> List[Status]:
        return self.__statuses

    def get_addresses(self) -> List[HostAddress]:
        return self.__addresses

    def get_hostnames(self) -> List[HostName]:
        return self.__hostnames

    def __parse_xml(self):
        logging.info('Parsing HostHint')

        for xml in self.__xml.findall('status'):
            self.__statuses.append(Status(xml, False))

        for xml in self.__xml.findall('address'):
            self.__addresses.append(HostAddress(xml, False))

        hostnames_xml = self.__xml.find('hostnames')
        if hostnames_xml != None:
            for hostname_xml in hostnames_xml.findall('hostname'):
                self.__hostnames.append(HostName(hostname_xml, False))


from .basehandler import BaseHandler
from ..file import DefaultHandler as FileHandler
from .. import models, forms, settings
from andweb.utils import cacheclassproperty
from django.db.models import Q
import json

class DefaultHandler(BaseHandler):
    __slots__ = ()

    def oninit(self):
        super().oninit()
        if self.is_get:
            self.assign('cats', models.Category.objects.filter(parent=None))

    def list(self):
        if self.is_get:
            args = self.get_args_adv(('search', ('cat', int, 0),
                ('page', int, 1), ('limit', int, 0), 'order_by', 'order'), '')
            search = args.search
            cat = args.cat
            query = Q()
            if search:
                query |= Q(name__icontains=search) | Q(desc__icontains=search)
            if cat:
                query &= Q(category_id=cat) | Q(category__parent_id=cat)
            data = models.Goods.publics().filter(query)
            if args.order_by:
                if args.order == 'DESC':
                    args.order_by = '-' + args.order_by
                data = data.order_by(args.order_by)
            data, pagination = self.pagination(data, args.page, args.limit)
            hots = models.Goods.publics().order_by('-view_count')[:3]
            return self.render(
                data=data,
                args=args,
                catid=cat,
                hots=hots,
                pagination=pagination)

    def publish(self):
        if self.is_get:
            form = forms.GoodsForm()
            if self.userinfo:
                form.initial = {'phone': self.userinfo.phone}
                catid = self.get_arg('cat', None)
                if catid:
                    form.initial['category'] = catid
            del form.fields['images']
        else:
            form = forms.GoodsForm(self.request.POST)
            if form.is_valid():
                form.instance.seller = self.user
                form.instance.status = models.Goods.VERIFY
                form.save()
                return self.redirect('../account/goods')

        return self.render(form=form, upload_url=self.upload_url)

    def update(self):
        goods = models.Goods.objects.filter(id=self.get_arg('id'), seller=self.user).first()
        if goods:
            if self.is_get:
                form = forms.GoodsForm(instance=goods, is_update=True)
                del form.fields['images']
            else:
                form = forms.GoodsForm(self.request.POST, instance=goods, is_update=True)
                if form.is_valid():
                    form.instance.status = models.Goods.VERIFY
                    form.save()
                    return self.redirect('../account/goods')

            images = {"files": [FileHandler.get_file_dict(img) for img in goods.images.all()]}
            iamges = json.dumps(images)
            return self.render(
                form=form,
                upload_url=self.upload_url,
                images=iamges
            )
        else:
            return self.page404()

    def detail(self):
        if self.is_get:
            goods = models.Goods.objects.filter(id=self.get_arg('id')).first()
            if goods:
                similar = models.Goods.objects.filter(category=goods.category).exclude(id=goods.id)
                hots = models.Goods.objects.exclude(id=goods.id).order_by('-view_count')[:6]
                goods.view_count += 1
                goods.save()
                return self.render(goods=goods, similar=similar, hots=hots)
        return self.page404()

    def delete(self):
        models.Goods.objects.filter(id=self.get_arg('id'), seller=self.user).delete()
        return self.goback()

    def comment(self):
        if self.is_get:
            return self.render()
        else:
            pass

    @cacheclassproperty
    def upload_url(self):
        return FileHandler.guessUrl('upload')


"""カスタムsignalとslotの作成方法
signalとslotのオーバーロード

[説明ページ]
https://tech.nkhn37.net/pyqt-signal-slot-custom/#signalslot-2
"""
import sys

from PyQt6 import QtCore as qtc
from PyQt6 import QtGui as qtg
from PyQt6 import QtWidgets as qtw

class FormWindow(qtw.QWidget):
    """フォームウィンドウ"""

    # シグナルを定義(オーバーロード)
    submitted = qtc.pyqtSignal([str], [int, str])

    def __init__(self):
        """コンストラクタ"""
        super().__init__()
        # 画面タイトルの設定
        self.setWindowTitle("フォーム")
        # レイアウトの設定
        layout = qtw.QHBoxLayout()
        self.setLayout(layout)

        # ウィジェットの生成
        self.line_edit = qtw.QLineEdit()
        self.submit_button = qtw.QPushButton("登録", clicked=self.on_submit)

        # レイアウト配置
        layout.addWidget(self.line_edit)
        layout.addWidget(self.submit_button)

    def on_submit(self):
        """登録ボタン用スロット"""
        text = self.line_edit.text()
        if text.isdigit():
            # 数値の場合は数値と文字列を返却する
            self.submitted[int, str].emit(int(text), text)
        else:
            # その他の場合は文字列のみ返却する
            self.submitted[str].emit(text)

        # フォームウィンドウを閉じる
        self.close()

class MainWindow(qtw.QWidget):
    """メインウィンドウ"""

    def __init__(self):
        super().__init__()
        # 画面タイトルの設定
        self.setWindowTitle("カスタムスロットの作成")
        # 画面サイズの設定
        self.resize(320, 100)

        # メインレイアウトの設定
        main_layout = qtw.QVBoxLayout()
        self.setLayout(main_layout)

        # ウィジェットの生成
        self.label = qtw.QLabel("文字列表示欄")
        self.change_button = qtw.QPushButton("変更")
        self.change_button.clicked.connect(self.on_change)

        # レイアウト配置
        main_layout.addWidget(self.label)
        main_layout.addWidget(self.change_button)
        main_layout.addStretch()

        # 画面表示
        self.show()

    def on_change(self):
        """フォーム呼び出し用スロット"""
        # フォームウィンドウをインスタンス化
        self.form_window = FormWindow()
        # フォームウィンドウのシグナルをラベルのsetTextに接続
        self.form_window.submitted[str].connect(self.on_submitted_str)
        self.form_window.submitted[int, str].connect(self.on_submitted_int_and_str)
        # フォームウィンドウを表示
        self.form_window.show()

    def on_submitted_str(self, text):
        """slot (strのsignal用)

        Args:
            text: 文字列
        """
        self.label.setText(text)

    def on_submitted_int_and_str(self, value, text):
        """slot (intとstrのsignal用)

        Args:
            value: 数値
            text: 文字列
        """
        disp_text = f"value:{value}, text:{text}"
        self.label.setText(disp_text)

def main():
    """メイン関数"""
    app = qtw.QApplication(sys.argv)
    mv = MainWindow()
    sys.exit(app.exec())

if __name__ == "__main__":
    main()