# coding: utf-8

"""

This module contains all data objects getted from forum and wiki API. These API provides JSON data, and this module enhances data model by mirroring data attributes to data model. Here is an exemple :

.. code-block:: python

    from campbot import CampBot

    bot = CampBot(use_demo=True)
    waypoint = bot.wiki.get_waypoint(107702)

    # this two lines are perfectly equivalents
    elevation = waypoint["elevation"]  # standard way to access data
    elevation = waypoint.elevation  # and sexier way.

    # set values is possible
    waypoint.elevation = 1000
    assert waypoint["elevation"] == 1000  # it's true!

We try to use the second way every times it's possible in this documentation.
"""

from __future__ import print_function, unicode_literals, division

import re
import logging
from .differ import get_diff_report

def _input(message):  # pragma: no cover
    try:  # py 2
        return raw_input(message)
    except NameError:  # py 3
        return input(message)

def get_constructor(document_type):
    return {
        "u": WikiUser,
        "a": Area,
        "w": Waypoint,
        "o": Outing,
        "i": Image,
        "m": Map,
        "x": Xreport,
        "c": Article,
        "b": Book,
        "r": Route,
    }[document_type]

class BotObject(dict):
    """
    Base class for all data object
    """

    def __init__(self, campbot, data):
        super(BotObject, self).__init__(data)
        self._campbot = campbot

    # make instance.key equivalent to instance["key"]
    def __getattr__(self, item):
        if item.startswith("_"):
            raise AttributeError(
                "Object {} has not attribute {}".format(self.__class__.__name__, item)
            )

        if item not in self:  # pragma: no cover
            print("666777", self)
            raise AttributeError(
                "Object {} has not attribute {}".format(self.__class__.__name__, item)
            )

        return self[item]

    def __setattr__(self, key, value):
        if key in self:
            self[key] = value
        else:
            super(BotObject, self).__setattr__(key, value)

    def _convert_list(self, name, constructor):
        if name in self:
            self[name] = [constructor(self._campbot, data) for data in self[name]]

    # def _convert_dict(self, name, constructor):
    #     if name in self:
    #         self[name] = {
    #             key: constructor(self._campbot, self[name][key]) for key in self[name]
    #         }

class Version(BotObject):
    """
    A historical version of one wiki document.
    """

    def __init__(self, campbot, data):
        super(Version, self).__init__(campbot, data)
        if self["document"]:
            self["document"] = get_constructor(self["document"]["type"])(
                campbot, self["document"]
            )
        else:
            self["document"] = None

    def get_diff_url(self, lang):
        constructor = get_constructor(document_type=self.document.type)

        if not self.previous_version_id:
            return self.document.get_url(lang)

        return "{}/{}/diff/{}/{}/{}/{}".format(
            self._campbot.wiki.ui_url,
            constructor.url_path,
            self.document.document_id,
            lang,
            self.previous_version_id,
            self.version["version_id"],
        )

    def get_locale_length(self, lang):
        locale = self.document.get_locale(lang)

        return locale.get_length() if locale else 0

class Contribution(BotObject):
    def __init__(self, campbot, data):
        super(Contribution, self).__init__(campbot, data)
        self["document"] = get_constructor(self["document"]["type"])(
            campbot, self["document"]
        )
        self["user"] = ShortWikiUser(campbot, self["user"])

    def get_full_document(self):
        return self._campbot.wiki.get_wiki_object(
            self.document["document_id"], document_type=self.document["type"]
        )

class Locale(BotObject):
    """
    Locale is a set of field, given a lang.
    """

    def get_title(self):
        """
        Get the title, with prefix if it exists.

        :return: String, pretty title
        """

        if "title_prefix" in self:
            return "{} : {}".format(self.title_prefix, self.title)
        else:
            return self.title

    def get_locale_fields(self):
        return (
            "description",
            "gear",
            "remarks",
            "route_history",
            "summary",
            "access",
            "access_period",
            "title",
            "external_resources",
            "other_comments",
            "slope",
            "slackline_anchor1",
            "slackline_anchor2",
        )

    def get_length(self):
        """
        Get text length

        :return: Integer, number of characters
        """

        result = 0
        for field in self.get_locale_fields():
            if field in self and self[field]:
                result += len(self[field])

        return result

class WikiObject(BotObject):
    """
    Base object for all wiki documents
    """

    url_path = None

    def __init__(self, campbot, data):
        super(WikiObject, self).__init__(campbot, data)

        if "associations" in self and self["associations"] is not None:
            self["associations"] = BotObject(campbot=campbot, data=self["associations"])
            self.associations._convert_list("images", Image)

        self._convert_list("locales", Locale)
        self._data = data

    def get_url(self, lang=None):
        """
        :return: camptocamp.org URL.
        """

        return "{}/{}/{}{}".format(
            self._campbot.wiki.ui_url,
            self.url_path,
            self.document_id,
            "" if lang is None else "/" + lang,
        )

    def get_history_url(self, lang):
        """

        :return: camptocamp.org version list URL
        """

        return "{}/{}/history/{}/{}".format(
            self._campbot.wiki.ui_url, self.url_path, self.document_id, lang
        )

    def get_title(self, lang):
        locale = self.get_locale(lang)
        return locale.get_title() if locale else ""

    def get_locale(self, lang):
        """
        :param lang: fr, en, de ...

        :return: String, or None if locale does not exists in this lang
        """

        if "locales" not in self:
            return None

        for locale in self.locales:
            if locale.lang == lang:
                return locale

    def search(self, patterns, lang):
        """
        Search a pattern (regular expression)

        :param lang: fr, de, en...

        :return: True if pattern is found, False otherwise
        """

        locale = self.get_locale(lang)

        for field in locale.get_locale_fields():
            if field in locale and locale[field]:
                for pattern in patterns:
                    if re.search(pattern, locale[field]):
                        return True
        return False

    def print_diff(self):
        report = get_diff_report(self._data, self)

        for l in report:
            print(l)

    def _build_payload(self, message):
        return {"document": self, "message": message}

    def save(self, message, ask_before_saving=True):
        """
        Save object to camptocamp.org. Bot must be authentified.

        :param message: Modification comment
        :param ask_before_saving: Boolean, ask user before saing document

        :return: raw request response, useless.
        """

        self.print_diff()

        if ask_before_saving:
            if _input("Save {} : {}, y/[n] ?\n".format(self.get_url(), message)) != "y":
                return None
        else:
            logging.info(f"Saving {self.get_url()} : {message}")

        return self._campbot.wiki.put(
            "/{}/{}".format(self.url_path, self.document_id),
            self._build_payload(message),
        )

    def is_valid(self):
        """
        :return: True if document can be saved
        """

        return self.get_invalidity_reason() is None

    def is_personal(self):
        return False

    def get_invalidity_reason(self):
        return None

class ShortWikiUser(BotObject):
    def get_contributions_url(self):
        return "{}/whatsnew#u={}".format(self._campbot.wiki.ui_url, self.user_id)

    def is_newbie(self):
        contribs = self._campbot.wiki.get(
            "/documents/changes?limit=50&u={}".format(self.user_id)
        )
        return len(contribs["feed"]) < 50

    def get_wiki_user(self):
        return self._campbot.wiki.get_user(user_id=self.user_id)

class WikiUser(WikiObject):
    url_path = "profiles"

    def get_contributions(self, oldest_date=None, newest_date=None):
        return self._campbot.wiki.get_contributions(
            user_id=self.document_id, oldest_date=oldest_date, newest_date=newest_date
        )

    def get_last_contribution(self, oldest_date=None, newest_date=None):
        for contribution in self.get_contributions(
            oldest_date=oldest_date, newest_date=newest_date
        ):
            return contribution

        return None

    def is_personal(self):
        return True

class Route(WikiObject):
    """Route object : https://www.camptocamp.org/routes"""

    url_path = "routes"

class Article(WikiObject):
    """Article object : https://www.camptocamp.org/articles"""

    url_path = "articles"

    def is_personal(self):
        return self.article_type == "personal"

class Image(WikiObject):
    """Image object : https://www.camptocamp.org/images"""

    url_path = "images"

    def is_personal(self):
        return self.image_type in ("personal", "copyright")

class Book(WikiObject):
    """Book object : https://www.camptocamp.org/books"""

    url_path = "books"

class Xreport(WikiObject):
    """Xreport object : https://www.camptocamp.org/xreports"""

    url_path = "xreports"

    def is_personal(self):
        return True

class Waypoint(WikiObject):
    """Waypoint object : https://www.camptocamp.org/waypoints"""

    url_path = "waypoints"

    def get_invalidity_reason(self):
        if self.waypoint_type in ("hut", "gite") and self.custodianship is None:
            return "custodianship is missing"

        if self.elevation is None and self.waypoint_type not in ("climbing_indoor",):
            return "elevation is missing"

        return None

class Area(WikiObject):
    """Area object : https://www.camptocamp.org/areas"""

    url_path = "areas"

    def _build_payload(self, message):
        payload = super(Area, self)._build_payload(message)

        #  Geometry info must not be present in payload, otherwise, save actions fails
        del payload["document"]["geometry"]

        return payload

class Map(WikiObject):
    """Map object : https://www.camptocamp.org/maps"""

    url_path = "maps"

class Outing(WikiObject):
    """Outings object : https://www.camptocamp.org/outings"""

    url_path = "outings"

    def is_personal(self):
        return True

class ForumUser(BotObject):
    def get_admin_view(self):
        return self._campbot.forum.get(
            "/admin/users/{}/{}.json".format(self.id, self.username)
        )

    def anonymise(self):
        return self._campbot.forum.put(
            "/admin/users/{}/anonymize.json".format(self.id), data=None
        )

class Post(BotObject):
    def __init__(self, campbot, data):
        super(Post, self).__init__(campbot, data)
        self._convert_list("polls", Poll)

class Poll(BotObject):
    def __init__(self, campbot, data):
        super(Poll, self).__init__(campbot, data)


"""Submit proposal content."""
import os
from typing import Optional

import httpx
from starlette.datastructures import UploadFile

from saltapi.auth.token import create_token
from saltapi.repository.user_repository import User
import logging

logger = logging.getLogger(__name__)

proposal_submission_url = f"{os.environ['STORAGE_SERVICE_URL']}/proposal/submit"

async def submit_proposal(
    proposal: UploadFile, proposal_code: Optional[str], submitter: str
) -> str:
    """Submit a proposal."""
    generic_error = "The proposal could not be sent to the storage service."
    files = {
        "proposal": (proposal.filename, proposal.file, "application/octet-stream"),
    }
    data = {
        "submitter": submitter,
    }
    if proposal_code:
        data["proposal_code"] = proposal_code
    user = User(
        id=-1,
        username="admin",
        first_name="",
        last_name="",
        email="",
        roles=["Admin"],
        permissions=[],
    )
    auth_token = create_token(user=user, expiry=300, algorithm="RS256")
    headers = {"Authorization": f"Bearer {auth_token}"}
    try:
        async with httpx.AsyncClient() as client:
            response = await client.post(
                proposal_submission_url, data=data, files=files, headers=headers
            )
    except Exception:
        logger.exception(msg=generic_error)
        raise Exception(generic_error)
    submission_id = _submission_id(response)
    if submission_id:
        return submission_id

    # error handling
    error = _submission_error(response)
    if error:
        logger.error(msg=error)
        raise Exception(error)
    else:
        logger.error(msg=generic_error)
        raise Exception(generic_error)

def _submission_id(response: httpx.Response) -> Optional[str]:
    """
    Extract the submission id sent by the server, if there is one.

    The response body is parsed as a JSON object and its submission_id field is
    returned. If this fails (because the response isn't JSON object or has no
    submission_id field) None is returned.
    """
    try:
        submission_id = response.json().get("submission_id")
        if submission_id is not None:
            return str(submission_id)
        else:
            return None
    except Exception:
        return None

def _submission_error(response: httpx.Response) -> Optional[str]:
    """
    Extract the error message sent by the server, if there is one.

    The response body and is parsed as a JSON object and its error field is returned.
    If this fails (because the response isn't JSON object or has no error field) None is
    returned.
    """
    try:
        error = response.json().get("error")
        if error is not None:
            return str(error)
        else:
            return None
    except Exception:
        return None


from typing import List
from RLEnv.EnvLayer.PCBRoutingEnv import PCBRoutingEnv
from scipy.spatial.distance import cityblock
import numpy as np

class rl_env(PCBRoutingEnv):
    def __init__(
        self,
        resolution: float,
        pcb_folder: str,
        pcb_names: List[str],
        connect_coef: float=20.0,
        dist_coef: float=0.5,
        path_coef: float = 0.1
    ) -> None:
        super().__init__(resolution, pcb_folder, pcb_names)
        self.connect_coef = connect_coef
        self.dist_coef = dist_coef
        self.path_coef = path_coef

    def reward(self) -> float:
        if np.array_equal(self._agent_location, self._target_location):
            return self.connect_coef
        if self.conflict:
            return -self.dist_coef * cityblock(self._agent_location, self._target_location)

        return -self.path_coef


from struct import unpack
import json
import hid
from math import cos, atan

USB_VID = 0x04d8
USB_PID = 0xef7e

def hid_multiread(dev):
    data = dev.read(128, timeout_ms=10)
    res = data

    while len(data) > 0:
        data = dev.read(128, timeout_ms=10)
        res.extend(data)

    return res

def hid_query(dev, addr):
    # 68 byte request, might actually need 64, but not clear
    # when hid versus hidraw is used.
    buffer = bytearray([0] * 68)

    buffer[0] = 0  # Report ID
    buffer[1] = 0
    buffer[2] = addr >> 8  # Page to read
    buffer[3] = addr & 0xff

    res = dev.send_feature_report(buffer)
    assert res >= 0

    res = hid_multiread(dev)
    assert res[:4] == list(buffer[:4])

    return res[4:]

class Calibration:

    def __init__(self, json_in):
        config = json_in

        self.screenW = int(config['screenW']['value'])
        self.screenH = int(config['screenH']['value'])
        self.DPI = int(config['DPI']['value'])
        self.pitch = config['pitch']['value']
        self.slope = config['slope']['value']
        self.center = config['center']['value']

        # Physical image width
        self.screenInches = self.screenW / self.DPI

        self.pitch = self.pitch * self.screenInches * cos(atan(1.0 / self.slope))
        self.tilt = self.screenH / (self.screenW * self.slope)
        self.subp = 1.0 / (3 * self.screenW) * self.pitch

def lg_json(usb_vid=USB_VID, usb_pid=USB_PID, save_flag=False, json_name="LookingGlassConfig.json"):
    '''
    :param usb_vid: Looking Glass USB port VID, look up by 'sudo lsusb | grep Microchip'
    :param usb_pid: Looking Glass USB port PID, look up by 'sudo lsusb | grep Microchip'
    :param save_flag: whether to save the json
    :param json_name: save json name
    :return: a Calibration class of the Looking Glass
    '''
    devs = list(hid.enumerate(usb_vid, usb_pid))
    # print(devs)
    assert len(devs) == 1
    devinfo = devs[0]

    dev = hid.device()
    dev.open_path(devinfo['path'])
    # dev.set_nonblocking(1)

    # Data is read in pages of 64 bytes. First page (0) starts with a
    # 4 byte header denoting the length of the calibration data (in JSON
    # format)
    page = hid_query(dev, 0)

    json_size = unpack('>I', bytes(page[:4]))[0]
    # print('JSON size: %d' % json_size)

    json_data = page[4:]
    addr = 1
    while len(json_data) < json_size:
        page = hid_query(dev, addr)
        json_data.extend(page)
        addr += 1

    json_data = json_data[:json_size]
    json_data = bytes(json_data)
    json_data = json_data.decode('utf8')

    # Pretty print
    parsed = json.loads(json_data)
    print(json.dumps(parsed, indent=4))
    if save_flag:
        with open(json_name, 'w') as outfile:
            outfile.write(json.dumps(parsed, indent=4))
    return Calibration(parsed)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('sponsorships', '0003_sponsorship_event'),
    ]

    operations = [
        migrations.CreateModel(
            name='SponsorshipLevel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=250)),
                ('description', models.TextField(blank=True)),
                ('amount', models.DecimalField(max_digits=10, decimal_places=2)),
                ('event', models.ForeignKey(related_name='sponsorship_levels', to='events.Event')),
            ],
            options={
                'verbose_name': 'Sponsorship Level',
                'verbose_name_plural': 'Sponsorship Levels',
            },
        ),
        migrations.AddField(
            model_name='sponsorship',
            name='level',
            field=models.ForeignKey(related_name='sponsorships', blank=True, to='sponsorships.SponsorshipLevel', null=True),
        ),
    ]


from __future__ import print_function

import logging
import sys

from argh import *
from vcloudtools.api import VCloudAPIClient

log = logging.getLogger(__name__)
parser = ArghParser()

@arg('path', help='Path to fetch', default='/')
def browse(args):
    """
    Browse the vCloud API using the built-in hypermedia links
    """
    c = VCloudAPIClient()
    res = c.browse(args.path)

    print('HTTP/1.1 {0} {1}'.format(res.status_code, res.reason))

    for k, v in res.headers.items():
        print("{0}: {1}".format(k, v))

    print()
    print(res.content)

def main():
    dispatch_command(browse)

if __name__ == '__main__':
    main()


import json

with open ("city.json") as file:
	data = json.load(file)

list_data = []
for i in data:
	#print (i['name'])
	list_data.append({"id":i['id'], "text":i["name"]})

data = {"results":list_data}
with open("city_name.json", "w") as f:
	json.dump(list_data, f)


from django.shortcuts import render, redirect, reverse
from django.contrib.auth import logout
from django.contrib.auth.views import LoginView, LogoutView, login_required

@login_required(login_url='accounts:login')
def logoutview(request):
    logout(request)
    return redirect('accounts:login')

@login_required(login_url='accounts:login')
def profileview(request):
    context = {}
    return render(request, 'accounts/profile.html', context)

class Login(LoginView):
    template_name = 'accounts/login.html'
    next_page = 'accounts:profile'
    redirect_authenticated_user = True


import h5py
import json
import numpy as np
from os.path import splitext, basename, join as pjoin
from pipeline_utils import print_and_call
from pipeline_config import MAPPING_PATH
from graphslam_config import GRAPHSLAM_EVAL_DIR, GRAPHSLAM_MAPS_DIR, MATCH_JSON_DATA
from sklearn.neighbors import NearestNeighbors
import matplotlib.pyplot as plt

'''
Evaluate alignment between maps
First compute bounds of map features to compare
Then compute score
'''

# TODO Parallelize

if __name__ == '__main__':
    # First compute bounding box / center data
    bounds_file_pairs = list()
    for match in MATCH_JSON_DATA:
        fstem1 = '--'.join(match['rss1'])
        fstem2 = '--'.join(match['rss2'])

        map_data1 = pjoin(GRAPHSLAM_MAPS_DIR, fstem1 + '.h5')
        map_data2 = pjoin(GRAPHSLAM_MAPS_DIR, fstem2 + '.h5')
        pcd1 = splitext(map_data1)[0] + '.pcd'
        pcd2 = splitext(map_data2)[0] + '.pcd'

        # First convert to pcd format
        cmd = '%s/bin/h5_to_pcd --h5 %s --pcd %s' % (MAPPING_PATH, map_data1, pcd1)
        print_and_call(cmd)
        cmd = '%s/bin/h5_to_pcd --h5 %s --pcd %s' % (MAPPING_PATH, map_data2, pcd2)
        print_and_call(cmd)

        # Then compute the bounding boxes
        bounds1 = '%s/%s.h5' % (GRAPHSLAM_EVAL_DIR, splitext(basename(pcd1))[0])
        bounds2 = '%s/%s.h5' % (GRAPHSLAM_EVAL_DIR, splitext(basename(pcd2))[0])
        cmd = '%s/bin/compute_bounds %s %s' % (MAPPING_PATH, pcd1, bounds1)
        print_and_call(cmd)
        cmd = '%s/bin/compute_bounds %s %s' % (MAPPING_PATH, pcd2, bounds2)
        print_and_call(cmd)

        bounds_file_pairs.append((bounds1, bounds2))

    # Now compute match quality
    eval_json = dict()
    eval_json['match_eval'] = list()
    for (file_pair, match_data) in zip(bounds_file_pairs, MATCH_JSON_DATA):
        h5f = h5py.File(file_pair[0], 'r')
        centers1 = h5f['cluster_centers'][...]
        h5f.close()
        h5f = h5py.File(file_pair[1], 'r')
        centers2 = h5f['cluster_centers'][...]
        h5f.close()

        # Compute nearest neighbor distances

        nbrs = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(centers1)
        distances, tgt_indices = nbrs.kneighbors(centers2)
        distances = distances.ravel()
        distances = distances[distances < 2.0]  # PARAM

        # Also compute lateral distances when not taking z coord into account

        centers1_lat = np.array(centers1)
        centers2_lat = np.array(centers2)
        centers1_lat[:, 2] = 0.0
        centers2_lat[:, 2] = 0.0
        nbrs_lat = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(centers1_lat)
        distances_lat, tgt_indices_lat = nbrs_lat.kneighbors(centers2_lat)
        distances_lat = distances_lat.ravel()
        distances_lat = distances_lat[distances_lat < 2.0]  # PARAM

        # Compute aggregate statistics

        mean_dist = np.mean(distances)
        median_dist = np.median(distances)

        mean_dist_lat = np.mean(distances_lat)
        median_dist_lat = np.median(distances_lat)

        # Store

        match_eval = dict()
        match_eval['match_data'] = match_data
        match_eval['match_distances'] = {'mean_dist': mean_dist, 'distances': distances.tolist(), 'median_dist': median_dist}
        match_eval['match_distances_lat'] = {'mean_dist': mean_dist_lat, 'distances': distances_lat.tolist(), 'median_dist': median_dist_lat}
        eval_json['match_eval'].append(match_eval)

        # Save evaluation summary

        eval_json_file = '%s/%s.json' % (GRAPHSLAM_EVAL_DIR, '+'.join((fstem1, fstem2)))
        json.dump(eval_json, open(eval_json_file, 'w'), indent=4, sort_keys=True)

        # Save figures

        plt.hist(distances.tolist(), 50)
        plt.ylabel('count')
        plt.xlabel('distance')
        fig_file = '%s/%s_hist.pdf' % (GRAPHSLAM_EVAL_DIR, '+'.join((fstem1, fstem2)))
        plt.savefig(fig_file)

        plt.hist(distances_lat.tolist(), 50)
        plt.ylabel('count')
        plt.xlabel('lateral distance')
        fig_file = '%s/%s_hist_lat.pdf' % (GRAPHSLAM_EVAL_DIR, '+'.join((fstem1, fstem2)))
        plt.savefig(fig_file)


import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)

def marginal_distribution(mu, sigma2, indeces):
    mu_U = mu[indeces]
    sigma2_U = sigma2[indeces][:,indeces].reshape(-1,len(indeces))
    return mu_U, sigma2_U

def conditional_distribution(X, mu, sigma2, indeces):
    mu_U, sigma2_U = marginal_distribution(mu, sigma2, indeces)
    indeces_V = list(set(range(mu.shape[0])).difference(set(indeces)))
    mu_V, sigma2_V = marginal_distribution(mu, sigma2, indeces_V)
    sigma2_U_V = sigma2[indeces][:,indeces_V]
    sigma2_V_U = sigma2_U_V.T
    U = X[indeces]
    mu_V_U = mu_V + np.dot(np.dot(sigma2_V_U, np.linalg.pinv(sigma2_U)), U-mu_U)
    sigma2_V_U = sigma2_V - np.dot(np.dot(sigma2_V_U,np.linalg.pinv(sigma2_U)), sigma2_U_V)
    return mu_V_U, sigma2_V_U

def display_prior_Gaussian_Process(mu, sigma, lim):
    np.random.seed(0)
    xmin, xmax = lim
    X = np.arange(xmin, xmax,0.1)
    cov = np.array([[np.exp(-(X[i] - X[j])*(X[i] - X[j])/(2*sigma*sigma))  for i in range(X.shape[0])] for j in range(X.shape[0])])
    Y = np.random.multivariate_normal(np.array([mu]*X.shape[0]), cov, 3)
    plt.figure()
    plt.plot(X, Y.T)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()

def display_posterior_Gaissian_Process(X_post, Y_post, X_pred, sigma):
    np.random.seed(0)
    xmin, xmax = min(X_pred), max(X_pred)
    X = np.r_[X_post, X_pred]
    Y = np.r_[Y_post, np.zeros(X_pred.shape[0])]
    mu = np.zeros(X.shape[0])
    cov = np.array([[np.exp(-(X[i] - X[j])*(X[i] - X[j])/(2*sigma*sigma))  for i in range(X.shape[0])] for j in range(X.shape[0])])
    mu_pred, sigma2_pred = conditional_distribution(Y, mu, cov, list(range(X_post.shape[0])))

    line = plt.plot(X_pred, mu_pred)
    plt.setp(line, linewidth = 3.0)
    for i in range(5):
        Y_pred = np.random.multivariate_normal(mu_pred, sigma2_pred)
        line = plt.plot(X_pred, Y_pred)
        plt.setp(line, linewidth = 1.0)
    plt.scatter(X_post, Y_post, marker='x', zorder=100, color = 'r')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    return

sigma_list = [0.3, 0.5, 1.0]

#(a)
for sigma in sigma_list:
    display_prior_Gaussian_Process(0, sigma, (-5,5))

#(c)
X_S = np.array([-1, 2.4, -2.5, -3.3, 0.3])
Y_S = np.array([2, 5.2, -1.5, -0.8, 0.3])
xmin, xmax, step = -4, 3, 0.05
for sigma in sigma_list:
    display_posterior_Gaissian_Process(X_S, Y_S, np.arange(xmin, xmax, step), sigma)


import functools

print("******* Recursive and Memoization *******")

@functools.lru_cache(maxsize=None)
def grid_traveller(m,n):
    if (m == 1 and n == 1):
        return 1
    elif (m == 0 or n==0 ):
        return 0
    else:
        return (grid_traveller(m-1,n)+grid_traveller(m,n-1))

print(grid_traveller(1,1))   # 1
print(grid_traveller(2,3))   # 3
print(grid_traveller(3,2))   # 3
print(grid_traveller(3,3))   # 6
print(grid_traveller(18,18)) # 2333606220

# tabulation

print("******* Tabulation *******")

def grid_traveller2(m,n):
    table = []
    for i in range(m+1):
        table.append([0 for i in range(n+1)])
    table[1][1] = 1
    for i in range(m+1):
        for x in range(n+1):
            current = table[i][x]
            if x+1 <= n:
                table[i][x+1] += current
            if i+1 <=m:
                table[i+1][x] += current
    return table[m][n]

print(grid_traveller2(1,1))   # 1
print(grid_traveller2(2,3))   # 3
print(grid_traveller2(3,2))   # 3
print(grid_traveller2(3,3))   # 6
print(grid_traveller2(18,18)) # 2333606220


import time
import os, json
import wiotp.sdk.application

client = None

def commandCallback(event):
    if event.eventId == "doorStatus":
        # Received event 'doorStatus'
        payload = json.loads(event.payload)
        # Get the status and time
        status = payload['status']
        time = payload['time']
        print("Status: " + status)
        print("Time: " + time)

def main():
    try:
        # Try and connect the client to the IBM Server
        options = wiotp.sdk.application.parseConfigFile("application.yaml")
        client = wiotp.sdk.application.ApplicationClient(config=options)
        client.connect()
        while True:
            # Continually subscribe to the event and call the callback function
            client.deviceEventCallback = commandCallback
            client.subscribeToDeviceEvents(eventId="doorStatus")
            time.sleep(0.1)
    except Exception as e:
        print(e)

if __name__ == "__main__":
    main()


import pathlib
import pygubu
PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = PROJECT_PATH / "snakegame.ui"

import tkinter as tk
from tkinter import *
from PIL import ImageTk, Image
import random, os
import numpy as np

from operator import itemgetter
import pickle

# - GAMEPLAN DATA SETUP
GAMEPLAN_SIZE     = 40     # Set the number of positions (boxes) that the snake can move (Horizontal and vertical)
GAMEBOX_SIZE      = 20     # Set the size, in pixels, for the width of the box
GAME_PADDING      = 10     # Set the padding on each side of the board
GAME_SPEED        = 150    # Set the default speed for the snake. Lower number is faster
SNAKE_LENGTH_ADD  = 3      # The increase in length each time the snake catch the cake

class SnakegameApp:

    direction = [0,-1]
    position  = [0,0]
    candypos  = [0,0]
    gamedata = {
        'step'          : 0,
        'score'         : 0,
        'iteration'     : 0,
        'speed'         : GAME_SPEED,
        'delay'         : 0,
        'length'        : 5,
        'generation'    : 0,
    }

    snake_list = []
    gamematrix = np.zeros([GAMEPLAN_SIZE, GAMEPLAN_SIZE])

    def __init__(self, game_engine_hook, running_ai=False):

        self.gameplan_size    = GAMEPLAN_SIZE
        self.gamebox_size     = GAMEBOX_SIZE
        self.game_padding     = GAME_PADDING
        self.gamestatus       = 'FIRST TIME'
        self.running_ai       = running_ai
        self.game_engine_hook = game_engine_hook

        # -----------------------------------------------------------------------------------------
        # - PyGubu Builder Magic - Setup the static layout
        # -----------------------------------------------------------------------------------------

        self.builder = builder = pygubu.Builder()
        builder.add_resource_path(PROJECT_PATH)
        builder.add_from_file(PROJECT_UI)
        # Main widget
        self.mainwindow = builder.get_object("toplevel1", None)
        self.canvas     = builder.get_object("canvas", None)
        self.info       = builder.get_object("info", None)
        self.highscore  = builder.get_object("highscore", None)

        self.score_variable = None
        self.info_variable = None
        self.highscore_variable = None
        self.scale_variable = None
        self.status_variable = None
        self.restart_variable = None
        builder.import_variables(self,
                                 ['score_variable',
                                  'info_variable',
                                  'highscore_variable',
                                  'scale_variable',
                                  'status_variable',
                                  'restart_variable'])

        builder.connect_callbacks(self)

        # Complete the gameplan in the canvas object --------------------------------------------

        for pos in range(0, self.gameplan_size+1, 1):
            xl = self.game_padding + pos*self.gamebox_size
            t  = self.gameplan_size*self.gamebox_size+self.game_padding

            self.canvas.create_line(xl, self.game_padding, xl, t)
            self.canvas.create_line(self.game_padding, xl, t, xl)

        # - Get the snake head and body image from file (19x19), and cake image
        self.img_snake_body = ImageTk.PhotoImage(Image.open("snake_body.bmp"))
        self.img_snake_head = ImageTk.PhotoImage(Image.open("snake_head_up.bmp"))
        self.img_cake       = ImageTk.PhotoImage(Image.open("cake-19x19.bmp"))

        # - Bind some command buttons for shortcuts
        self.mainwindow.bind("<space>", self.spacebar_command)

        if running_ai == False:
            # - Bind the arrow keys to the update move function
            self.mainwindow.bind("<Left>"  , lambda value : self.snake_update_move( -1,  0))
            self.mainwindow.bind("<Right>" , lambda value : self.snake_update_move( +1,  0))
            self.mainwindow.bind("<Up>"    , lambda value : self.snake_update_move(  0, -1))
            self.mainwindow.bind("<Down>"  , lambda value : self.snake_update_move(  0, +1))

    # - Run the mainloop

    def run(self):
        self.mainwindow.mainloop()

    def start_new(self):

        # set the first position for the snake
        self.position[0] = random.randint(12, self.gameplan_size-12)   # '12' is just to set it not too close to edge
        self.position[1] = random.randint(12, self.gameplan_size-12)

        self.gamematrix[self.position[0], self.position[1]] = 1       # Upself.date the gamematrix, '1' means position is 'snake_head'

        self.snake = self.canvas.create_image(
            self.position[0]*self.gamebox_size+self.game_padding+10,     # '10' is the image offset
            self.position[1]*self.gamebox_size+self.game_padding+10,
            image=self.img_snake_head,
            tags=('clean','snake'))

        # Set the first position for the cake, avoid putting it on-top of snake
        while True:
            self.candypos[0] = random.randint(5, self.gamebox_size-5)    # '5' is just to keep it away from edge
            self.candypos[1] = random.randint(5, self.gamebox_size-5)
            if not(self.candypos[0] == self.position[0] and self.candypos[1] == self.position[1]):
                break
        self.gamematrix[self.candypos[0], self.candypos[1]] = 3    # '3' indicates 'cake'

        self.candy = self.canvas.create_image(
            self.candypos[0]*self.gamebox_size+self.game_padding+10,
            self.candypos[1]*self.gamebox_size+self.game_padding+10,
            image=self.img_cake,
            tags=('clean', 'cake'))

    # --------------------------------------------------------------------------------------------
    # snake_update_move: depending on gamestatus, change the direction parameter
    # --------------------------------------------------------------------------------------------
    def snake_update_move(self, x, y):
        if (self.direction[0] != -x) and (self.direction[1] != -y):
            self.direction[0], self.direction[1] = x, y

    def check_collision(self, x, y):
        # Check wall crash
        if ((x < 0 or x>self.gameplan_size-1) or (y < 0 or y>self.gameplan_size-1)):
            return 'CRASH_WALL'

        # Check if we crashed with snake body
        if self.gamematrix[x,y] == 2:
            return 'CRASH_SNAKE'

        # Check if we have done to many iterations since last cake was found
        if (len(self.snake_list) > 2) and (self.gamedata['iteration'] > 100*len(self.snake_list)):
            return 'CRASH_ITERATION'

        return 'NO_COLLISION'

    def check_candy_found(self, x, y):
        if self.candypos == [x,y]:
            return True

        return False

    # --------------------------------------------------------------------------------------------
    # move: Move the snake, and update status information
    # --------------------------------------------------------------------------------------------
    def move(self):

        # Save the old position, and update position with the new direction
        prevpos = [0,0]
        prevpos[0] = self.position[0]
        prevpos[1] = self.position[1]

        self.position[0] += self.direction[0]
        self.position[1] += self.direction[1]

        # Check if we hit the wall or the body
        is_collision = self.check_collision(self.position[0], self.position[1])

        if is_collision != 'NO_COLLISION':
            self.gamestatus = is_collision

            if is_collision == 'CRASH_WALL' :
                self.info_variable.set("GAME OVER!\nYou hit the wall!\nPress 'Start Game' to go again.")
            elif is_collision == 'CRASH_SNAKE':
                self.info_variable.set("GAME OVER!\nYou ran into yourself!\nPress 'Start Game' to go again.")
            else:
                self.info_variable.set("GAME OVER!\nYou are stuck!\nPress 'Start Game' to go again.")
            self.info.config(bg='red')

            return

        # Check if we caught the candy
        if self.check_candy_found(self.position[0], self.position[1]) == True:
            self.gamedata['score'] += 1
            self.score_variable.set(f"{self.gamedata['score']:03d}")
            self.gamestatus = 'CAKE_FOUND'
            self.gamedata['iteration'] = 0
            # - place the cake again, be sure that is not set in an occupied box
            while True:
                self.candypos[0] = random.randint(5, self.gameplan_size-5)
                self.candypos[1] = random.randint(5, self.gameplan_size-5)
                if self.gamematrix[self.candypos[0], self.candypos[1]] == 0:
                    break
                else:  # For debugging, TODO
                    print("CANNOT FIND CAKE POSITION")

            self.gamematrix[self.candypos[0], self.candypos[1]] = 3
            self.canvas.moveto(
                self.candy,
                self.candypos[0]*self.gamebox_size+self.game_padding+1,
                self.candypos[1]*self.gamebox_size+self.game_padding+1
            )
            self.gamedata['length'] += SNAKE_LENGTH_ADD

        # Update new position in gamematrix
        self.gamematrix[prevpos[0], prevpos[1]] = 0    # Clear old position. (Actually not needed)
        self.gamematrix[self.position[0], self.position[1]] = 1

        # Move the image_head of the snake to it's new position
        self.canvas.move(self.snake,
            self.direction[0]*self.gamebox_size,
            self.direction[1]*self.gamebox_size
        )

        # Move each image section of the snake body to it's new positions
        if len(self.snake_list) < self.gamedata['length']:    # Need to create new body segments
            body = self.canvas.create_image(
                prevpos[0]*self.gamebox_size + self.game_padding + 10,
                prevpos[1]*self.gamebox_size + self.game_padding + 10,
                image=self.img_snake_body,
                tags=('clean', 'body')
            )
            self.snake_list.insert(0,[body, prevpos[0], prevpos[1]])
            self.gamematrix[prevpos[0], prevpos[1]] = 2
        else:
            item = self.snake_list.pop()
            self.gamematrix[item[1], item[2]]=0    # Clear old positon in matrix
            item[1], item[2] = prevpos[0], prevpos[1]
            self.snake_list.insert(0, item)
            self.canvas.moveto( item[0],
                                item[1]*self.gamebox_size+self.game_padding,
                                item[2]*self.gamebox_size+self.game_padding)
            self.gamematrix[prevpos[0], prevpos[1]]=2

        # Update the step counter (Need to present it in the dashboard later ...)
        self.gamedata['step'] += 1
        self.gamedata['iteration'] += 1

        self.status_variable.set(
            f"Status:\n\nstep: {self.gamedata['step']}\n" +\
            f"iteration: {self.gamedata['iteration']}\n" +\
            f"Generation: {self.gamedata['generation']}\n")

    # --------------------------------------------------------------------------------------------

    def game_engine(self):
        if self.gamestatus == 'GAMEOVER':
            return

        self.game_engine_hook()

        # self.move()

        self.mainwindow.after(int(self.gamedata['delay']),self.game_engine)
        # self.mainwindow.after(300,self.game_engine)
    # ---------------------------------------------------------------------------------------------

    def spacebar_command(self, event):
        self.restart_command()

    def setspeed_command(self, scale_value):
        pass

    def restart_command(self, dont_restart_engine=False):

        # -- Clean up previous session
        # ----- Delete all objects
        self.canvas.delete('clean')
        self.gamematrix.fill(0)
        self.gamedata['step']   = 0
        self.gamedata['score']  = 0
        self.gamedata['speed']  = self.scale_variable.get()
        self.gamedata['delay']  = (490-40*self.scale_variable.get())/3

        #print(f"scale: {self.scale_variable.get()} speed: {self.gamedata['speed']}")

        self.gamedata['length'] = 5
        self.snake_list = []

        self.info_variable.set("\n      Catch the Cake ....")
        self.info.config(bg="green")

        self.score_variable.set(f"{self.gamedata['score']:03d}")

        # -- Start up   game session
        self.gamestatus = 'RUNNING'
        self.start_new()
        if dont_restart_engine == False:
            self.game_engine()

if __name__ == "__main__":
    app = SnakegameApp(GAMEPLAN_SIZE, GAMEBOX_SIZE, GAME_PADDING)
    app.run()

# %%


from uuid import uuid4

import pytest

from pydent.marshaller.base import add_schema
from pydent.marshaller.base import ModelRegistry
from pydent.marshaller.fields import Alias
from pydent.marshaller.fields import Callback
from pydent.marshaller.fields import Field
from pydent.marshaller.fields import Nested
from pydent.marshaller.fields import Relationship

class TestDump:
    def test_dump_empty_data(self, base):
        """Dump should produce an empty dictionary."""

        @add_schema
        class MyModel(base):
            pass

        model = MyModel()
        assert model.dump() == {}

    def test_dump_empty_data_with_non_tracked_attrs(self, base):
        """Expect that non-tracked attributes are excluded from the dump."""

        @add_schema
        class MyModel(base):
            pass

        model = MyModel()
        model.id = 4
        assert model.dump() == {}

    def test_dump_loaded_data(self, base):
        """Manually set data should appear in the dump."""

        @add_schema
        class MyModel(base):
            pass

        model = MyModel._set_data({"id": 5, "name": "MyName"})
        assert model.dump() == {"id": 5, "name": "MyName"}

    def test_dump_loaded_data_and_overwrite(self, base):
        """Manually set data can be overridden by setting attributes."""

        @add_schema
        class MyModel(base):
            pass

        model = MyModel._set_data({"id": 5, "name": "MyName"})
        model.id = 6
        assert model.dump() == {"id": 6, "name": "MyName"}

    def test_dump_empty_field(self, base):
        """Empty fields should return an empty dictionary."""

        @add_schema
        class MyModel(base):
            fields = dict(field=Field())

        model = MyModel()
        assert model.dump() == {}

    def test_dump_field(self, base):
        @add_schema
        class MyModel(base):
            fields = dict(field=Field())

        model = MyModel._set_data({"name": "NAME"})
        assert model.dump() == {"name": "NAME"}

    def test_dump_with_new_data_key(self, base):
        @add_schema
        class MyModel(base):
            fields = {
                "field": Field(),
                "source": Callback(
                    lambda s: getattr(s, "field"),
                    callback_args=(Callback.SELF,),
                    always_dump=True,
                    data_key="field",
                ),
            }

        model = MyModel({"field": 5})
        assert model.field == model.source
        print(model._get_data())
        assert model.dump() == {"field": 5}
        model.source = 6
        assert model.field == model.source
        assert model.dump() == {"field": 6}
        model.field = 7
        assert model.field == model.source
        assert model.dump() == {"field": 7}

        model = MyModel({"source": 5})
        assert model.field == model.source
        print(model._get_data())
        assert model.dump() == {"field": 5}
        model.source = 6
        assert model.field == model.source
        assert model.dump() == {"field": 6}
        model.field = 7
        assert model.field == model.source
        assert model.dump() == {"field": 7}
        print(model._get_data())

    def test_alias(self, base):
        """Expect that alias fields refer to exactly the attribute set in the
        alias.

        That means, the 'source' field should refer to the 'field'
        attribute.
        """

        @add_schema
        class MyModel(base):
            fields = {"field": Field(), "source": Alias("field")}

        model = MyModel({"field": 5})
        assert model.field == model.source
        assert model.dump() == {"field": 5}
        model.source = 6
        assert model.field == model.source
        assert model.dump() == {"field": 6}
        model.field = 7
        assert model.field == model.source
        assert model.dump() == {"field": 7}

        model = MyModel({"source": 5})
        assert model.field == model.source
        print(model._get_data())
        assert model.dump() == {"field": 5}
        model.source = 6
        assert model.field == model.source
        assert model.dump() == {"field": 6}
        model.field = 7
        assert model.field == model.source
        assert model.dump() == {"field": 7}

    def test_dump_marshalling_field(self, base):
        """Expect the custom HTMLTag field to be properly
        serialized/deserialized."""

        class HTMLTag(Field):
            def serialize(self, caller, val):
                return "<{tag}>{val}</{tag}>".format(tag=self.data_key, val=val)

        @add_schema
        class MyModel(base):
            fields = dict(h1=HTMLTag())

        model = MyModel._set_data({"h1": "raw"})
        assert model.h1 == "raw"

        model.h1 = "This is a Heading 1 Title"
        assert model.h1 == "This is a Heading 1 Title"

        assert model.dump() == {"h1": "
This is a Heading 1 Title
"}

    def test_always_dump(self, base):
        """Expect that fields with 'always_dump' are, by default, dumped as
        empty constructors event when they are empty."""

        @add_schema
        class MyModel(base):
            fields = dict(
                field1=Callback("find"), field2=Callback("find", always_dump=True)
            )

            def find(self):
                return 100

        m = MyModel()

        assert m.dump() == {"field2": 100}
        assert m.dump(include="field1") == {"field1": 100, "field2": 100}
        assert m.dump(ignore="field2") == {}

    def test_empty_list_field(self, base):
        """Expect."""

        @add_schema
        class ModelWithList(base):
            fields = dict(mylist=Field())

        model = ModelWithList()
        model.mylist = []
        assert model.mylist == []
        model.mylist.append(5)
        assert model.mylist == [5]

class TestNested:
    """Tests for nested serialization/deserialization."""

    @pytest.fixture(scope="function")
    def Company(self, base):
        @add_schema
        class Company(base):
            pass

        return Company

    @pytest.fixture(scope="function")
    def Publisher(self, base):
        @add_schema
        class Publisher(base):

            fields = dict(author=Nested("Author"), company=Nested("Company"))

        return Publisher

    @pytest.fixture(scope="function")
    def Author(self, base):
        @add_schema
        class Author(base):

            fields = dict(
                publisher=Nested("Publisher"), id=Field("id", allow_none=True)
            )

        return Author

    def test_simple_nested(self, Author, Publisher):
        author = Author._set_data(
            {"name": "Richard Dawkings", "publisher": {"name": "Scotts Books"}}
        )

        print(author._get_data())
        assert isinstance(author, Author)
        assert isinstance(author.publisher, Publisher)

        assert author.name == "Richard Dawkings"
        assert author.publisher.name == "Scotts Books"

    def test_double_nested(self, Author, Publisher, Company):
        author = Author._set_data(
            {
                "name": "Samuel",
                "publisher": {"name": "Archive 81", "company": {"name": "Damage Inc."}},
            }
        )

        print(author._get_data())
        assert isinstance(author, Author)
        assert isinstance(author.publisher, Publisher)
        assert isinstance(author.publisher.company, Company)

    @pytest.fixture(scope="function")
    def author_example_data(self):
        data = {
            "name": "Samuel",
            "publisher": {"name": "Archive 81", "company": {"name": "Damage Inc."}},
        }
        return data

    @pytest.fixture(scope="function")
    def author_example(self, author_example_data, Author, Publisher, Company):
        author = Author._set_data(author_example_data)
        return author

    def test_shared_data(self, author_example, author_example_data):

        author = author_example
        company = author.publisher.company

        print(id(author_example_data["publisher"]))
        assert author_example_data["publisher"] is author._get_data()["publisher"]
        print(id(author._get_data()["publisher"]))
        publisher = author.publisher
        print(id(publisher._get_data()))
        assert author._get_data()["publisher"] is publisher._get_data()

    def test_double_nested_dump(self, author_example, author_example_data):
        assert author_example._get_data() == author_example_data
        assert author_example.publisher._get_data() == author_example_data["publisher"]
        assert (
            author_example.publisher.company._get_data()
            == author_example_data["publisher"]["company"]
        )

    def test_del_nested(self, author_example, author_example_data):

        author_example.name = "TIM"
        assert author_example.name == "TIM"

        author_example.publisher.name = "Holland"
        assert author_example.publisher.name == "Holland"

        author_example.publisher.company.name = "ABC"
        assert author_example.publisher.company.name == "ABC"
        del author_example.publisher.company

        with pytest.raises(AttributeError):
            author_example.publisher.company

        assert "company" not in author_example._get_data()["publisher"]
        assert "company" not in author_example.publisher._get_data()

    def test_set_none_on_nested(self, author_example):
        author_example.publisher = None
        assert author_example.publisher is None
        assert author_example._get_data()["publisher"] is None

    def test_set_nested_attribute(self, author_example, Publisher):
        author_example.publisher = None
        assert author_example.publisher is None
        assert author_example._get_data()["publisher"] is None
        publisher = Publisher._set_data({"name": "P"})
        author_example.publisher = publisher

        assert author_example.publisher.name == "P"
        assert author_example._get_data()["publisher"] is publisher._get_data()

    def test_nested_dump(self, author_example, author_example_data):

        new_company_name = str(uuid4())

        expected_data = dict(author_example_data)
        expected_data["publisher"]["company"]["name"] = new_company_name

        author_example.publisher.company.name = new_company_name

        expected_data_copy = dict(expected_data)
        expected_data_copy.pop("publisher")
        assert expected_data_copy == author_example.dump()

        expected_data_copy = dict(expected_data["publisher"])
        expected_data_copy.pop("company")
        assert expected_data_copy == author_example.publisher.dump()

        assert (
            expected_data["publisher"]["company"]
            == author_example.publisher.company.dump()
        )

    def test_load_a_model(self, base, author_example):
        @add_schema
        class AuthorList(base):
            fields = dict(author=Nested("Author"))

        author_list = AuthorList()
        author_example.publisher.company.name = "Umbrella Corp"
        author_list.author = author_example
        assert author_list.author.publisher.company.name == "Umbrella Corp"

        author_example.publisher.company.name = "LexCorp"
        assert author_list.author.publisher.company.name == "LexCorp"

class TestRelationship:
    @pytest.fixture(scope="function")
    def Company(self, base):
        @add_schema
        class Company(base):
            pass

        return Company

    @pytest.fixture(scope="function")
    def Publisher(self, base):
        @add_schema
        class Publisher(base):
            fields = dict(
                company=Relationship(
                    "Company", "instantiate_model", 6, {"name": "MyCompany"}
                )
            )

            def instantiate_model(self, model_name, model_id, name="Default"):
                return ModelRegistry.get_model(model_name)._set_data(
                    {"id": model_id, "name": name}
                )

        return Publisher

    @pytest.fixture(scope="function")
    def Author(self, base):
        @add_schema
        class Author(base):
            fields = dict(
                publisher=Relationship(
                    "Publisher", "instantiate_model", 4, {"name": "MyPublisher"}
                )
            )

            def instantiate_model(self, model_name, model_id, name="Default"):
                return ModelRegistry.get_model(model_name)._set_data(
                    {"id": model_id, "name": name}
                )

        return Author

    @pytest.mark.parametrize(
        "model,include,expected",
        [
            ("Company", None, {}),
            ("Publisher", None, {}),
            ("Author", None, {}),
            pytest.param(
                "Publisher",
                "company",
                {"company": {"id": 6, "name": "MyCompany"}},
                id="include 1 layer nested",
            ),
            pytest.param(
                "Author",
                "publisher",
                {"publisher": {"id": 4, "name": "MyPublisher"}},
                id="include 1 layer nested",
            ),
            pytest.param(
                "Author",
                {"publisher": "company"},
                {
                    "publisher": {
                        "id": 4,
                        "name": "MyPublisher",
                        "company": {"id": 6, "name": "MyCompany"},
                    }
                },
                id="include 2 layer nested",
            ),
        ],
    )
    def test_nested_dump_with_include(
        self, base, Author, Publisher, Company, model, include, expected
    ):
        instance = ModelRegistry.get_model(model)()
        assert instance.dump(include=include) == expected

    @pytest.mark.parametrize(
        "model,only,expected",
        [
            pytest.param(
                "Author", "publisher", {"publisher": {"name": "MyPublisher", "id": 4}}
            ),
            pytest.param(
                "Author", {"publisher": "name"}, {"publisher": {"name": "MyPublisher"}}
            ),
            pytest.param("Author", {"publisher": "id"}, {"publisher": {"id": 4}}),
            pytest.param(
                "Author",
                {"publisher": "company"},
                {"publisher": {"company": {"name": "MyCompany", "id": 6}}},
            ),
            pytest.param(
                "Author",
                {"publisher": {"company": "id"}},
                {"publisher": {"company": {"id": 6}}},
            ),
        ],
    )
    def test_relationship_dump_with_only(
        self, base, Author, Publisher, Company, model, only, expected
    ):
        instance = ModelRegistry.get_model(model)()
        assert instance.dump(only=only) == expected

    def test_relationship_dump_ignore(self, base, Author):
        instance = Author._set_data({"name": "MyName", "id": 5})
        assert instance.dump() == {"name": "MyName", "id": 5}
        assert instance.dump(ignore="name") == {"id": 5}
        assert instance.dump(ignore=["name", "id"]) == {}

    def test_basic_relationship(self, base):
        @add_schema
        class Publisher(base):
            pass

        @add_schema
        class Author(base):

            fields = dict(
                publisher=Relationship(
                    "Publisher", "instantiate_model", 4, {"name": "MyPublisher"}
                ),
                cache=True,
            )

            def instantiate_model(self, model_name, model_id, name="Default"):
                return ModelRegistry.get_model(model_name)._set_data(
                    {"id": model_id, "name": name}
                )

        author = Author()
        assert author.dump() == {}
        assert isinstance(
            author.publisher, Publisher
        ), "publisher attribute should be a Publisher type"
        assert (
            author.publisher._get_data() is author._get_data()["publisher"]
        ), "data should be shared between the Author and Publisher"

        assert author._get_data() == {"publisher": {"id": 4, "name": "MyPublisher"}}

        assert author.dump() == {}
        assert author.dump(include=["publisher"]) == author._get_data()

    def test_many_relationship(self, base):
        @add_schema
        class Publisher(base):
            pass

        @add_schema
        class Author(base):

            fields = dict(
                publisher=Relationship(
                    "Publisher",
                    "instantiate_model",
                    4,
                    {"name": "MyPublisher"},
                    many=True,
                )
            )

            def instantiate_model(self, model_name, model_id, name="Default"):
                models = []
                for i in range(3):
                    models.append(
                        ModelRegistry.get_model(model_name)._set_data(
                            {"id": model_id, "name": name}
                        )
                    )
                return models

        author = Author()
        print(author.dump())
        print(author.dump(include="publisher"))
        assert len(author.publisher) == 3
        assert len(author.dump(include="publisher")["publisher"]) == 3
        author.publisher = [
            Publisher._set_data({"id": 3}),
            Publisher._set_data({"id": 5}),
        ]

        assert len(author.publisher) == 2
        assert len(author.dump(include="publisher")["publisher"]) == 2
        assert author.publisher[0].id == 3
        assert author.publisher[1].id == 5

        author.publisher.append(Publisher())
        assert len(author.publisher) == 3
        assert len(author.dump(include="publisher")["publisher"]) == 3

    def test_load_relationship(self, base):
        @add_schema
        class Publisher(base):
            pass

        @add_schema
        class Author(base):

            fields = dict(
                publishers=Relationship(
                    "Publisher",
                    "instantiate_model",
                    4,
                    {"name": "MyPublisher"},
                    many=True,
                )
            )

            def instantiate_model(self, model_name, model_id, name="Default"):
                models = []
                for i in range(3):
                    models.append(
                        ModelRegistry.get_model(model_name)._set_data(
                            {"id": model_id, "name": name}
                        )
                    )
                return models

        publisher_data = {"name": "Torr Books"}

        author = Author._set_data(
            {"name": "Steven King", "publishers": [publisher_data]}
        )

        assert len(author.publishers) == 1
        assert isinstance(author.publishers[0], Publisher)
        assert author.publishers[0]._get_data() is publisher_data
        del author.publishers

        assert len(author.publishers) == 3
        assert isinstance(author.publishers[0], Publisher)


import errno
import linecache
import mimetypes
import os
import signal
import sys
from datetime import datetime
from functools import wraps
from urllib.parse import urlparse

import pandas as pd
import requests
from bs4 import BeautifulSoup
from validator_collection import checkers

EN_KEY_WORDS = ["debt", "statistical", "statistics", "bulletin", "monthly", "report", "strategy"]

def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wraps(func)(wrapper)

    return decorator

def is_downloadable(url):
    """
    Does the url contain a downloadable resource
    """
    try:
        file_extensions = ["pdf", "docx", "doc", "xls", "xlsx" "csv"]
        content_type_list = ["pdf", "word", "excel", "officedocument"]
        response = requests.get(url, timeout=10)
        if response.status_code != 200:
            return None
        headers = response.headers
        content_type = headers.get("Content-Type")

        for f in content_type:
            if f in content_type_list:
                return True

        filename = url.split("/")[-1]
        for e in file_extensions:
            if e in filename:
                return True

        if 'text' in content_type.lower():
            return False
        if 'html' in content_type.lower():
            return False

        return True
    except Exception:
        return False

def get_weblinks(fpath=None):
    """
    Gets website links and put them in a data frame
    :param fpath:
    :return:
    """

    df = pd.read_csv(fpath)
    df["Link"].fillna("No link yet", inplace=True)
    country_dict = {}

    for index, row in df.iterrows():
        country_code = row["Country Code"]
        country_name = row["DMF Country name"]
        url = row["Link"]
        country_dict[country_code] = {"targetUrl": url, "countryName": country_name}

    return country_dict

def get_links_from_target_sites(url=None):
    """
    Given the website, gets the links
    :param url:
    :return:
    """
    # TODO: detect webpage language and return it
    try:
        response = requests.get(url, timeout=10)
        if response.status_code != 200:
            return None
        html = response.text
        bs = BeautifulSoup(html, "html.parser")
        urls = {}
        for a in bs.find_all('a', href=True):
            urls[a['href']] = a.getText()
        return urls
    except Exception:
        return None

def retrieve_filename_and_extension(response=None, url=None):
    file_extensions = ["pdf", "docx", "doc", "xls", "xlsx" "csv"]
    content_type_list = ["pdf", "word", "excel", "officedocument"]
    try:
        filename = url.split("/")[-1]
        for e in file_extensions:
            if e in filename:
                return filename

        content_type = response.headers['content-type']
        for c in content_type_list:
            if c in content_type.lower():
                extension = mimetypes.guess_extension(content_type)
                filename = url.split("/")[-1] + extension
                return filename
    except Exception:
        return None

def download_file(url=None, outfolder=None):
    """
    Download and save file if possible
    :param url:
    :param outfolder:
    :return:
    """
    try:
        file = requests.get(url, allow_redirects=True, timeout=10)
        if file.status_code != 200:
            return None
        filename = retrieve_filename_and_extension(response=file, url=url)
        fpath = os.path.join(outfolder, filename)
        open(fpath, 'wb').write(file.content)
        return filename
    except Exception:
        return None

def download_content(content_url=None, output_folder=None, base_url=None, visit_log=None):
    """
    Given a list of links extracted from seed list of websites
    download relevant content
    :param urls: a dict object with country details and urls
    :param key_words: key words to determine what content to download
    :return:
    """
    try:
        if checkers.is_url(content_url):
            if is_downloadable(content_url):
                return download_file(url=content_url, outfolder=output_folder)
            else:
                return scrape_docs_from_links(seed_url=content_url, output_dir=output_folder,
                                              root_url=base_url, seen_links=visit_log, relevant=True)
        else:
            parsed_uri = urlparse(base_url)
            root_url = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)
            revised_link = root_url[:-1] + content_url
            return download_content(content_url=revised_link, output_folder=output_folder,
                                    base_url=revised_link, visit_log=visit_log)
    except Exception:
        exc_type, exc_obj, tb = sys.exc_info()
        f = tb.tb_frame
        lineno = tb.tb_lineno
        filename = f.f_code.co_filename
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        print('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj))

def get_relevant_links(starter_url=None, has_key_words=True):
    links = get_links_from_target_sites(url=starter_url)
    if not links:
        return None

    relevant_urls = [starter_url]
    for l, d in links.items():
        for w in EN_KEY_WORDS:
            if w in l.lower():
                relevant_urls.append(l)
                break
            if d:
                if w in d.lower():
                    relevant_urls.append(l)
                    break
        for e in ["pdf", "docx", "doc", "xls", "xlsx" "csv"]:
            if e in l:
                relevant_urls.append(l)
                break
    return relevant_urls

def scrape_docs_from_links(seed_url=None, output_dir=None, root_url=None, seen_links=None, relevant=False):
    relevant_urls = set(get_relevant_links(starter_url=seed_url, has_key_words=relevant))
    if not relevant_urls:
        return None

    files_downloaded = []
    for u in relevant_urls:
        print("========================================")
        print(u)
        print("========================================")
        try:
            if u in seen_links:
                seen_links[u] = seen_links[u] + 1
            else:
                seen_links[u] = 1
            if seen_links[u] > 2:
                continue
            res = download_content(content_url=u, output_folder=output_dir, base_url=root_url, visit_log=seen_links)
            if res:
                files_downloaded.append({"downloadedFileName": res, "downloadUrl": u})
        except Exception as e:
            exc_type, exc_obj, tb = sys.exc_info()
            f = tb.tb_frame
            lineno = tb.tb_lineno
            filename = f.f_code.co_filename
            linecache.checkcache(filename)
            line = linecache.getline(filename, lineno, f.f_globals)
            print('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj))
            pass

    return files_downloaded

def process_single_country(url=None, downloads_dir=None, country_code=None):
    """
    A helper function which calls the rest of the functions to download data
    :param downloads_dir:
    :return:
    """
    # ========================================
    # SET UP DIRECTORY TO PUT FILES
    # ========================================
    country_downloads_dir = os.path.join(downloads_dir, country_code)
    if not os.path.exists(country_downloads_dir):
        os.makedirs(country_downloads_dir)

    # =========================================
    # DOWNLOAD FILES WHERE AVAILABLE
    # =========================================
    links_visits = {url: 1}
    downloaded_files = scrape_docs_from_links(seed_url=url, output_dir=country_downloads_dir,
                                              root_url=url, seen_links=links_visits, relevant=True)
    return downloaded_files

def process_all_countries(metadata_outfile=None, country_web_links=None, downloads_dir=None, country_list=None):
    """
    Gets the download results and saves into CSV
    :param results:
    :return:
    """
    urls = get_weblinks(fpath=country_web_links)
    ts = datetime.now()
    time_format = "%m-%d-%Y %H:%M"
    ts_str = ts.strftime(time_format)

    df_data = []
    data_pt = {"dateProcessed": ts_str, "keyWords": EN_KEY_WORDS, "comment": None,
               "downloadRelevant": None, "status": None}

    for k, v in urls.items():
        if k not in country_list:
            continue
        try:
            print("Working on country : {}".format(k))
            print()
            res = process_single_country(url=v["targetUrl"], downloads_dir=downloads_dir, country_code=k)
            data_pt["countryName"] = v["countryName"]
            data_pt["countryCode"] = k
            data_pt["targetUrl"] = v["targetUrl"]
            if data_pt["targetUrl"] == "No link yet":
                data_pt["comment"] = 'Need to find MoF weblink'
                data_pt["status"] = "Not started"
                df_data.append(data_pt)

            if res:
                for item in res:
                    data_pt.update(item)
                    data_pt["status"] = "Complete"
                    df_data.append(data_pt)
            else:
                data_pt["comment"] = 'Something went wrong'
                data_pt["status"] = 'in progress'
                df_data.append(data_pt)
        except Exception as e:
            exc_type, exc_obj, tb = sys.exc_info()
            f = tb.tb_frame
            lineno = tb.tb_lineno
            filename = f.f_code.co_filename
            linecache.checkcache(filename)
            line = linecache.getline(filename, lineno, f.f_globals)
            print('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj))
            print("Failed to complete work for this country")
            pass

    df = pd.DataFrame(df_data)
    cols = ["countryName", "countryCode", "targetUrl", "downloadUrl", "downloadedFileName",
            "dateProcessed", "keyWords", "downloadRelevant", "comment", 'status']
    df = df[cols]
    df.to_csv(metadata_outfile, index=False)

def main():
	# replace the paths below with your paths
    base_dir = os.path.abspath("/Users/dmatekenya/Google-Drive/teachingAndLearning/SIAP-oct-2019/python-for-data-science/")
    downloads_folder = os.path.join(base_dir, "fileDownloads")
    weblinks_csv = os.path.join(base_dir, "data", "webLinks.csv")
    meta_outfile = os.path.join(base_dir, "fileDownloads", "processingLogs.csv")
    countries = ["ETH", "BEN", "GMB", "GHA"]
    process_all_countries(metadata_outfile=meta_outfile, country_web_links=weblinks_csv,
                          downloads_dir=downloads_folder, country_list=countries)
    print("DONE")

if __name__ == '__main__':
    main()


#Libray
import csv
import math
import matplotlib.pyplot as plt
from sklearn import tree
from sklearn.model_selection import KFold

#Variables
X = []
y = []
Y_series = [] #used to save real values and respective predictions
dtr_MADscores = []
dtr_RMSEscores = []
features = ('X','Y','month','day','FFMC','DMC','DC','ISI','temp','RH','wind','rain')
month_dict = {'jan':1,'feb':2,'mar':3,'apr':4,'may':5,'jun':6,
              'jul':7,'aug':8,'sep':9,'oct':10,'nov':11,'dec':12,}
day_dict = {'mon':1,'tue':2,'wed':3,'thu':4,'fri':5,'sat':6,'sun':7}
#modifiable
keep_col = None
kf_rounds = None
depth = None

#Retrieve user input
n = int(input("Enter # of desired features: "))
keep_col = list(map(int,input("Enter the feature columns (format: 0 1 2 ...): ").strip().split()))[:n]
kf_rounds = int(input("Enter # of 10 fold cross validation rounds: "))
depth = int(input("Enter depth of decision tree (3 is reccomended): "))

#Load data
print("\nLoading data...", end=' ')
with open("../resource/forestfires.csv", 'r') as csvfile:
  reader = csv.reader(csvfile)
  for i, row in enumerate(reader):
      if i > 0: #skipping the header
          temp = [row[0],row[1],month_dict[row[2]],day_dict[row[3]],row[4],row[5],
                  row[6],row[8],row[9],row[10],row[11]]
          X.append([float(i) for i in temp])
          #natural log transform function
          y.append(math.log(float(row[-1])+1))
print("Done")

#Update X according to selected features
X_fs = []
for instance in X:#_std:
    temp = []
    for k,value in enumerate(instance):
        if k in keep_col:
            temp.append(value)
    X_fs.append(temp)

#Train and test model with rounds of 10 fold cross validtion
print("\nPerforming 10 fold cross validation...")
for kf_round in range(kf_rounds):
    print("Round " + str(kf_round+1))
    #split data into test and train
    kf = KFold(n_splits=10, shuffle=True)
    kf.split(X_fs,y)
    for train_index, test_index in kf.split(X_fs):
        X_train = []
        y_train = []
        for index in train_index:
            X_train.append(X_fs[index])
            y_train.append(y[index])
        X_test = []
        y_test = []
        for index in test_index:
            X_test.append(X_fs[index])
            y_test.append(y[index])

        #Build models
        dtr = tree.DecisionTreeRegressor(max_depth=depth)
        dtr = dtr.fit(X_train,y_train)

        #Test models
        dtr_totalError = 0
        dtr_totalSE = 0
        for instance,target in zip(X_test,y_test):
            #reversing natural log transformation
            dtr_prediction = math.exp(dtr.predict([instance])[0])-1
            target_transform = math.exp(target)-1
            #populating series for later plotting
            Y_series.append([target_transform,dtr_prediction])
            #totaling errors
            dtr_error = target_transform - dtr_prediction
            dtr_totalError += abs(dtr_error)
            dtr_totalSE += dtr_error*dtr_error
        #saving MAD and RMSE scores
        dtr_MADscores.append(dtr_totalError/len(X_test))
        dtr_RMSEscores.append(math.sqrt(dtr_totalSE/len(X_test)))
print("Done")

#Calculte average scores
dtr_avgMAD = sum(dtr_MADscores)/len(dtr_MADscores)
dtr_avgRMSE = sum(dtr_RMSEscores)/len(dtr_RMSEscores)

#Print average peformace of models
print("\nDT w/ depth " + str(depth) +":")
print("average MAD = " + str(dtr_avgMAD))
print("average RMSE = " + str(dtr_avgRMSE))

#Sort real values and predictions by increasing order of actual values
Y_series.sort(key=lambda x:x[0])
truth_series = [i for i,j in Y_series] #actual values
dtr_series = [j for i,j in Y_series] #dtr predictions

#Plot real values and dtr predictions
plt.figure(figsize=(12,12))
plt.title(label="DT")
plt.xlabel('Ordered test set')
plt.ylabel('Burned area (in hectares)')
plt.ylim([0,20])
plt.plot(truth_series, 'bo', label='real values')
plt.plot(dtr_series, 'r+', label='predictions')
plt.legend()
plt.show()


from statistics import median_low as mdl, median_high as mdh, median as md
from copy import deepcopy as dc
num = int(input())
floors = list(map(int, input().split()))
newfloor = dc(floors)
newfloor.sort()

if len(floors)%2==0:
    medl = mdl(newfloor)
    medh = mdh(newfloor)
    midmed = md(newfloor)
    ind = min([floors.index(medl), floors.index(medh)])

    if floors.index(medl) == floors.index(medh):
        print(floors.index(midmed)+1)
    else:
        print(ind+1)
else:
    midmed = md(newfloor)
    print(floors.index(midmed)+1)


import tkinter as tk
from tkinter import ttk
import datetime as dt
import mysql.connector
from tkinter import messagebox
import configparser

class NuovoLottoCucina(tk.Toplevel):
    def __init__(self):
        super(NuovoLottoCucina, self).__init__()
        self.title("Nuovo Lotto Cucina")
        self.geometry("+0+0")

        self.data = dt.date.today()
        self.config = self.leggi_file_ini()

        self.conn = mysql.connector.connect(host=self.config['DataBase']['host'],
                                            database=self.config['DataBase']['db'],
                                            user=self.config['DataBase']['user'],
                                            password='')
        self.c = self.conn.cursor()

        self.lista_da_salvare = []
        self.lista_nuova_produzione = []
        self.nuova_produzione = tk.StringVar()
        self.prog_lotto_ven = self.data.strftime('%d%m%y')
        self.img_btn1 = tk.PhotoImage(file=".//immagini//logo_piccolo.gif")
        self.value = tk.StringVar()
        self.value_peso = tk.StringVar()

        # DISPOSIZIONE FRAME
        self.frame_alto = tk.Frame(self, bd='3', relief='groove')
        self.frame_centro = tk.Frame(self, height=450, width=self.winfo_screenwidth(),
                                     bd='3', relief='groove')
        self.frame_basso = tk.Frame(self, bd='3', background='white', relief='groove')

        # LABEL nuovo lotto vendita
        self.lbl_nuovo_lotto = tk.Label(self.frame_alto, text='NUOVO LOTTO VENDITA', font=('Helvetica', 20),
                                        foreground='blue', relief='ridge', padx=20)
        self.lbl_prog_lotto_vendita = tk.Label(self.frame_alto, text=str(self.prog_lotto_ven),
                                               font=('Helvetica', 20), bg='white', relief='sunken', padx=20)

        # LABEL che mostra il numero della settimana
        self.lbl_settimana = tk.Label(self.frame_alto, text='SETTIMANA NUMERO ',
                                      foreground='blue', font=('Verdana', 20), relief='ridge', padx=20)
        self.lbl_nr_settimana = tk.Label(self.frame_alto, text=str(1 + int(self.data.strftime('%W'))),
                                         font=('Verdana', 20), bg='white', relief='sunken', padx=20)

        # TREEVIEW per riepilogo immissioni
        self.tree = ttk.Treeview(self.frame_centro, height=15)
        self.tree['columns'] = ('prog_v', 'prodotto', 'peso', 'settimana')

        self.tree['displaycolumns'] = ('prodotto', 'peso')
        self.tree['show'] = 'headings'

        self.tree.column("prodotto", width=180)
        self.tree.column("peso", width=80)

        self.tree.heading("prodotto", text="prodotto")
        self.tree.heading("peso", text="peso")

        self.tree.tag_configure('odd', background='light green')

        # NOTEBOOK e posizione
        self.notebook = ttk.Notebook(self.frame_centro)

        # TAB 1 per PRIMI PIATTI
        self.tab1 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab1, text='Primi', compound='left', image=self.img_btn1)

        self.lista_primi = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'Primi piatti'")

        for row in self.c:
            self.lista_primi.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_primi)):
            if row % 10 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab1,
                           text=str(self.lista_primi[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_primi[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 2 per PRIMI pesce
        self.tab2 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab2, text='Primi Pesce', compound='left', image=self.img_btn1)

        self.lista_primi_pesce = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'Primi piatti di pesce'")

        for row in self.c:
            self.lista_primi_pesce.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_primi_pesce)):
            if row % 10 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab2,
                           text=str(self.lista_primi_pesce[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_primi_pesce[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 3 per SECONDI
        self.tab3 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab3, text='Secondi', compound='left', image=self.img_btn1)

        self.lista_secondi = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'secondi piatti'")

        for row in self.c:
            self.lista_secondi.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_secondi)):
            if row % 13 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab3,
                           text=str(self.lista_secondi[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_secondi[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 4 per SECONDI pesce
        self.tab4 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab4, text='Secondi Pesce', compound='left', image=self.img_btn1)

        self.lista_secondi_pesce = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = '5'")

        for row in self.c:
            self.lista_secondi_pesce.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_secondi_pesce)):
            if row % 13 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab4,
                           text=str(self.lista_secondi_pesce[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_secondi_pesce[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 5 per CONTORNI
        self.tab5 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab5, text='Contorni', compound='left', image=self.img_btn1)

        self.lista_contorni = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'contorni'")

        for row in self.c:
            self.lista_contorni.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_contorni)):
            if row % 10 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab5,
                           text=str(self.lista_contorni[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_contorni[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 6 per DOLCI
        self.tab6 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab6, text='Dolci', compound='left', image=self.img_btn1)

        self.lista_dolci = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'dolci'")

        for row in self.c:
            self.lista_dolci.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_dolci)):
            if row % 10 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab6,
                           text=str(self.lista_dolci[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_dolci[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # TAB 7 per PIATTI freddi
        self.tab7 = ttk.Frame(self.notebook)
        self.notebook.add(self.tab7, text='Piatti freddi', compound='left', image=self.img_btn1)

        self.lista_piatti_freddi = []
        self.c.execute("SELECT prodotto FROM prodotti WHERE merceologia = 'piatti freddi'")

        for row in self.c:
            self.lista_piatti_freddi.extend(row)

        row, col = 1, 0
        for i in range(0, len(self.lista_piatti_freddi)):
            if row % 10 == 0:
                col += 1
                row = 1
            tk.Radiobutton(self.tab7,
                           text=str(self.lista_piatti_freddi[i]),
                           variable=self.value,
                           width=25,
                           indicatoron=0,
                           value=self.lista_piatti_freddi[i],
                           font='Verdana').grid(row=row, column=col, sticky='w')
            row += 1

        # LABELFRAME per peso da inserire e bottoni
        self.lblframe_peso = ttk.LabelFrame(self.frame_basso, text='Peso')

        # ENTRY per inserimento del peso
        self.entry_peso = ttk.Entry(self.lblframe_peso,
                                    font=('Helvetica', 20),
                                    textvariable=self.value_peso)
        self.entry_peso.focus()

        # BOTTONE ESCI E SALVA
        self.btn_invia = tk.Button(self.frame_basso,
                                   text="Invio",
                                   font=('Helvetica', 20),
                                   command=self.invia)
        self.btn_esci = tk.Button(self.frame_basso,
                                  text="Chiudi finestra",
                                  font=('Helvetica', 20),
                                  command=self.esci_senza_salvare)
        self.btn_esci_salva = tk.Button(self.frame_basso,
                                        text="Esci e salva",
                                        font=('Helvetica', 20),
                                        command=self.esci_salva)
        self.btn_elimina_riga = tk.Button(self.frame_centro, text='Elimina riga', command=self.rimuovi_riga_selezionata)

        # LAYOUT
        self.frame_alto.grid(row=0, column=0, padx=10)
        self.frame_centro.grid(row=1, column=0)
        self.frame_basso.grid(row=2, column=0, columnspan=3)

        self.notebook.grid(row=0, column=0, rowspan=3)

        self.tree.grid(row=0, column=1)
        self.btn_elimina_riga.grid(row=1, column=1, sticky='we')

        self.lbl_settimana.grid(row=0, column=1)
        self.lbl_nr_settimana.grid(row=0, column=2)

        self.lbl_nuovo_lotto.grid(row=0, column=3)
        self.lbl_prog_lotto_vendita.grid(row=0, column=4)

        self.lblframe_peso.grid(row=0, column=0)
        self.entry_peso.grid()

        self.btn_invia.grid(row=0, column=1, padx=10, pady=10)
        self.btn_esci_salva.grid(row=0, column=2, padx=10, pady=10)
        self.btn_esci.grid(row=0, column=3, padx=10, pady=10)

    @staticmethod
    def leggi_file_ini():
        ini = configparser.ConfigParser()
        ini.read('config.ini')
        return ini

    def rimuovi_riga_selezionata(self):
        curitem = self.tree.selection()[0]
        self.tree.delete(curitem)

    def invia(self):
        self.tree.insert('', 'end', values=('L' + (str(self.prog_lotto_ven)),
                                            self.value.get(),
                                            self.value_peso.get(),
                                            self.data,
                                            (1 + int(self.data.strftime('%W')))))
        self.entry_peso.delete(0, tk.END)

    def esci_senza_salvare(self):
        if bool(self.tree.get_children()):
            messagebox.showinfo('Attenzione', 'Ci sono dati inseriti non salvati')
        else:
            self.destroy()

    def esci_salva(self):
        for child in self.tree.get_children():
            self.lista_da_salvare.append(self.tree.item(child)['values'])
        print(self.lista_da_salvare)
        self.c.executemany('INSERT INTO lotti_vendita_cucina(progressivo_ven_c, prodotto, quantita,'
                           'data_prod, settimana) VALUES (%s,%s,%s,%s,%s)', self.lista_da_salvare)
        self.conn.commit()
        self.conn.close()
        self.destroy()

if __name__ == '__main__':
    root = tk.Tk()
    new = NuovoLottoCucina()
    root.mainloop()


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Created on 2017/12/1

__author__ = "Sky Jin "

"""
    Description:
        练习 1 ： 去掉页面动态窗： 这里举一个新世界教育官网首页的例子
        由于alert弹窗不美观，现在大多数网站都会使用自定义弹窗，
        使用Selenium自带的方法就驾驭不了了，此时就要搬出JS大法
        driver.execute_script(js_monitor

"""
from selenium import webdriver
from time import sleep

options = webdriver.ChromeOptions()
options.add_argument('disable-infobars')
driver = webdriver.Chrome(chrome_options=options)
driver.maximize_window()
driver.get("http://sh.xsjedu.org/")
driver.implicitly_wait(20)

# js = driver.execute_script('document.getElementById("doyoo_monitor").style.display')
# print(js)

# 关闭悬浮框的显示。
js_monitor = 'document.getElementById("doyoo_monitor").style.display = "none"'
driver.execute_script(js_monitor)
sleep(2)
driver.quit()


from datetime import datetime
import schedule

from telebot import types

from rf_bank_api import get_banks_currency
from keyboards import kb_banks, kb_currencies, kb_configure
from database_work import add_banks, add_currencies, get_currencies, get_banks, form_gist
from data import banks, currencies, rus_to_en_banks, rus_to_en_currencies
from obj_store_work import get_from_os

import telebot

def schedule_statistic():
    schedule.every().monday.at("07:00").do(form_gist, 'statistics')
    while True:
        schedule.run_pending()

def telegram_bot(token):
    bot = telebot.TeleBot(token)

    @bot.message_handler(commands=["start"])
    def start_message(message):
        bot.send_message(message.chat.id, "Чтобы узнать о возможностях бота, введите команду /help")

    @bot.message_handler(commands=["help"])
    def start_message(message):
        bot.send_message(message.chat.id, "/help - помощь \n/configure - выбор валют и банков \n/notifyOn - включить ежедневные уведомления\n"
                                          "/get - получить сводку по выбранным валютам и банкам \n/getstat - получение статистики ")

    @bot.message_handler(commands=["get"])
    def start_message(message):
        send_notify(message)

    @bot.message_handler(commands=['configure'])
    def start_message(message: types.Message):
        response = bot.send_message(message.chat.id, text="Выберите из списка:", reply_markup=kb_configure)
        d = {'c': [], 'l': []}
        bot.register_next_step_handler(response, choose_option, d)

    @bot.message_handler(commands=['getstat'])
    def start_message(message: types.Message):
        response = get_from_os()
        bot.send_photo(message.chat.id, response['Body'].read())

    def choose_option(message, d):
        if message.text == 'Выбрать банки':
            response = bot.send_message(message.chat.id, text="Выберите банки:", reply_markup=kb_banks)
            bot.register_next_step_handler(response, choose_banks, d)
        if message.text == 'Выбрать валюты':
            response = bot.send_message(message.chat.id, text="Выберите валюты:", reply_markup=kb_currencies)
            bot.register_next_step_handler(response, choose_currency, d)
        if message.text == 'Закрыть':
            bot.send_message(message.chat.id, text=f"Изменения сохранены.\nТекущие настройки:\n Банки:{d.get('l')}\n"
                                                   f"Валюты: {d.get('c')}", reply_markup=types.ReplyKeyboardRemove())

    def choose_banks(message, d):
        if message.text != "Закрыть":
            for bank in banks:
                if message.text == banks.get(bank).get("rus_spell"):
                    append_banks(d.get('l'), message)
                    break
            message = bot.send_message(message.chat.id, text="Выберите банки:", reply_markup=kb_banks)
            bot.register_next_step_handler(message, choose_banks, d)
        else:
            add_banks(message.chat.id, d.get('l'))
            message = bot.send_message(message.chat.id, text=f"Выбранные банки: {d.get('l')}. Сохранено!",
                                       reply_markup=kb_configure)
            bot.register_next_step_handler(message, choose_option, d)

    def append_banks(l, message):
        if not l.__contains__(message.text):
            l.append(message.text)
        return bot.send_message(message.chat.id, text=f"Выбранные банки: {l}. Выберите банки:",
                                reply_markup=kb_banks)

    def append_currencies(c, message):
        if not c.__contains__(message.text):
            c.append(message.text)
        return bot.send_message(message.chat.id, text=f"Выбранные валюты: {c}. Выберите валюты:",
                                reply_markup=kb_currencies)

    def choose_currency(message, d):
        if message.text != "Закрыть":
            for cur in currencies:
                print()
                if (message.text + " (EUR)" == currencies.get(cur).get("rus_spell")) or \
                        (message.text + " (USD)" == currencies.get(cur).get("rus_spell")):
                    append_currencies(d.get('c'), message)
                    break
            message = bot.send_message(message.chat.id, text="Выберите валюты:", reply_markup=kb_currencies)
            bot.register_next_step_handler(message, choose_currency, d)
        else:
            add_currencies(message.chat.id, d.get('c'))
            bot.send_message(message.chat.id, text=f"Выбранные валюты: {d.get('c')}. Сохранено!",
                             reply_markup=kb_configure)
            bot.register_next_step_handler(message, choose_option, d)

    @bot.message_handler(commands=['show'])
    def start_message(message: types.Message):
        user_id = message.chat.id
        bot.send_message(message.chat.id, text=f"Текущие настройки:\n Банки:{get_banks(user_id)}\n"
                                               f"Валюты: {get_currencies(user_id)}")

    @bot.message_handler(commands=['notifyOn'])
    def notify_on(message):
        configure_notification(message)

    def configure_notification(message):
        schedule.every().day.at("07:00").do(send_notify, message)
        bot.send_message(message.chat.id, f"Уведомления включены.", parse_mode='html')
        while True:
            schedule.run_pending()

    def send_notify(message):
        bot.send_message(message.chat.id, text=str(datetime.now()))
        user_id = message.chat.id
        for bank in get_banks(user_id)[0]:
            for curr in get_currencies(user_id)[0]:
                bot.send_message(message.chat.id,
                                 text=get_banks_currency(rus_to_en_banks.get(bank), rus_to_en_currencies.get(curr)))

    bot.polling()


#!/usr/bin/env python3

from itertools import product, permutations, combinations, combinations_with_replacement
import heapq
from collections import deque, defaultdict, Counter
from bisect import bisect
import sys

def input(): return sys.stdin.readline().rstrip()
def list_int(): return list(map(int, input().split()))

def is_ok(mid):
    if mid > 0:
        return True
    else:
        return False

def binary_search(ok, ng):
    # 複雑な二部探索用
    while ng - ok > 1:
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok

INF = float('inf')

# mod = 1000000007
# mod = 998244353
DIR = [(0, 1), (0, -1), (1, 0), (-1, 0)]
sys.setrecursionlimit(10**9)

#  -----------------------  #
N = int(input())

points = [[]]
Array = defaultdict(int)

for i in range(N):
    x, y = map(int, input().split())
    points.append([x, y])
    Array[(x, y)] += 1

ans = 0

for x in range(1, N+1):
    for y in range(x+1, N+1):
        x1, y1 = points[x]
        x2, y2 = points[y]
        if x1 == x2 or y1 == y2:
            continue
        if Array[(x2, y1)] and Array[(x1, y2)]:
            ans += 1

print(ans // 2)