"""
Base fields
===========

This module contains the definition for all basic fields. A field describes
how data should be serialized to JSON and deserialized again
and allows to define special methods for the different CRUD operations
defined by the http://jsonapi.org specification.

You should only work with the following fields directly:

*   :class:`Link`

    For JSON API link objects (usually included in a JSON API links object).

    :seealso: http://jsonapi.org/format/#document-links

*   :class:`Attribute`

    Represent information about a resource object (but not a relationship or a
    link).

    :seealso: http://jsonapi.org/format/#document-resource-object-attributes

*   :class:`ToOne`, :class:`ToMany`

    Represent relationships on a resource object.

    :seealso: http://jsonapi.org/format/#document-resource-object-relationships

.. todo::

    Add support for nested fields (aka embedded documents).

"""

import urllib.parse
from collections import Mapping
from typing import Optional, Sequence

from ..abc.field import FieldABC
from ..common import ALLOWED_MEMBER_NAME_REGEX, Event, JSONAPI
from ..errors import InvalidType, InvalidValue
from ..jsonpointer import JSONPointer

__all__ = (
    'BaseField',
    'Attribute',
    'Link',
    'Relationship',
)

class BaseField(FieldABC):
    """
    This class describes the base for all fields defined on a schema and
    knows how to serialize, deserialize and validate the field.
    A field is usually directly mapped to a property (*mapped_key*)
    on the resource object, but this mapping can be customized
    by implementing custom *getters* and *setters*
    (via :mod:`~aiohttp_json_api.schema.decorators`).

    .. hint::

        The inheritance of fields is currently implemented using the
        :func:`~copy.deepcopy` function from the standard library. This means,
        that in some rare cases, it is necessarily that you implement a
        custom :meth:`__deepcopy__` method when you subclass
        :class:`BaseField`.

    :arg str name:
        The name of the field in the JSON API document. If not explicitly
        given, it's the same as :attr:`key`.
    :arg str mapped_key:
        The name of the associated property on the resource class. If not
        explicitly given, it's the same as :attr:`key`.
    :arg bool allow_none:
        Allow to receive 'null' value
    :arg Event writable:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is writable.
    :arg Event required:
        Can be any :class:`~aiohttp_json_api.schema.common.Event`
        enumeration value and describes in which CRUD context the field
        is required as input.
    """

    def __init__(self, *, name: str = None, mapped_key: str = None,
                 allow_none: bool = False,
                 writable: Event = Event.ALWAYS,
                 required: Event = Event.NEVER):
        #: The name of this field on the
        # :class:`~aiohttp_json_api.schema.BaseSchema`
        #: it has been defined on. Please note, that not each field has a *key*
        #: (like some links or meta attributes).
        self._key = None

        #: A :class:`aiohttp_json_api.jsonpointer.JSONPointer`
        #: to this field in a JSON API resource object. The source pointer is
        #: set from the BaseSchema class during initialisation.
        self._sp = None

        self._name = name
        self._mapped_key = mapped_key
        self.allow_none = allow_none

        assert isinstance(writable, Event)
        self.writable = writable

        assert isinstance(required, Event)
        self.required = required

    @property
    def key(self) -> str:
        return self._key

    @property
    def sp(self) -> JSONPointer:
        return self._sp

    @property
    def name(self) -> Optional[str]:
        return self._name

    @name.setter
    def name(self, value: Optional[str]):
        if not ALLOWED_MEMBER_NAME_REGEX.fullmatch(value):
            raise ValueError(f"Field name '{value}' is not allowed.")
        self._name = value

    @property
    def mapped_key(self) -> Optional[str]:
        return self._mapped_key

    @mapped_key.setter
    def mapped_key(self, value: Optional[str]):
        self._mapped_key = value

    def serialize(self, schema, data, **kwargs):
        return data

    def deserialize(self, schema, data, sp, **kwargs):
        return data

    def pre_validate(self, schema, data, sp):
        pass

    def post_validate(self, schema, data, sp):
        pass

class Attribute(BaseField):
    """
    .. seealso::

        http://jsonapi.org/format/#document-resource-object-attributes

    An attribute is always part of the resource's JSON API attributes object,
    unless *meta* is set, in which case the attribute appears in the resource's
    meta object.

    Per default, an attribute is mapped to a property on the resource object.
    You can customize this behaviour by implementing your own *getter* and
    *setter*:

    .. code-block:: python3

        class Article(BaseSchema):

            title = Attribute()

    Does the same as:

    .. code-block:: python3

        class Article(BaseSchema):

            title = Attribute()

            @gets('title')
            def title(self, article):
                return article.title

            @sets('title')
            def title(self, article, new_title):
                article.title = new_title
                return None

    :arg bool meta:
        If true, the attribute is part of the resource's *meta* object.
    :arg bool load_only:
        If `True` skip this field during serialization, otherwise
        its value will be present in the serialized data.
    :arg \*\*kwargs:
        The init arguments for the :class:`BaseField`.
    """

    def __init__(self, *, meta: bool = False, load_only=False, **kwargs):
        super(Attribute, self).__init__(**kwargs)
        self.meta = bool(meta)
        self.load_only = load_only
        self._trafaret = None

class Link(BaseField):
    """
    .. seealso::

        http://jsonapi.org/format/#document-links

    .. code-block:: python3

        class Article(BaseSchema):

            self = Link(route="some_route_name")

            author = ToOne()
            author_related = Link(
                route="another_route_name", link_of="author"
            )

    In the http://jsonapi.org specification, a link is always part of a
    JSON API links object and is either a simple string or an object with
    the members *href* and *meta*.

    A link is only readable and *not* mapped to a property on the resource
    object (You can however define a *getter*).

    :arg str route:
        A route name for the link
    :arg str link_of:
        If given, the link is part of the links object of the field with the
        key *link_of* and appears otherwise in the resource object's links
        objects. E.g.: ``link_of = "author"``.
    :arg bool normalize:
        If true, the *serialize* method normalizes the link so that it is
        always an object.
    """

    def __init__(self, route: str, link_of: str, *, name: str = None,
                 normalize: bool = False, absolute: bool = True):
        super(Link, self).__init__(name=name, writable=Event.NEVER)

        self.normalize = bool(normalize)
        self.absolute = absolute
        self.route = route
        self.link_of = link_of

    def serialize(self, schema, data, **kwargs):
        """Normalizes the links object if wished."""
        registry = schema.ctx.request.app[JSONAPI]['registry']
        rid = registry.ensure_identifier(data)
        route = schema.ctx.request.app.router[self.route]
        route_url = route._formatter.format_map({'type': rid.type,
                                                 'id': rid.id,
                                                 'relation': self.link_of})
        if schema.ctx is not None and self.absolute:
            result = urllib.parse.urlunsplit(
                (schema.ctx.request.scheme, schema.ctx.request.host, route_url,
                 None, None)
            )
        else:
            result = route_url

        if not self.normalize:
            return result
        elif isinstance(result, str):
            return {'href': result}

        return result

class Relationship(BaseField):
    """
    .. seealso::

        http://jsonapi.org/format/#document-resource-object-relationships

    Additionally to attributes and basic fields, we must know how to *include*
    the related resources in the case of relationships. This class defines
    the common interface of *to-one* and *to-many* relationships (links object,
    meta object, *self* link, *related* link, validation, ...).

    Relationships are always part of the resource's JSON API relationships
    object.

    .. seealso::

        * :class:`~aiohttp_json_api.schema.relationships.ToOne`
        * :class:`~aiohttp_json_api.schema.relationships.ToMany`

    :arg Event require_data:
        If true, the JSON API relationship object must contain the *data*
        member. Must be a :class:`~aiohttp_json_api.schema.common.Event`
        instance.
    :arg bool dereference:
        If true, the relationship linkage is dereferenced automatic when
        decoded. (Implicitly sets *require_data* to Event.ALWAYS)
    :arg Sequence[str] foreign_types:
        A set with all foreign types. If given, this list is used to validate
        the input data. Leave it empty to allow all types.
    """
    relation = None

    def __init__(self, *, dereference: bool = True,
                 require_data: Event = Event.ALWAYS,
                 foreign_types: Sequence[str] = None,
                 links: Sequence[Link] = None,
                 id_field: Attribute = None,
                 **kwargs):
        BaseField.__init__(self, **kwargs)
        self.links = {link.name: link for link in links} if links else {}

        # NOTE: The related resources are loaded by the schema class for
        #       performance reasons (one big query vs many small ones).
        self.dereference = dereference

        self.foreign_types = frozenset(foreign_types or [])

        assert isinstance(require_data, Event)
        self.require_data = require_data
        self.id_field = id_field

    def add_link(self, link: Link):
        """
        Adds a new link to the links object.
        """
        self.links[link.name] = link
        return self

    def validate_resource_identifier(self, schema, data, sp):
        """
        .. seealso::

            http://jsonapi.org/format/#document-resource-identifier-objects

        Asserts that *data* is a JSON API resource identifier with the correct
        *type* value.
        """
        if not isinstance(data, Mapping):
            detail = 'Must be an object.'
            raise InvalidType(detail=detail, source_pointer=sp)

        if not ('type' in data and 'id' in data):
            detail = 'Must contain a "type" and an "id" member.'
            raise InvalidValue(detail=detail, source_pointer=sp)

        if self.foreign_types and not data['type'] in self.foreign_types:
            detail = f'Unexpected type: "{data["type"]}".'
            raise InvalidValue(detail=detail, source_pointer=sp / 'type')

        if self.id_field is not None:
            self.id_field.pre_validate(self, data['id'], sp / 'id')

    def validate_relationship_object(self, schema, data, sp):
        """
        Asserts that *data* is a JSON API relationship object.

        *   *data* is a dictionary
        *   *data* must be not empty
        *   *data* may only have the members *data*, *links* or *meta*.
        *   *data* must contain a *data* member, if :attr:`dereference` or
            :attr:`require_data` is true.
        """
        if not isinstance(data, Mapping):
            detail = 'Must be an object.'
            raise InvalidType(detail=detail, source_pointer=sp)

        if not data:
            detail = 'Must contain at least a "data", "links" or "meta" member.'
            raise InvalidValue(detail=detail, source_pointer=sp)

        if not (data.keys() <= {'links', 'data', 'meta'}):
            unexpected = (data.keys() - {'links', 'data', 'meta'}).pop()
            detail = f"Unexpected member: '{unexpected}'."
            raise InvalidValue(detail=detail, source_pointer=sp)

        if (self.dereference or self.require_data) and 'data' not in data:
            detail = 'The "data" member is required.'
            raise InvalidValue(detail=detail, source_pointer=sp)

    def pre_validate(self, schema, data, sp):
        self.validate_relationship_object(schema, data, sp)
        super(Relationship, self).pre_validate(schema, data, sp)


# Import Meteostat library and dependencies

from datetime import datetime
from dateutil.deltatime import deltatime
from meteostat import Point, Daily
import localpackage.modified_ozone as ooo
import pandas as pd
import localpackage.fetch_city as fc
from citipy import citipy

#API key AQICN
o3 = ooo.Ozone('d8a099d2492a444219a00713bddafb693699c53f')

#obtener las coordenadas elegidas en tableau en el point location
def obtain_params():
    sheet_id = '1rjx1D0tLXRb3c01ezuaQwfi2LAq5ybR1R1el9V1anMM'
    sheet_name = 'areaverde'
    url = f'https://docs.google.com/spreadsheets/d/{sheet_id}/gviz/tq?tqx=out:csv&sheet={sheet_name}'
    a=pd.read_csv(url)
    lat=a['lat'][0]
    lon=a['lon'][0]
    especiedict={'area': a['area'][1],a['especie1'][1]:a['especie1'][2],a['especie2'][1]:a['especie2'][2],a['especie3'][1]:a['especie3'][2]}
    return lat, lon, especiedict
def point(latitud, longitud):
    location = Point(latitud, longitud)
    city=o3.get_city_id(latitud,longitud)
    return location, city
#obtener la poblacion
def population_data(latitud, longitud):
    city = citipy.nearest_city(latitud, longitud).city_name
    if city== 'new york':
        city='New York City'
    data=fc.obtain_data(city)[0]
    return data
#obtener la fecha actual
def date():
    end = datetime.today()
    end = end.replace(hour=0, minute=0, second=0, microsecond=0)
    start = end- relativedelta(years=1)
    return start, end
#obtener datos diarios del último año
def last_year_weather(latitud,longitud):
    start=date()[0]
    end=date()[1]
    location = point(latitud,longitud)[0]
    data = Daily(location, start, end)
    data = data.fetch().drop(['tmin','tmax','snow','wdir','wpgt','pres','tsun'], axis=1)
    data=data[['wspd','prcp','tavg']]
    return data

def historical_Ct(latitud,longitud):
    city=point(latitud, longitud)[1]
    data = o3.get_historical_data(city_id=city)
    return data
def get_data(latitud,longitud):
    df=last_year_weather(latitud,longitud)
    start=date()[0]
    end=date()[1]
    rawdata=historical_Ct(latitud,longitud).fillna(method='ffill').fillna(method='bfill')
    Ct=rawdata['pm25']
    data=pd.concat([df,Ct],axis=1).fillna(method='ffill').fillna(method='bfill')[start:end]
    data=data[['wspd','prcp','pm25','tavg']]
    return data
def get_city_emission(latitud,longitud):
    city= list(population_data(latitud, longitud))
    contrydict=pd.read_csv('localpackage/Emission_inventory.csv', sep=';').set_index('Pais').T.to_dict('list')
    dict={}
    name=city[0]
    Chab=float(city[1])
    pais=city[4]
    Et=contrydict[pais][0]
    Et=float(Et.replace(',','.'))
    hab=float(city[5])
    Ehab=Et/hab
    Ecity=Ehab*Chab
    dict[name]=Ecity
    return dict, name


import torch
import torchvision
import torch.nn as nn
import numpy as np

from problog.logic import Var
from utils.df_dpl_utils import neural_predicate
from DeepProbLog.train import train_model2
from DeepProbLog.data_loader import load
from DeepProbLog.model import Model
from DeepProbLog.optimizer import Optimizer
from DeepProbLog.network import Network
from metrics.metric_recording import save_data, clear_file, save_cm

#### NET

# Wardrobe specific parameters:
num_ftrs_wardrobe = 7
nr_output = 3
num_outputs_cm = 8

net = torchvision.models.resnet50(pretrained=True)

# Freeze feature extraction weights to speed up training (these parameters will not be changed during back propagation)
for param in net.parameters():
    param.requires_grad = False

# Parameters of newly constructed modules have requires_grad=True by default
num_ftrs_resnet = net.fc.in_features
# net.fc = nn.Linear(num_ftrs_resnet,num_ftrs_wardrobe)
net.fc = nn.Sequential(
            nn.Linear(num_ftrs_resnet, num_ftrs_wardrobe),
            # nn.ReLU(),
            # nn.Linear(120, 84),
            # nn.ReLU(),
            # nn.Linear(84, num_ftrs_wardrobe),
            nn.Softmax(1)
            )

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
net.to(device)

clear_file("advanced_outfit_dist.txt")
clear_file("advanced_outfit_acc.txt")
clear_file("advanced_outfit_F1.txt")

def labelVector(bits) :
    return 1*int(bits[2]) + 2*int(bits[1]) + 4*int(bits[0])

labelMap={0:[0,0,0], 1:[0,0,1],2:[0,1,0],3:[0,1,1],4:[1,0,0],5:[1,0,1],6:[1,1,0],7:[1,1,1]}

def hamming_dist(l, c) :
    bl = labelMap[l]
    bc = labelMap[c]
    distance = 0
    for index in range(len(bl)):
        distance += abs(bc[index] - bl[index])
    return distance

def test(model,iteration):
    net.eval()
    for param in net.fc.parameters() :
        param.requires_grad = False
    n=0
    correct = 0
    N = len(test_queries)
    confusion = np.zeros((num_outputs_cm, num_outputs_cm), dtype=np.uint32)  # First index actual, second index predicted
    total_distance=0
    for d in test_queries:
        args = list(d.args)
        label = args[-nr_output:]
        args[-nr_output:] = [Var('X_{}'.format(i)) for i in range(nr_output)]
        q = d(*args)
        out = model.solve(q, None, True)
        out = max(out, key=lambda x: out[x][0])
        if out == d:
            correct += 1
        else:
            n += 1
        l = labelVector(label)
        c = labelVector(list(out.args)[-nr_output:])
        confusion[l, c] += 1
        total_distance += hamming_dist(l, c)

    save_cm(confusion,"advanced_outfit_cm.txt")
    print(confusion)
    F1 = 0
    for nr in range(num_outputs_cm):
            TP = confusion[nr, nr]
            FP = sum(confusion[:, nr]) - TP
            FN = sum(confusion[nr, :]) - TP
            F1 += 2 * TP / (2 * TP + FP + FN) * (FN + TP) / N

    acc = correct / N
    print("Acc : " + str(acc))
    avg_distance = total_distance / n
    save_data(iteration,avg_distance,"advanced_outfit_dist.txt")
    save_data(iteration,acc,"advanced_outfit_acc.txt")
    save_data(iteration,F1,"advanced_outfit_F1.txt")

    for param in net.fc.parameters() :
        param.requires_grad = True
    net.train()
    return

#### DPL

pl_file_path = 'pl_files/advanced_outfit.pl'

train_queries = load('data/generated_data/train_advanced_outfit_data.txt')
test_queries = load('data/generated_data/test_advanced_outfit_data.txt')

with open(pl_file_path) as f:
    problog_string = f.read()

net.optimizer = torch.optim.Adam(net.fc.parameters(), lr=0.001)

netwrk = Network(net,'fashion_df_net', neural_predicate)

model = Model(problog_string,[netwrk],caching=False)
optimizer = Optimizer(model,2)

train_model2(model,train_queries,3,optimizer,test_iter=5000,test=test,snapshot_iter=10000)


from numpy import packbits
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn.modules import conv
from torchvision import models

class PartialConv(nn.Module):
    def weight_init(self, m):
        classname = m.__class__.__name__    ##获取当前结构名称
        if classname.find('Conv') != -1:
            nn.init.normal_(m.weight, 0.0, 0.002)  ##正态分布初始化
        elif classname.find('BatchNorm') != -1:
            nn.init.normal_(m.weight, 1.0, 0.02)   ##正态分布初始化
            nn.init.zeros_(m.bias)

    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                padding=0,dilation = 1, group=1, bias = False ):
        super(PartialConv, self).__init__()
        self.input_conv = nn.Conv2d(in_channels, out_channels, kernel_size,
                                    stride, padding, dilation, group, bias)
        self.mask_conv = nn.Conv2d(in_channels, out_channels, kernel_size,
                                        stride, padding, dilation, group, False)
        torch.nn.init.constant_(self.mask_conv.weight, 1.0)
        self.input_conv.apply(self.weight_init)

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

    def forward(self, input, mask):
        output = self.input_conv(input*mask)
        if self.input_conv.bias is not None:
            output_bias = self.input_conv.bias.view(1,-1,1,1).expand_as(output)
        else:
            output_bias = torch.zeros_like(output)
        with torch.no_grad():
            output_mask = self.mask_conv(mask)
        no_update_holes = output_mask == 0
        mask_sum = output_mask.masked_fill_(no_update_holes, 1.0)

        output_pre = (output - output_bias) / mask_sum + output_bias
        output = output_pre.masked_fill_(no_update_holes, 0.0)

        new_mask = torch.ones_like(output)
        new_mask = new_mask.masked_fill_(no_update_holes, 0.0)

        return output, new_mask

class PCBActive(nn.Module):
    def __init__(self, in_channels, out_channels, stride = 1, activ='leaky', conv_bias = False):
        super(PCBActive, self).__init__()

        self.conv = PartialConv(in_channels, out_channels, 3, stride=stride, padding=1, bias= conv_bias)
        self.bn = nn.BatchNorm2d(out_channels)
        if activ == 'relu':
            self.activation = nn.ReLU()
        elif activ == 'leaky':
            self.activation = nn.LeakyReLU(negative_slope=0.2, inplace=True)

    def forward(self, input, mask):
        out, out_mask = self.conv(input, mask)
        out = self.bn(out)
        out = self.activation(out)

        return out, out_mask

class DoublePConv(nn.Module):
    def __init__(self, inchannels, outchannels, stride = 1, active='leaky', conv_bias = False):
        super(DoublePConv, self).__init__()
        self.pconv1 = PCBActive(inchannels, outchannels, stride=stride, activ= active, conv_bias=conv_bias)
        self.pconv2 = PCBActive(outchannels, outchannels, stride=stride, activ= active, conv_bias=conv_bias)

    def forward(self, input, mask):
        out1, mask1 = self.pconv1(input, mask)
        out, out_mask = self.pconv2(out1, mask1)

        return out, out_mask


import json
from pytube import YouTube
import ssl
import requests
from lxml import etree

ssl._create_default_https_context = ssl._create_unverified_context

def extra_video_data(video_url):
    if 'tiktok' in video_url:
        print(video_url)
        page=requests.get(url='https://www.tiktok.com/oembed?url='+video_url)
        data = json.loads(page.text)
        video_data = {"embed_url": video_url, "video_title": data['title'],"video_id":data['provider_url'],'articleImageLink': data['thumbnail_url'], 'articleUser' : data['author_name']}
        return video_data
        # html = etree.HTML(page)
    else:

        result = YouTube(video_url)
        embed_url = result.embed_url
        video_id=result.video_id
        video_title = result.title
        video_data = {"embed_url": embed_url, "video_title": video_title,"video_id":video_id}
        return video_data


"""View for checkout"""
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.conf import settings
from django.utils import timezone
import stripe
from tickets.models import Ticket
from .models import NewFeatureUpvote
from .forms import MakePaymentForm

stripe.api_key = settings.STRIPE_SECRET

@login_required()
def checkout(request):
    """Checkout view"""
    if request.method == 'POST':
        payment_form = MakePaymentForm(request.POST)
        # If form is valid
        if payment_form.is_valid():
            cart = request.session.get('cart', {})
            total = 0
            new_feature_to_upvote = []
            # Add username and date and save order
            for id, amount in cart.items():
                new_feature = get_object_or_404(Ticket, pk=id)
                new_feature_to_upvote.append((new_feature, amount))
                total += amount
                new_feature_upvote = NewFeatureUpvote(username=request.user.username, amount=total, new_feature=new_feature, date=timezone.now())
                new_feature_upvote.save()
            # Try payment, fetch errors
            try:
                customer = stripe.Charge.create(
                    amount=int(total*100),
                    currency='EUR',
                    description=request.user.email,
                    card=payment_form.cleaned_data['stripe_id']
                    )
            except stripe.error.CardError:
                messages.error(request, "Your card was declined!")
            # If payment was successful
            if customer.paid:
                messages.error(request, "Your payment was successfull!")
                # Upvote payed features, add amount to payments
                for feature in new_feature_to_upvote:
                    ticket = Ticket.objects.get(pk=feature[0].pk)
                    ticket.votes.up(user_id=request.user.pk)
                    amount = feature[1]
                    ticket.payments += amount
                    ticket.save()
                request.session['cart'] = {}
                return redirect(reverse('tickets'))
            # If payment was not successful
            else:
                messages.error(request, "Payment was not successful!")
        # If form is not valid
        else:
            print(payment_form.errors)
            messages.error(request, "We were unable to make a payment with that card!")
    else:
        payment_form = MakePaymentForm

    return render(request, 'checkout.html', {'payment_form': payment_form, 'publishable': settings.STRIPE_PUBLISHABLE})


import glob
import json
import sys
import numpy as np
import os

# this scrpit is used to find a proper color map factor used in 'building.py' by mapping the average density to average color

if __name__ == '__main__':
	graph = sys.argv[1]

	wavemaps = glob.glob(f'{graph}/{graph}_waves/wavemap_*.json')

	buildingList = []
	for wavemap in wavemaps:
		_, name = os.path.split(wavemap)
		if name.count('_') == 3:
			buildingList.append(wavemap)

	densityArray = []
	for waveFile in buildingList:
		with open(waveFile, 'r') as f:
			data = json.load(f)
		for wave, waveData in data.items():
			if int(wave) > 0:
				v = waveData['ss']
				vo = waveData['t'] + waveData['s']
				e = 2 * waveData['ie'] + waveData['ee']
				densityArray.append((e / (v * vo)) if e > 0 else 0)
			else:
				continue

	aveDensity = np.mean(densityArray)
	factor = np.square(aveDensity / (aveDensity - 1))
	print(factor)


# -*- coding: utf-8 -*-
"""
Created on Sat Apr 14 11:18:12 2018

@author: ziwenruo
"""

# -*- coding: utf-8 -*-
"""
Created on Sun Mar 18 09:35:34 2018

@author: ziwenruo
"""

import tensorflow as tf
import numpy as np
import pandas as pd
import os
import argparse
from collections import namedtuple

REC_DB_PATH = 'G:\\workarea\\scripts\\stock_tfexample\\train'
SRECORD = namedtuple('REC',"date high close tick")

record_info = pd.DataFrame({
        'name':['code','date','label_type','tick'],
        'type':[tf.string,tf.string,tf.int64,tf.float32],
        'shape':[(),(),(),(299,299,3)],
        'isbyte':[True,True,False,False],
        'length_type':['fixed','fixed','fixed','var'],
        }, columns=['name','type','shape','isbyte','length_type'])

def get_filenames(cate, path=REC_DB_PATH):
    # get all file names
    files= os.listdir(path)
    filepaths = [os.path.join(path,file) for file in files if not os.path.isdir(file) and '.tfrecord' in file]
    if cate in ("t0", "t1", "t2"):
        filepaths = [file for file in filepaths if "_%s_"%cate in file]
    filepaths.sort(key=os.path.getsize, reverse=True)
    return np.array(filepaths)

def read_stock_tfrecord(fname):
    rec_opt = tf.python_io.TFRecordOptions(tf.python_io.TFRecordCompressionType.GZIP)
    record_iterator = tf.python_io.tf_record_iterator(fname, options=rec_opt)
    example = tf.train.Example()
    TFREC = namedtuple('TFREC',"date code label tick")
    for i in iter(record_iterator):
        example.ParseFromString(i)
        mycode = example.features.feature['code'].bytes_list.value
        mydate = example.features.feature['date'].bytes_list.value
        mylabel = example.features.feature['label_type'].int64_list.value[0]
        mytick = example.features.feature['tick'].float_list.value
        yield TFREC(mydate, mycode, mylabel, mytick)

#
#tarfile = ["G:\\workarea\\scripts\\stock_tfexample\\train\\tick20180319_t1_603712.tfrecord",
#           "G:\\workarea\\scripts\\stock_tfexample\\train\\tick20180319_t0_002294.tfrecord",
#           "G:\\workarea\\scripts\\stock_tfexample\\train\\tick20180319_t0_002032.tfrecord",
#           ]

def provide_rec(flist):
    for f in flist:
        yield from read_stock_tfrecord(f)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--rtype', help='example: t0|t2|t1')
    parser.add_argument('--path', default=REC_DB_PATH, help='example: t0|t2|t1')

    args = parser.parse_args()

#    data_path = 'G:\\workarea\\scripts\\stock_tfexample\\train'
    db_file_list = get_filenames(args.rtype)

    count = 0
    for y in iter(provide_rec(db_file_list)):
        count += 1
        print("<{}> {} {} {}".format(count, y.date, y.code, y.label))

    print("Got {} records finally!!".format(count))

if __name__ == '__main__':
    main()


from django.contrib import admin

from .models import Order, OrderLineItem, Coupon

class OrderLineItemAdminInline(admin.TabularInline):
    '''Customize the admin interface to display order line items'''
    model = OrderLineItem
    readonly_fields = ('line_item_total',)

class OrderAdmin(admin.ModelAdmin):
    '''Customize the admin interface to display order details'''

    inlines = (OrderLineItemAdminInline,)

    readonly_fields = ('order_id', 'created', 'updated', 'tax',
                       'delivery_cost', 'order_total', 'grand_total',)

    fields = ('order_id', 'user_profile', 'first_name', 'last_name',
              'email_address', 'phone_number', 'street_address1',
              'building_number1',
              'street_address2', 'building_number2',
              'city', 'postal_code',
              'country', 'created', 'updated', 'tax', 'paid',
              'delivery_cost', 'order_total', 'grand_total',)

    list_display = (
        'order_id',
        'first_name',
        'last_name',
        'email_address',
        'phone_number',
        'street_address1',
        'building_number1',
        'street_address2',
        'building_number2',
        'city',
        'postal_code',
        'country',
        'order_total',
        'tax',
        'delivery_cost',
        'grand_total',
        'created',
        'updated',
        'paid',
    )

    ordering = ('-created',)

class CouponAdmin(admin.ModelAdmin):
    '''Customize the admin interface to display gift coupon details'''
    list_display = (
        'coupon_id',
        'coupon_code',
        'coupon_value',
        'coupon_expiry',
        'created',
        'active',
        'description',
    )

admin.site.register(Order, OrderAdmin)
admin.site.register(Coupon, CouponAdmin)


#! /usr/bin/env python
import heapq
import itertools

from storygen.events.event import PlagueEvent, BirthEvent
from storygen.events.timestamp import Time, TimeDelta
from storygen.names.name import Name

def heappopwhile(predicate, heap):
    while True:
        try:
            e = heapq.heappop(heap)
        except IndexError:
            break
        if predicate(e):
            yield e
        else:
            heapq.heappush(heap, e)
            break

class World:

    def __init__(self):
        self.clock = Time(5000, 1, 1)
        self.events = []
        self.people = set()
        self.men = set()
        self.women = set()

    def schedule(self, e):
        if e.timestamp < self.clock:
            raise RuntimeError("Cannot schedule an event in the past")
        heapq.heappush(self.events, e)

    def step(self, dt=None):
        dt = dt or TimeDelta(days=1)
        self.clock += dt
        # self.log("A new day")
        population = len(self.people)
        for e in heappopwhile((lambda e: e.timestamp <= self.clock), self.events):
            e(self)
        # if population != len(self.people):
        #     print("WORLD POPULATION: {}".format(len(self.people)))
        return bool(self.events)

    def steps(self, n, dt=None):
        for i in range(n):
            yield self.step(dt=dt)

    def step_infinite(self, dt=None):
        while True:
            yield self.step(dt=dt)

    def step_all(self, dt=None):
        for e in itertools.takewhile((lambda has_events: has_events), self.step_infinite(dt=dt)):
            yield e

    def log(self, message, *args, timestamp=None, **kwargs):
        timestamp = timestamp or self.clock
        msg = message.format(*args, **kwargs)
        print("[{clock:%Y-%m-%d}] {msg}".format(clock=timestamp, msg=msg))

def main():
    initial_population = 100

    from storygen.names.phoneme import load_phonemes
    from storygen.languages.language import LanguageGenerator
    from storygen.culture.culture import Culture
    from storygen.people.person import Person

    language_gen = LanguageGenerator(load_phonemes())
    language = language_gen()
    culture = Culture(language)
    print("Language phonemes: {}".format(", ".join(sorted(str(p) for p in language.phonemes))))
    names = [Name(culture) for n in range(initial_population)]

    world = World()

    for i, name in enumerate(names):
        birthdate = world.clock
        person = Person(name, Person.MALE if (i % 2) else Person.FEMALE, birthdate, culture)
        birth = BirthEvent(person)
        world.schedule(birth)

    # world.schedule(PlagueEvent(world.clock + TimeDelta(days=100000)))

    for _ in world.step_all():
        pass

    world.log("History has ended after {} years", world.clock.year-5000)

if __name__ == "__main__":
    main()


import matplotlib.pyplot as plt
import math
import random
from decimal import Decimal

# Recursive factorial
def factorial(n):
	if n < 0:
		return -1 # Error, defined only for positive numbers
	if n == 1 or n == 0:
		return 1
	return n*factorial(n-1)

# Heron's method
def sqrt(s):
	x = s/2 # initial guess
	# Iterate until error is small
	while x**2 - s > 0.01  or x**2 - s < -0.01:
		x = ((s/x)+x)/2
	return x

# Tylor sin x in degrees
def sin(x):
	x = (x*3.1416)/180 # assuming degrees as input
	s = 0
	for n in range(0,10):
		alpha = 2*n+1
		s = s + (((-1)**n)*(x**alpha))/factorial(alpha)
	return s

# Tylor cos x in degrees
def cos(x):
	x = (x*3.1416)/180
	s = 0
	for n in range(0,10):
		alpha = 2*n
		s = s + (((-1)**n)*(x**alpha))/factorial(alpha)
	return s

# linear congruential method
# x_i+1 = (a*X_n + c) mod m
def myrand(x):
	x = hash(str(x)) # using a hash to have a large starging number
	c = 1013904223
	a = 1664525
	m = 2**32
	x = (a*x+c) % m
	return x/m # to get number between 0 and 1

# Euclidean distance
def distance(v1,v2):
	# If one cluster is empty
	if len(v1)==0 or len(v2)==0:
		return 1000 # distance is infinite
	sum = 0
	for i in range(len(v1)):
		sum += ((v2[i]-v1[i])**2)
	return sqrt(sum)

fig = plt.figure()
t = []
for i in range(0,360):
	t.append(sin(i))

s = []
for i in range(0,360):
	s.append(math.sin(math.radians(i)))

plt.plot(t,"-",c="blue", label="Without import")
plt.plot(s,":", linewidth=3,c="red", label="With import")
plt.title("Sine")
plt.xlabel("Degree")
plt.ylabel("Sine")
plt.legend(loc="upper left")
plt.show()

fig = plt.figure()
t = []
for i in range(0,360):
	t.append(cos(i))

s = []
for i in range(0,360):
	s.append(math.cos(math.radians(i)))

plt.plot(t,"-",c="blue", label="Without import")
plt.plot(s,":", linewidth=3,c="red", label="With import")
plt.title("Cosine")
plt.xlabel("Degree")
plt.ylabel("Cosine")
plt.legend(loc="upper left")
plt.show()

fig = plt.figure()
t = []
for i in range(0,100):
	t.append(sqrt(i))

s = []
for i in range(0,100):
	s.append(math.sqrt(i))

plt.plot(t,"-",c="blue", label="Without import")
plt.plot(s,":", linewidth=3,c="red", label="With import")
plt.title("Square root")
plt.xlabel("Value")
plt.ylabel("Square root")
plt.legend(loc="upper left")
plt.show()

fig = plt.figure()
x = []
for j in range(0,50):
	for i in range(0,50):
		x.append(myrand(i+myrand(j)))

y = []
for j in range(0,50):
	for i in range(0,50):
		y.append(myrand(j+myrand(i)))

x1 = []
for j in range(0,50):
	for i in range(0,50):
		x1.append(random.random())

y1 = []
for j in range(0,50):
	for i in range(0,50):
		y1.append(random.random())

plt.scatter(x,y,c="blue",marker="o", label="Without import")
plt.scatter(x1,y1,c="red",marker="x", label="With import")
plt.title("Random")
plt.xlabel("x coordinate")
plt.ylabel("y coordinate")
plt.legend(loc="upper left")
plt.show()


import os
import sys
import time

import schedule

def job():
    run_time_cmd = "ps -eo pid,comm,cmd,start,etime | grep 'python main.py' | grep -v grep | sort -k 5 | head -n 1"
    run_time = os.popen(run_time_cmd).read().strip().split(" ")[-1]
    sys.stdout.write("\r" + f"run time : {run_time}")
    sys.stdout.flush()

    run_hour = run_time.split(":")[0]
    if run_time and int(run_hour) >= 60:
        # kill
        print("kill job")
        kill_cmd = "kill -9 `ps -ef|grep 'python main.py'|grep -v 'grep'|awk '{print $2}'`"
        os.system(kill_cmd)
        watchdog = False

watchdog = True

schedule.every(10).minutes.do(job) # 每隔 10 分运行一次 job 函数

while True and watchdog:
    schedule.run_pending()   # 运行所有可以运行的任务
    time.sleep(360)


"""
Convenient setup for jupyter notebook explorations
Use via inserting:
   `from proteinworkshop.utils.notebook import *`
as the last import in your jupyter notebook imports cell.
"""

import os
import pathlib

import hydra
from loguru import logger as log

from proteinworkshop import constants

try:
    # Convenient for debugging
    import lovely_tensors as lt

    lt.monkey_patch()
except:
    pass

def init_hydra_singleton(
    path: os.PathLike = constants.HYDRA_CONFIG_PATH,
    reload: bool = False,
    version_base: str = "1.2",
) -> None:
    """Initialises the hydra singleton.

    .. seealso::
        https://stackoverflow.com/questions/60674012/how-to-get-a-hydra-config-without-using-hydra-main

    :param path: Path to hydra config, defaults to ``constants.HYDRA_CONFIG_PATH``
    :type path: os.PathLike, optional
    :param reload: Whether to reload the hydra config if it has already been
        initialised, defaults to ``False``
    :type reload: bool, optional
    :raises ValueError: If hydra has already been initialised and ``reload`` is
        ``False``
    """
    # See: https://stackoverflow.com/questions/60674012/how-to-get-a-hydra-config-without-using-hydra-main
    if reload:
        clear_hydra_singleton()
    try:
        path = pathlib.Path(path)
        # Note: hydra needs to be initialised with a relative path. Since the hydra
        #  singleton is first created here, it needs to be created relative to this
        #  file. The `rel_path` below takes care of that.
        rel_path = os.path.relpath(path, start=pathlib.Path(__file__).parent)
        hydra.initialize(rel_path, version_base=version_base)
        log.info(f"Hydra initialised at {path.absolute()}.")
    except ValueError:
        log.info("Hydra already initialised.")

def clear_hydra_singleton() -> None:
    """
    Clears the initialised hydra singleton.
    """
    if hydra.core.global_hydra.GlobalHydra not in hydra.core.singleton.Singleton._instances:  # type: ignore
        return
    hydra_singleton = hydra.core.singleton.Singleton._instances[hydra.core.global_hydra.GlobalHydra]  # type: ignore
    hydra_singleton.clear()
    log.info("Hydra singleton cleared and ready to re-initialise.")


import serial
import time
import urllib.request
import urllib.parse

class Serial_Controller:
    def __init__(self, port, baudrate):
        print("Serial Connecting...")
        self.ser = serial.Serial(port, baudrate, timeout=1)
        time.sleep(2)

    def send_msg(self, msg):
        self.ser.write(msg)
        print("send ", msg)

    def read_reply(self):
        reply = self.ser.readline()
        reply = reply.decode()
        reply = reply.rstrip("\n")
        reply = reply.rstrip("\r")
        print("recv ", reply)
        return reply

    def close(self):
        self.ser.close()

class Char_Getter:
    def __init__(self):
        self.url = "https://arcane-bayou-55620.herokuapp.com/getArray/"

    def get_charArray(self, c):
        print("REQUEST...")
        char = urllib.parse.quote(c)
        print("GET...")
        url = self.url + char
        array = urllib.request.urlopen(url).read()
        a = array.decode()
        a = self.reshape(a)
        return a

    def reshape(self, a):
        b = ""
        for i in range(8):
            for j in range(8):
                tmp = a[j*8+i]
                b += tmp
        return b


from SkinCancer.Model import Net
from SkinCancer.Dataloader import TrainDataset
from torch import save
from torch.tensor import Tensor
import torch.nn as nn
from torch.optim import Adam
from torch.utils.data import DataLoader

model = Net()
optimizer = Adam(model.parameters())
criterion = nn.BCELoss()

train_dataset = TrainDataset()
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

def train(epoch):
	for step, data in enumerate(train_loader):
		train_x, train_y = data
		train_y = train_y.type('torch.FloatTensor')
		optimizer.zero_grad()
		y_pred = model.forward(train_x)
		loss = criterion(y_pred, train_y)
		loss.backward()
		optimizer.step()
		if step == len(train_dataset) // 32 - 1:
			print('Epoch {}, loss={}'.format(epoch, loss.item()))

for i in range(1, 11):
	train(i)

save(model.state_dict(), 'model_skin_cancer.pt')


import cv2
import numpy as np

canvas = np.ones([640,640,3], 'uint8')*255 # making a white canvas for drawing
color = (0,0,0)
radius = 5
pressed = False

def painter(event, x, y, flags, params):
    global canavs, pressed
    if event == cv2.EVENT_LBUTTONDOWN:
        pressed = True
        cv2.circle(canvas, (x,y), radius, color, -2)
    elif event == cv2.EVENT_MOUSEMOVE and pressed == True:
        cv2.circle(canvas, (x,y), radius, color, -2)
    elif event == cv2.EVENT_LBUTTONUP:
        pressed = False

cv2.namedWindow("canvas")
cv2.setMouseCallback("canvas", painter)

while True:
    cv2.imshow("canvas", canvas)

    k = cv2.waitKey(1)

    if k & 0xff == ord('q'):
        break

    if k & 0xff == ord('y'):
        color = (0, 255, 255) # yellow color

    if k & 0xff == ord('b'):
        color = (255,0,0) # blue color

    if k & 0xff == ord('r'):
        color = (0,0,255) # red color

    if k & 0xff == ord('g'):
        color = (0,255,0) # green color

    if k & 0xff == ord('c'):
        canvas = np.ones([640,640,3], 'uint8')*255

cv2.destroyAllWindows()


from http.server import SimpleHTTPRequestHandler
from HTTPWebSocketsHandler import HTTPWebSocketsHandler

class SocketHandler(SimpleHTTPRequestHandler):

    def parse_request(self):
        parseStatus = super().parse_request()
        if self.headers.get("Upgrade", False) and self.headers.get("Upgrade", None).lower().strip() == "websocket":
            self.command = "SOCKET"
        return parseStatus

    def do_SOCKET(self):
        HTTPWebSocketsHandler(self)


"""
CS101 Webscraping Project Example
Gwen Urbanczyk
"""
from bs4 import BeautifulSoup
import requests

def get_actors(movie_num):
    """
    Function goes through the first movie_num movies on the IMDb top 1000 movies page.
    (movie_num must be a multiple of 50 and 0 < x <= 1000) and scrapes thier titles
    and cast member list.
    Returns a tuple of a list of titles and a list of actor lists.
    """
    if movie_num % 50 != 0:
        raise ValueError("movie_num must be a multiple of 50")
    if movie_num < 0 or movie_num > 1000:
        raise ValueError("movie_num must be between 0 and 1000")

    list_base_url = 'https://www.imdb.com/search/title/?groups=top_1000&'
    titles = []
    actor_lists = []

    for page in range(1, movie_num, 50):
        # Building the URL...
        url = list_base_url
        if page != 1:
            url += "start={}".format(page)

        # Scraping the source code
        source = requests.get(url).text
        soup = BeautifulSoup(source, 'html.parser')
        url_base = 'https://www.imdb.com'

        soup = soup.find('div', class_ = "lister-list")

        # For each movie on the page...
        for entry in soup.find_all('div', class_="lister-item mode-advanced"):
            # Get the link to the movie's page
            content = entry.find('div', class_="lister-item-content")
            title = content.h3.a.text
            url_extension = content.h3.a['href']

            # Get the source code off the movie's page
            new_url = url_base + url_extension
            source2 = requests.get(new_url).text
            soup2 = BeautifulSoup(source2, 'html.parser')
            cast_list = []

            soup2 = soup2.find('div', id = 'pagecontent').find('div', id = 'main_bottom')
            soup2 = soup2.find('div', id="titleCast").find('table', class_="cast_list")

            # For each cast member in the grid...
            for cast_member in soup2.find_all('tr'):
                name = cast_member.find('td', class_="")
                # Needed because sometimes there are empty entries
                if name:
                    name = name.a.text
                    name = name.strip()
                    cast_list.append(name)

            # Append to result a tuple of the title and the cast_list
            titles.append(title)
            actor_lists.append(cast_list)

    return (titles, actor_lists)

def main():
    """
    Program scrapes the IMDb top 1000 movies page for the movie's titles and
    list of cast members, then prompts the user to enter a movie title, then an actor
    from that movie, and outputs all the movies that include that actor. Users can continue
    to enter movies and actors until they choose to exit the prompt loop.

    Warning! Program is very slow, even with low number of movies (50-100)
    """

    print("Hello! Below, please enter the number of movies you want to scrape off of IMDb's " + \
          "top 1000 movies list. Please note that this number should be a multiple of 50, as " + \
          "the list is organized into pages of 50 movies each. Also note the larger the number, " + \
          "the longer the program will take.")
    print()
    movies_to_scrape = int(input("Please enter the number of movies you want to scrape: "))

    # Scrape the data off the IMDb site
    titles, actors = get_actors(movies_to_scrape)

    done = False

    # Menu Loop for find movies with a given actor in them
    while not done:
        user_in = input("Enter \'t\' to see list of titles, " + \
                        "enter title name to get actor list, enter nothing to exit: ")

        # exit
        if user_in == "":
            done = True
        # print list of titles
        elif user_in == "t":
            print(titles)
        # Enter sub-menu for actor selection
        elif user_in in titles:
            # Print the list of actors
            print(actors[titles.index(user_in)])
            actor = input("Enter a actor to find other movies with them in it: ")
            print()

            result = ""
            # Find all the other movies with that actor in them
            for actor_list in actors:
                current_title = titles[actors.index(actor_list)]
                if current_title != user_in:
                    if actor in actor_list:
                        result += current_title + '\n'

            result = result.rstrip('\n')

            # Output result
            if result != "":
                print("Here are some other movies with {} in them that you might like!".format(actor))
                print(result)
            else:
                print(("Sorry! I couldn't find any other movies with {} in them, try " + \
                      "increasing the number of movies to scrape!").format(actor))

        else:
            print("Oops! Sorry! Command or Movie not recognized!")

if __name__ == "__main__":
    main()


from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication, BasicAuthentication, TokenAuthentication
from rest_framework.permissions import AllowAny
from rest_framework import status
from notificaciones.models import NotificacionRespaldo
from notificaciones.serializers import NotificacionRespaldoSerializer
from rest_framework.response import Response

from datetime import datetime

LISTA_DIAS_DICT = {0:'LUNES',1:'MARTES',2:'MIÉRCOLES',3:'JUEVES',4:'VIERNES',5:'SÁBADO',6:'DOMINGO'}
# Create your views here.

# Obtener las notificaciones por user_tag y si fueron o no revisadas
@api_view(['GET'])
@authentication_classes([SessionAuthentication, BasicAuthentication, TokenAuthentication])
@permission_classes([AllowAny])
def notificaciones(request):
   if request.user.is_authenticated:

      print(request.GET)

      #Obtener params de un url
      user_tag = request.GET["user_tag"]

      response = []
      if "was_reviewed" in request.GET:
         fue_revisada = request.GET["was_reviewed"]
         response = NotificacionRespaldo.objects.filter(user_tag=user_tag).filter(fue_revisada=fue_revisada).distinct()
      else:
         response = NotificacionRespaldo.objects.filter(user_tag=user_tag).distinct()

      responseFinal = []
      for rsp in response:
         data_rsp = NotificacionRespaldoSerializer(rsp).data
         data_rsp['dia'] = LISTA_DIAS_DICT[data_rsp['dia']]

         if data_rsp['fecha'] is not None:
            data_rsp['fecha'] = data_rsp['fecha'].split(".")[0]
            data_rsp['fecha'] = datetime.strptime(data_rsp['fecha'], "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%d %H:%M:%S")

         responseFinal.append(data_rsp)
      return Response(responseFinal, status=status.HTTP_200_OK)

   msg = {
      'error': 'Permission Denied!'
   }
   return Response(msg, status=status.HTTP_403_FORBIDDEN)

# Actualizar la notificación
@api_view(['PUT'])
@authentication_classes([SessionAuthentication, BasicAuthentication, TokenAuthentication])
@permission_classes([AllowAny])
def notificacionUpdate(request, pk):

   #Valida que exista la relación
   if request.user.is_authenticated:
      try:
         data = NotificacionRespaldo.objects.get(pk=pk)
      except NotificacionRespaldo.DoesNotExist:
         return Response({'message': 'La notificación no existe'},status=status.HTTP_404_NOT_FOUND)

   #Actualiza el registro por pk, se puede actualizar por partes
   if request.method == 'PUT' and request.user.is_authenticated:
      requestFinal = {}
      requestFinal['fue_revisada'] = request.data['was_reviewed']
      serializer = NotificacionRespaldoSerializer(data, data=requestFinal, partial=True)
      if serializer.is_valid():
         serializer.save()
         return Response(serializer.data, status=status.HTTP_200_OK)
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

   else:
      msg = {
         'error': 'Permission Denied!'
      }
      return Response(msg, status=status.HTTP_403_FORBIDDEN)


"""
@author: dhoomakethu
"""

from setuptools import setup
from apocalypse import __version__
import platform

PSUTIL_ALPINE_LINUX = "4.1.0"

long_description = None
with (open('README.md')) as readme:
    long_description = readme.read()

def fix_ps_util(install_requires):
    for i, req in enumerate(install_requires[:]):
        if "psutil" in req:
            req = req.split("==")
            req[-1] = PSUTIL_ALPINE_LINUX
            req = "==".join(req)
            install_requires[i] = req

with open('requirements.txt') as reqs:
    install_requires = [
        line for line in reqs.read().split('\n')
        if (line and not line.startswith('--'))
    ]
    if platform.system() == "Linux":
        fix_ps_util(install_requires)

setup(name="apocalypse",
      url='https://github.com/dhoomakethu/apocalypse',
      version=__version__,
      packages=['apocalypse', 'apocalypse.utils',
                'apocalypse.chaos', 'apocalypse.app', 'apocalypse.chaos.events',
                'apocalypse.exceptions', "apocalypse.server"],
      description="Introduce chaos on to docker ecosystem",
      long_description=long_description,
      author="dhoomakethu",
      author_email="otlasanju@gmail.com",
      install_requires=install_requires,
      scripts=['doom'],
      include_package_data=True,
      # dependency_links=['https://github.com/dhoomakethu/python-coloredlogs'
      #                   '/tarball/master#egg=python-coloredlogs-5.0.1']
)


'''

https://www.codingame.com/training/easy/dungeons-and-maps

'''

import itertools
import sys

def debug(message):
    print(message, file=sys.stderr, flush=True)

def count_repetitive(items, index):
    # Count the repetition to the right of the item under index

    i = 1
    while True:
        # If the given index is the last item, the repetition is 1
        if index + 1 == len (items):
            return 1

        if items[index + i] == items[index]:
            i += 1
        else:
            return i

# Read the meta
w, h, count_x, count_y = [int(i) for i in input().split()]

debug(f"Size: {w}x{h}")
debug(f"Counts: {count_x},{count_y}")

# Store the measurements including the boundaries (0 and size) in an ascending order
x_meas = sorted([int(i) for i in input().split()] + [w] + [0])
y_meas = sorted([int(i) for i in input().split()] + [h] + [0])

# Calculate the sizes
x_sizes = sorted([(b-a) for a,b in itertools.combinations(x_meas, 2)])
y_sizes = sorted([(b-a) for a,b in itertools.combinations(y_meas, 2)])

# Getting all combinations between sizes has complexity of n^2
# so the following cannot work on case "9: Imbalance" for performance reasons
#
# # # print(sum([1 if x == y else 0 for x in x_sizes for y in y_sizes]))

squares_count = 0
i = j = 0
while True:

    # Check if i and j are still within bounds
    if (i == len(x_sizes)) or (j == len(y_sizes)):
        print(squares_count)
        exit(0)

    if x_sizes[i] == y_sizes[j]:
        # Calculate the repetitions of the matching items
        x_repetitions = count_repetitive(x_sizes, i)
        y_repetitions = count_repetitive(y_sizes, j)

        # Caclulate the squares count
        squares_count += x_repetitions * y_repetitions

        # Update the indexes accordingly
        i += x_repetitions
        j += y_repetitions

    elif x_sizes[i] < y_sizes[j]:
        # Increase the index of the smallest item
        i += 1

    elif x_sizes[i] > y_sizes[j]:
        # Increase the index of the smallest item
        j += 1


from flask import Flask
from flask_restplus import Api

from main.view.api import register_api

api = Api()

def create_app(name=None, _config=None):
    app = Flask(name)

    api.init_app(app)

    register_api(app)

    return app

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5050, debug=True)


#Copy

import time
import serial
import string
import socket
from threading import Thread

#time.sleep(25)

#Function to read data from Wi-Fi and send it to serial port.

def Read_from_Wifi_Ser_Write():
    while True:
        data_wifi = s.recv(buffer_size)         # 1024 is the buffer size
        print('data from wifi')
        print(data_wifi)
        ser.write(data_wifi)

#Funtion to read data from Serial Port and sends it to Wi-Fi

def Ser_Read_Send_to_Wifi():
    data_serial = ser.readline()
    print('data from serial',data_serial)
    s.send(data_serial)

print('Starting program')

#serial configuration

ser = serial.Serial('/dev/ttyS0', baudrate=115200,
                    parity=serial.PARITY_NONE,
                    stopbits=serial.STOPBITS_ONE,
                    bytesize=serial.EIGHTBITS
                    )
time.sleep(1)

HOST = "192.168.4.1"
PORT = 4002
buffer_size = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((HOST,PORT))

try:
    print('Starting program')
    ser.write('Hello World\r\n')
    ser.write('Serial Communication Using Raspberry Pi\r\n')
    ser.write('BCube (Pvt).Ltd \r\n')

    Thread(target = Read_from_Wifi_Ser_Write).start()

    while True:

        Ser_Read_Send_to_Wifi()

    ser.close()
    s.close()

except KeyboardInterrupt:
    print('Exiting Program')

except:
    print('Error Occurs, Exiting Program')

finally:
    ser.close()
    s.close()
    pass


from flask import Flask,Response,jsonify
from numpy import object_
from soup import title_check
from preferItem import prefer
import redis
from flask_restful import Api, Resource
import pandas as pd

import json
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

#app = Flask(__name__)
api = Api(app)
# flask의 화면을 띄우기
@app.route("/")
def nginx():
    app.logger.debug('debug')
    return 'hello! nginx'

@app.route('/tospring')
def hello():
    t=[]
    for i,title in enumerate(title_check()):
        t.append({'id':i,'title':title.decode('utf-8')})
    print(t)
    json_str = json.dumps(t,ensure_ascii=False)

    return  Response(json_str, content_type='application/json; charset=utf-8')

# 공지사항
@app.route('/Notices', methods=['GET'])
def get_titles():
    Title=[]
    title_dict = {}
    for i,title in enumerate(title_check()):
        Title.append({'id':i,'title':title.decode('utf-8')})
    print(Title)
    title_dict["Notices"] = Title

    return jsonify(title_dict)

@app.route('/Notices/<int:id>', methods=['GET'])
def get_title(id):
    Title=[]
    title_dict = {}
    for i,title in enumerate(title_check()):
        Title.append({'id':i,'title':title.decode('utf-8')})
    print(Title)
    title_dict["Notices"] = Title
    for item in title_dict():
        return item["Noices"][id]

    return jsonify({"message": " not found "})

# Announce page
@app.route('/Announces', methods=['GET'])
def get_Announces():
    decoded_data = {}
    redis_client = redis.Redis(host='127.0.0.1', port=6379, db=0)
    stored_data = redis_client.get('Announce')
    stored_data = stored_data.decode('utf-8')
    result = json.loads(stored_data)
    #decoded_data["ann"] = stored_data
    print(stored_data)
    return result
@app.route('/Announces/<int:id>', methods=['GET'])
def get_Announce(id):
    decoded_data = {}
    redis_client = redis.Redis(host='127.0.0.1', port=6379, db=0)
    stored_data = redis_client.get('Announce')
    stored_data = stored_data.decode('utf-8')
    result = json.loads(stored_data)
    for item in result:
        return result['announce'][id]
    return {"message": " not found "}

@app.route('/preferItem/<int:id>', methods=['GET'])
def preferDates(id):
    prefer_dict = {1:"라면류",2:"쌀",3:"밀가루",4:"고추장",5:"된장",6:"참기름",
               7:"가공햄류",8:"식용유",9:"통조림류",10:"설탕류",11:"간장류",12:"소면류",
               13:"김",14:"즉석밥",15:"샴푸",16:"치약",17:"비누"}
    prefer_itemsTotal = json.loads(prefer(id).encode('utf-8'))
    title__ = list(prefer_itemsTotal.keys())
    value = list(prefer_itemsTotal.values())
    preferItem_title = []
    preferItem_value = []
    prefer_top ={}
    for i in range(0,len(title__)):
        print(prefer_dict[int(title__[i])])   # 부족한 물품
        preferItem_title.append(prefer_dict[int(title__[i])])
        preferItem_value.append(int(value[i]))
    prefer_top['prefer_title'] = preferItem_title
    prefer_top['prefer_value'] = preferItem_value
    return jsonify(prefer_top)

@app.route('/preferItem/top3/<int:id>', methods=['GET'])
def preferDate(id):
    prefer_dict = {1:"라면류",2:"쌀",3:"밀가루",4:"고추장",5:"된장",6:"참기름",
               7:"가공햄류",8:"식용유",9:"통조림류",10:"설탕류",11:"간장류",12:"소면류",
               13:"김",14:"즉석밥",15:"샴푸",16:"치약",17:"비누"}
    prefer_itemsTotal = json.loads(prefer(id).encode('utf-8'))
    preferItem_list = []
    prefer_top ={}
    top3 = list(prefer_itemsTotal.keys())
    for i in range(0,3):
        print(prefer_dict[int(top3[i])])   # 부족한 물품
        preferItem_list.append(prefer_dict[int(top3[i])])
    prefer_top['top_three'] = preferItem_list
    return jsonify(prefer_top)

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0', port='5000', unix_sock='/home/jiyeong/flaskAPI/flaskAPI.sock' )


import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

driver=None

@pytest.fixture(scope='module')
def init_driver():
    global driver
    print("========hey init===========")
    serv_obj=Service("/home/s/Downloads/chromedriver_linux64/chromedriver")
    driver = webdriver.Chrome(service=serv_obj)
    driver.implicitly_wait(10)
    driver.delete_all_cookies()
    driver.get("https://www.google.com")
    yield
    print("======teardown======")
    driver.quit()

# @pytest.mark.usefixtures(init_driver)
def test_google_title(init_driver):
    assert driver.title == "Google"

#@pytest.mark.usefixtures(init_driver)
def test_curr_url(init_driver):
    assert driver.current_url == "https://www.google.com/"


import pygame
import random
(width, height) = (300, 300)
screen = pygame.display.set_mode((width, height))

def gen():

    start = (10,10)
    end = (290,290)
    list = [(start)]
    newstart = (10,10)
    while True:

        x = random.randrange(newstart[0],end[0])
        y = random.randrange(newstart[1],end[1])

        x = round(x/10)*10
        y = round(y/10)*10

        newstart = (x,y)
        list.append((x,y))

        if newstart[0] > 280 or newstart[1] > 280:
            list.append((290,290))
            break

    return list

def mazegen(width, height):

    interval = 20
    stage = 20
    while True:

        y = random.randrange(0, height-10)

        pygame.draw.line(screen, (0,0,0), (stage, 0), (stage, y), 5)
        y += 20
        pygame.draw.line(screen, (0,0,0), (stage, y), (stage, width) , 5)
        stage += 20

        if stage == 300:
            break


import numpy as np
import cv2

'''
from sys import version_info
import re

def checkLines( gridLines ):
    "This checks the lines' validity"
    print("----------Checking lines...") if option == True else 0
    check = True
    for line in gridLines:
        if line.count('X') > 0:
           print("Line {} is not complete.".format(gridLines.index(line) + 1)) if option == True else 0
           check = "NC"
        for nbr in range(1, 10):
            if (line.count(str(nbr)) > 1):
                print("Several occurences of {} in line {}.".format(nbr, gridLines.index(line) + 1)) if option == True else 0
                check = False
    if check == True and type(check) == type(True):
        print("Lines are valid.") if option == True else 0
    print("----------Lines checked.") if option == True else 0
    return check

def checkColumns( gridColumns ):
    "This checks the columns' validity"
    print("----------Checking columns...") if option == True else 0
    check = True
    for column in gridColumns:
        if column.count('X') > 0:
            print("Column {} is not complete.".format(gridColumns.index(column) + 1)) if option == True else 0
            check = "NC"
        for nbr in range(1, 10):
            if (column.count(str(nbr)) > 1):
                print("Several occurences of {} in column {}.".format(nbr, gridColumns.index(column) + 1)) if option == True else 0
                check = False
    if check == True and type(check) == type(True):
        print("Columns are valid.") if option == True else 0
    print("----------Columns checked.") if option == True else 0
    return check

def checkSquares( gridSquares ):
    "This checks the squares' validity"
    check = True
    print("----------Checking squares...") if option == True else 0
    for square in gridSquares:
        if square.count('X') > 0:
            print("Square {} is not complete.".format(gridSquares.index(square) + 1)) if option == True else 0
            check = "NC"
        for nbr in range(1, 10):
            if square.count(str(nbr)) > 1:
                print("Several occurences of {} in square {}.".format(nbr, gridSquares.index(square) + 1)) if option == True else 0
                check = False
    if check == True and type(check) == type(True):
        print("Squares are valid.") if option == True else 0
    print("----------Squares checked.") if option == True else 0
    return check

def getGridLines( grid ):
    return grid.split("\n")

def getGridColumns( gridLines ):
    gridColumns = []
    for i in range(0,9):
        toAppend = []
        for j in range(0, 9):
            toAppend.append(gridLines[j][i])
        gridColumns.append(toAppend)
    return gridColumns

def getGridSquares( gridLines ):
    gridSquares = []
    for y in range(0, 9, 3):
        for x in range(0, 9, 3):
            toAppend = []
            for j in range(0, 3):
                for i in range(0, 3):
                    toAppend.append(gridLines[y + j][x + i])
            gridSquares.append(toAppend)
    return gridSquares

def checkGrid():
    "This checks the grid's validity"
    gridLines = getGridLines(grid)
    gridColumns = getGridColumns(gridLines)
    gridSquares = getGridSquares(gridLines)
    print("-----Checking grid") if option == True else 0
    checkL = checkLines(gridLines)
    checkC = checkColumns(gridColumns)
    checkS = checkSquares(gridSquares)
    check = checkL and checkC and checkS
    return check

def solveGrid( index ):
    "This solves the grid recursively"

def getGridCases():
    "Fills the grid with case objects"

class Case:
    "Class for a grid's case"

    def __init__(self, content='X', modify=True):
        self.content = content
        self.modify = modify

    def nextNumber():
        if self.modify:
            if self.content == 'X':
                self.content = '1'
            elif int(self.content) < 9:
                self.content = str(int(self.content) + 1)

    def reset():
        if self.modfy:
            self.content = 'X'

sudokuFile = input("Please enter your grid's name (must be a .txt, do not enter the extension though): ")
option = input("Do you want to see the output of each grid check ? (yes/[no])")
option = True if option == "yes" else False
print("-----Opening {}.".format(sudokuFile))
with open("E:\\Code\\Python\\Sudoku Solver\\{}.txt".format(sudokuFile), 'r') as f:
    print("-----Reading {}.".format(sudokuFile))
    grid = f.read()
    print("-----Closing {}.".format(sudokuFile))
#grid = getGridCases()
#solveGrid(0)
print(grid[9])
'''
## Solve Every Sudoku Puzzle

## See http://norvig.com/sudoku.html

## Throughout this program we have:
##   r is a row,    e.g. 'A'
##   c is a column, e.g. '3'
##   s is a square, e.g. 'A3'
##   d is a digit,  e.g. '9'
##   u is a unit,   e.g. ['A1','B1','C1','D1','E1','F1','G1','H1','I1']
##   grid is a grid,e.g. 81 non-blank chars, e.g. starting with '.18...7...
##   values is a dict of possible values, e.g. {'A1':'12349', 'A2':'8', ...}

def cross(A, B):
    "Cross product of elements in A and elements in B."
    return [a+b for a in A for b in B]

digits   = '123456789'
rows     = 'ABCDEFGHI'
cols     = digits
squares  = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
            [cross(r, cols) for r in rows] +
            [cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs in ('123','456','789')])
units = dict((s, [u for u in unitlist if s in u])
             for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s]))
             for s in squares)

################ Unit Tests ################

def test():
    "A set of tests that must pass."
    assert len(squares) == 81
    assert len(unitlist) == 27
    assert all(len(units[s]) == 3 for s in squares)
    assert all(len(peers[s]) == 20 for s in squares)
    assert units['C2'] == [['A2', 'B2', 'C2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2'],
                           ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9'],
                           ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']]
    assert peers['C2'] == set(['A2', 'B2', 'D2', 'E2', 'F2', 'G2', 'H2', 'I2',
                               'C1', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9',
                               'A1', 'A3', 'B1', 'B3'])
    print('All tests pass.')

################ Parse a Grid ################

def parse_grid(grid):
    """Convert grid to a dict of possible values, {square: digits}, or
    return False if a contradiction is detected."""
    ## To start, every square can be any digit; then assign values from the grid.
    values = dict((s, digits) for s in squares)
    for s,d in grid_values(grid).items():
        if d in digits and not assign(values, s, d):
            return False ## (Fail if we can't assign d to square s.)
    return values

def grid_values(grid):
    "Convert grid into a dict of {square: char} with '0' or '.' for empties."
    chars = [c for c in grid if c in digits or c in '0.']
    assert len(chars) == 81
    return dict(zip(squares, chars))

################ Constraint Propagation ################

def assign(values, s, d):
    """Eliminate all the other values (except d) from values[s] and propagate.
    Return values, except return False if a contradiction is detected."""
    other_values = values[s].replace(d, '')
    if all(eliminate(values, s, d2) for d2 in other_values):
        return values
    else:
        return False

def eliminate(values, s, d):
    """Eliminate d from values[s]; propagate when values or places <= 2.
    Return values, except return False if a contradiction is detected."""
    if d not in values[s]:
        return values ## Already eliminated
    values[s] = values[s].replace(d,'')
    ## (1) If a square s is reduced to one value d2, then eliminate d2 from the peers.
    if len(values[s]) == 0:
        return False ## Contradiction: removed last value
    elif len(values[s]) == 1:
        d2 = values[s]
        if not all(eliminate(values, s2, d2) for s2 in peers[s]):
            return False
    ## (2) If a unit u is reduced to only one place for a value d, then put it there.
    for u in units[s]:
        dplaces = [s for s in u if d in values[s]]
        if len(dplaces) == 0:
            return False ## Contradiction: no place for this value
        elif len(dplaces) == 1:
            # d can only be in one place in unit; assign it there
            if not assign(values, dplaces[0], d):
                return False
    return values

################ Display as 2-D grid ################

def display(values):
    "Display these values as a 2-D grid."
    width = 1+max(len(values[s]) for s in squares)
    line = '+'.join(['-'*(width*3)]*3)
    for r in rows:
        print(''.join(values[r+c].center(width)+('|' if c in '36' else '')
                      for c in cols))
        if r in 'CF': print(line)
    print

################ Search ################

def solve(grid): return search(parse_grid(grid))

def search(values):
    "Using depth-first search and propagation, try all possible values."
    if values is False:
        return False ## Failed earlier
    if all(len(values[s]) == 1 for s in squares):
        return values ## Solved!
    ## Chose the unfilled square s with the fewest possibilities
    n,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
    return some(search(assign(values.copy(), s, d))
                for d in values[s])

################ Utilities ################

def some(seq):
    "Return some element of seq that is true."
    for e in seq:
        if e: return e
    return False

def from_file(filename, sep='\n'):
    "Parse a file into a list of strings, separated by sep."
    return open(filename).read().strip().split(sep)#file(filename).read().strip().split(sep)

def shuffled(seq):
    "Return a randomly shuffled copy of the input sequence."
    seq = list(seq)
    random.shuffle(seq)
    return seq

################ System test ################

import time, random

def solve_all(grids, name='', showif=0.0):
    """Attempt to solve a sequence of grids. Report results.
    When showif is a number of seconds, display puzzles that take longer.
    When showif is None, don't display any puzzles."""
    def time_solve(grid):
        start = time.clock()
        values = solve(grid)
        t = time.clock()-start
        ## Display puzzles that take long enough
        if showif is not None and t > showif:
            display(grid_values(grid))
            if values: display(values)
            print('(%.2f seconds)\n' % t)
        return (t, solved(values))
    times, results = zip(*[time_solve(grid) for grid in grids])
    N = len(grids)
    if N > 1:
        print("Solved %d of %d %s puzzles (avg %.2f secs (%d Hz), max %.2f secs)." % (
            sum(results), N, name, sum(times)/N, N/sum(times), max(times)))

def solved(values):
    "A puzzle is solved if each unit is a permutation of the digits 1 to 9."
    def unitsolved(unit): return set(values[s] for s in unit) == set(digits)
    return values is not False and all(unitsolved(unit) for unit in unitlist)

def random_puzzle(N=17):
    """Make a random puzzle with N or more assignments. Restart on contradictions.
    Note the resulting puzzle is not guaranteed to be solvable, but empirically
    about 99.8% of them are solvable. Some have multiple solutions."""
    values = dict((s, digits) for s in squares)
    for s in shuffled(squares):
        if not assign(values, s, random.choice(values[s])):
            break
        ds = [values[s] for s in squares if len(values[s]) == 1]
        if len(ds) >= N and len(set(ds)) >= 8:
            return ''.join(values[s] if len(values[s])==1 else '.' for s in squares)
    return random_puzzle(N) ## Give up and make a new puzzle

def disp_cam():
    cap = cv2.VideoCapture(0)
    cap.set(3, 1600)
    cap.set(4, 1200)
    cap.set(15, -8.0)
    time.sleep(2)
    while(cap.isOpened()):
        ret, frame = cap.read()
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('frame',gray)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

#grid1  = '003020600900305001001806400008102900700000008006708200002609500800203009005010300'
#grid2  = '4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......'
#hard1  = '.....6....59.....82....8....45........3........6..3.54...325..6..................'

'''if __name__ == '__main__':
    test()
    #solve_all(from_file("easy50.txt", '========'), "easy", None)
    solve_all(from_file("top95.txt"), "hard", None)
    solve_all(from_file("hardest.txt"), "hardest", None)
    solve_all([random_puzzle() for _ in range(99)], "random", 100.0)'''

## References used:
## http://www.scanraid.com/BasicStrategies.htm
## http://www.sudokudragon.com/sudokustrategy.htm
## http://www.krazydad.com/blog/2005/09/29/an-index-of-sudoku-strategies/
## http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/python/sudoku/


import os
import numpy as np
import torch
from torch.utils.data import Dataset
from ..utils.laserscan import LaserScan, SemLaserScan

EXTENSIONS_SCAN = ['.bin']
EXTENSIONS_EDGE = ['.png']
EXTENSIONS_LABEL = ['.label']

def is_scan(filename):
  return any(filename.endswith(ext) for ext in EXTENSIONS_SCAN)

def is_edge(filename):
  return any(filename.endswith(ext) for ext in EXTENSIONS_EDGE)

def is_label(filename):
  return any(filename.endswith(ext) for ext in EXTENSIONS_LABEL)

class SemanticKitti(Dataset):

  def __init__(self, root,    # directory where data is
               sequences,     # sequences for this data (e.g. [1,3,4,6])
               labels,        # label dict: (e.g 10: "car")
               color_map,     # colors dict bgr (e.g 10: [255, 0, 0])
               learning_map,  # classes to learn (0 to N-1 for xentropy)
               learning_map_inv,    # inverse of previous (recover labels)
               sensor,              # sensor to parse scans from
               max_points=150000,   # max number of points present in dataset
               gt=True, skip=0):            # send ground truth?
    # save deats
    self.root = os.path.join(root, "sequences")
    self.sequences = sequences
    self.labels = labels
    self.color_map = color_map
    self.learning_map = learning_map
    self.learning_map_inv = learning_map_inv
    self.sensor = sensor
    self.sensor_img_H = sensor["img_prop"]["height"]
    self.sensor_img_W = sensor["img_prop"]["width"]
    self.sensor_img_means = torch.tensor(sensor["img_means"],
                                         dtype=torch.float)
    self.sensor_img_stds = torch.tensor(sensor["img_stds"],
                                        dtype=torch.float)
    self.sensor_fov_up = sensor["fov_up"]
    self.sensor_fov_down = sensor["fov_down"]
    self.max_points = max_points
    self.gt = gt

    # get number of classes (can't be len(self.learning_map) because there
    # are multiple repeated entries, so the number that matters is how many
    # there are for the xentropy)
    self.nclasses = len(self.learning_map_inv)

    # sanity checks

    # make sure directory exists
    if os.path.isdir(self.root):
      print("Sequences folder exists! Using sequences from %s" % self.root)
    else:
      raise ValueError("Sequences folder doesn't exist! Exiting...")

    # make sure labels is a dict
    assert(isinstance(self.labels, dict))

    # make sure color_map is a dict
    assert(isinstance(self.color_map, dict))

    # make sure learning_map is a dict
    assert(isinstance(self.learning_map, dict))

    # make sure sequences is a list
    assert(isinstance(self.sequences, list))

    # placeholder for filenames
    self.scan_files = []
    self.edge_files = []
    self.label_files = []

    # fill in with names, checking that all sequences are complete
    for seq in self.sequences:
      # to string
      seq = '{0:02d}'.format(int(seq))

      print("parsing seq {}".format(seq))

      # get paths for each
      scan_path = os.path.join(self.root, seq, "velodyne")
      edge_path = os.path.join(self.root, seq, "edges")
      label_path = os.path.join(self.root, seq, "labels")

      # get files
      scan_files = [os.path.join(dp, f) for dp, dn, fn in os.walk(
          os.path.expanduser(scan_path)) for f in fn if is_scan(f)]
      edge_files = [os.path.join(dp, f) for dp, dn, fn in os.walk(
          os.path.expanduser(edge_path)) for f in fn if is_edge(f)]
      label_files = [os.path.join(dp, f) for dp, dn, fn in os.walk(
          os.path.expanduser(label_path)) for f in fn if is_label(f)]

      assert(len(scan_files) == len(edge_files))

      # check all scans have labels
      if self.gt:
        assert(len(scan_files) == len(label_files))

      # extend list
      self.scan_files.extend(scan_files)
      self.edge_files.extend(edge_files)
      self.label_files.extend(label_files)

    # sort for correspondance
    self.scan_files.sort()
    self.edge_files.sort()
    self.label_files.sort()

    if skip != 0:
        self.scan_files = self.scan_files[::skip]
        self.edge_files = self.edge_files[::skip]
        self.label_files = self.label_files[::skip]

    print("Using {} scans from sequences {}".format(len(self.scan_files),
                                                    self.sequences))

  def __getitem__(self, index):
    # get item in tensor shape
    scan_file = self.scan_files[index]
    edge_file = self.edge_files[index]
    if self.gt:
      label_file = self.label_files[index]

    # open a semantic laserscan
    if self.gt:
      scan = SemLaserScan(self.color_map,
                          project=True,
                          H=self.sensor_img_H,
                          W=self.sensor_img_W,
                          fov_up=self.sensor_fov_up,
                          fov_down=self.sensor_fov_down)
    else:
      scan = LaserScan(project=True,
                       H=self.sensor_img_H,
                       W=self.sensor_img_W,
                       fov_up=self.sensor_fov_up,
                       fov_down=self.sensor_fov_down)

    # open and obtain scan
    scan.open_scan(scan_file)
    scan.open_edge(edge_file)
    scan.open_edge(edge_file)
    if self.gt:
      scan.open_label(label_file)
      # map unused classes to used classes (also for projection)
      scan.sem_label = self.map(scan.sem_label, self.learning_map)
      scan.proj_sem_label = self.map(scan.proj_sem_label, self.learning_map)

    # make a tensor of the uncompressed data (with the max num points)
    unproj_n_points = scan.points.shape[0]
    unproj_xyz = torch.full((self.max_points, 3), -1.0, dtype=torch.float)
    unproj_xyz[:unproj_n_points] = torch.from_numpy(scan.points)
    unproj_range = torch.full([self.max_points], -1.0, dtype=torch.float)
    unproj_range[:unproj_n_points] = torch.from_numpy(scan.unproj_range)
    unproj_remissions = torch.full([self.max_points], -1.0, dtype=torch.float)
    unproj_remissions[:unproj_n_points] = torch.from_numpy(scan.remissions)
    if self.gt:
      unproj_labels = torch.full([self.max_points], -1.0, dtype=torch.int32)
      unproj_labels[:unproj_n_points] = torch.from_numpy(scan.sem_label)
    else:
      unproj_labels = []

    # get points and labels
    proj_range = torch.from_numpy(scan.proj_range).clone()
    proj_xyz = torch.from_numpy(scan.proj_xyz).clone()
    proj_remission = torch.from_numpy(scan.proj_remission).clone()
    proj_mask = torch.from_numpy(scan.proj_mask)
    if self.gt:
      proj_labels = torch.from_numpy(scan.proj_sem_label).clone()
      proj_labels = proj_labels * proj_mask
    else:
      proj_labels = []
    proj_x = torch.full([self.max_points], -1, dtype=torch.long)
    proj_x[:unproj_n_points] = torch.from_numpy(scan.proj_x)
    proj_y = torch.full([self.max_points], -1, dtype=torch.long)
    proj_y[:unproj_n_points] = torch.from_numpy(scan.proj_y)
    proj = torch.cat([proj_range.unsqueeze(0).clone(),
                      proj_xyz.clone().permute(2, 0, 1),
                      proj_remission.unsqueeze(0).clone()])
    proj = (proj - self.sensor_img_means[:, None, None]
            ) / self.sensor_img_stds[:, None, None]
    proj = proj * proj_mask.float()

    # get name and sequence
    path_norm = os.path.normpath(scan_file)
    path_split = path_norm.split(os.sep)
    path_seq = path_split[-3]
    path_name = path_split[-1].replace(".bin", ".label")
    # print("path_norm: ", path_norm)
    # print("path_seq", path_seq)
    # print("path_name", path_name)

    # return
    return proj, proj_mask, proj_labels, unproj_labels, path_seq, path_name, proj_x, proj_y, proj_range, unproj_range, proj_xyz, unproj_xyz, proj_remission, unproj_remissions, unproj_n_points, scan.edge

  def __len__(self):
    return len(self.scan_files)

  @staticmethod
  def map(label, mapdict):
    # put label from original values to xentropy
    # or vice-versa, depending on dictionary values
    # make learning map a lookup table
    maxkey = 0
    for key, data in mapdict.items():
      if isinstance(data, list):
        nel = len(data)
      else:
        nel = 1
      if key > maxkey:
        maxkey = key
    # +100 hack making lut bigger just in case there are unknown labels
    if nel > 1:
      lut = np.zeros((maxkey + 100, nel), dtype=np.int32)
    else:
      lut = np.zeros((maxkey + 100), dtype=np.int32)
    for key, data in mapdict.items():
      try:
        lut[key] = data
      except IndexError:
        print("Wrong key ", key)
    # do the mapping
    return lut[label]


from colorfield.fields import ColorField
from django.conf import settings
from django.core.validators import MinValueValidator
from django.db import models

from users.models import User

class Tag(models.Model):
    """Модель тега."""

    name = models.CharField(
        verbose_name='Наименование тега',
        unique=True,
        max_length=settings.NAME_MAX_LENGHT,
        blank=False,
    )
    color = ColorField(
        verbose_name='Цвет тега',
        unique=True,
    )
    slug = models.SlugField(
        'slug',
        max_length=settings.SHORT_FIELD_MAX_LENGHT,
        unique=True,
        blank=False,
        db_index=True
    )

    class Meta:
        verbose_name = 'Тег'
        verbose_name_plural = 'Теги'
        ordering = ('name',)

    def __str__(self) -> str:
        return f'{self.name}'

class Ingredient(models.Model):
    """Модель ингредиента."""

    name = models.CharField(
        verbose_name='Наименование ингредиента',
        unique=True,
        max_length=settings.NAME_MAX_LENGHT,
        blank=False,
    )
    measurement_unit = models.CharField(
        verbose_name='Единица измерения ингредиента',
        max_length=settings.SHORT_FIELD_MAX_LENGHT,
        blank=False
    )

    class Meta:
        verbose_name = 'Ингредиент'
        verbose_name_plural = 'Ингредиенты'
        ordering = ('name',)
        constraints = [
            models.UniqueConstraint(
                fields=['name', 'measurement_unit'],
                name='unique_ingredient_with_unit'
            )
        ]

    def __str__(self) -> str:
        return f'{self.name}'

class Recipe(models.Model):
    """Модель рецепта."""

    author = models.ForeignKey(
        User,
        related_name='recipes',
        verbose_name='Автор рецепта',
        on_delete=models.CASCADE,
        null=False,
        blank=False,
        default=0,
    )
    name = models.CharField(
        verbose_name='Наименование рецепта',
        max_length=settings.RECIPE_NAME_MAX_LENGHT,
        blank=False,
        unique=True
    )
    image = models.ImageField(
        verbose_name='Изображение рецепта',
        upload_to='recipes/images/',
        null=False,
        blank=False,
        default=None
    )
    pub_date = models.DateTimeField(
        verbose_name='Дата публикации',
        auto_now_add=True,
        editable=False,
    )
    text = models.TextField(
        verbose_name='Описание рецепта',
        null=False,
        blank=False,
    )
    ingredients = models.ManyToManyField(
        Ingredient,
        through='IngredientRecipe',
        verbose_name='Ингредиенты рецепта',
        related_name='recipes',
    )
    tags = models.ManyToManyField(
        Tag,
        through='TagRecipe',
        verbose_name='Теги рецепта',
        related_name='recipes',
    )
    cooking_time = models.PositiveSmallIntegerField(
        verbose_name='Время готовки рецепта',
        null=False,
        blank=False,
        default=settings.MIN_AMOUNT,
        validators=(
            MinValueValidator(
                settings.MIN_AMOUNT,
                message=(f'"Время готовки рецепта" не может быть '
                         f'меньше {settings.MIN_AMOUNT}')
            ),
        ),
    )

    class Meta:
        verbose_name = 'Рецепт'
        verbose_name_plural = 'Рецепты'
        ordering = ("-pub_date",)

    def __str__(self) -> str:
        return f'{self.name}'

class IngredientRecipe(models.Model):
    """Промежуточная сущность между моделями рецептов и ингредиентов."""

    ingredient = models.ForeignKey(
        Ingredient,
        verbose_name='Ингредиент',
        on_delete=models.PROTECT,
    )
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
    amount = models.PositiveSmallIntegerField(
        verbose_name='Количество',
        null=False,
        blank=False,
        default=settings.MIN_AMOUNT,
        validators=(
            MinValueValidator(
                settings.MIN_AMOUNT,
                message=(f'"Количество" не может быть '
                         f'меньше {settings.MIN_AMOUNT}')
            ),
        ),
    )

    class Meta:
        verbose_name = 'Ингридиент'
        verbose_name_plural = 'Количество ингридиентов'
        ordering = ('recipe',)
        constraints = [
            models.UniqueConstraint(
                fields=['ingredient', 'recipe'],
                name='unique_ingredient_with_recipe'
            )
        ]

    def __str__(self) -> str:
        return f'{self.ingredient}: {self.recipe}'

class TagRecipe(models.Model):
    """Промежуточная сущность между моделями рецептов и тегов."""

    tag = models.ForeignKey(
        Tag,
        verbose_name='Тег',
        on_delete=models.PROTECT,
    )
    recipe = models.ForeignKey(
        Recipe,
        on_delete=models.CASCADE
    )

    def __str__(self) -> str:
        return f'{self.tag}: {self.recipe}'

class BaseListModel(models.Model):
    """Базовая модель для привязки пользователя и рецепта."""

    user = models.ForeignKey(
        User,
        verbose_name='Пользователь',
        related_name='%(class)ss',
        on_delete=models.CASCADE,
    )
    recipe = models.ForeignKey(
        Recipe,
        verbose_name='Рецепт',
        related_name='in_%(class)ss',
        on_delete=models.CASCADE,
    )

    class Meta:
        abstract = True

    def __str__(self) -> str:
        return f'{self.user.username}: {self.recipe.name}'

class Favorite(BaseListModel):
    """Модель избранных рецептов."""

    class Meta:
        verbose_name = 'Избранное'
        verbose_name_plural = 'Избранные'
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'recipe'], name='unique_favorites'
            )
        ]

class Cart(BaseListModel):
    """Модель списка покупок."""

    class Meta:
        verbose_name = 'Список покупок'
        verbose_name_plural = 'Список покупок'
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'recipe'], name='unique_cart'
            )
        ]


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

from django.db import migrations, models
import datetime

class Migration(migrations.Migration):

    dependencies = [
        ('cpovc_forms', '0022_auto_20190712_1904'),
    ]

    operations = [
        migrations.RenameField(
            model_name='ovchivmanagement',
            old_name='Substitution_FirstLine_ARV',
            new_name='substitution_firstline_arv',
        ),
        migrations.RenameField(
            model_name='ovchivmanagement',
            old_name='Support_group_Enrollment',
            new_name='support_group_enrollment',
        ),
        migrations.AlterField(
            model_name='ovchivmanagement',
            name='substitution_firstline_date',
            field=models.DateTimeField(default=datetime.datetime(2019, 7, 19, 12, 9, 36, 765622)),
        ),
        migrations.AlterField(
            model_name='ovchivriskscreening',
            name='art_referral_completed_date',
            field=models.DateTimeField(default=datetime.datetime(2019, 7, 19, 12, 9, 36, 764614), null=True),
        ),
        migrations.AlterField(
            model_name='ovchivriskscreening',
            name='art_referral_date',
            field=models.DateTimeField(default=datetime.datetime(2019, 7, 19, 12, 9, 36, 764574), null=True),
        ),
        migrations.AlterField(
            model_name='ovchivriskscreening',
            name='date_of_event',
            field=models.DateField(default=datetime.datetime(2019, 7, 19, 12, 9, 36, 764681), null=True),
        ),
        migrations.AlterField(
            model_name='ovchivriskscreening',
            name='referral_made_date',
            field=models.DateTimeField(default=datetime.datetime(2019, 7, 19, 12, 9, 36, 764498), null=True),
        ),
    ]


#!/usr/bin/env python
import random

import numpy as np

import lib

np.set_printoptions(formatter={'int': lib.color_sign})

log = lib.log_c()

MAP_SIZE = 3 # grid size nxn
NUM_SHIPS = 3
RANDOM_SEED = 42

P1_HITS = 0
P2_HITS = 0

def set_player_board(grid):
    '''
    iterate NUM_SHIPS times to get the coords of the user, it will print
    the board every time the user enters a coord with the ship already
    in place.

    :params: grid of MAP_SIZE by MAP_SIZE, dtype int

    :returns: grid with numbers updated
    '''
    i = 1
    while True:
        if i > NUM_SHIPS:
            break

        log.separator('-')

        log.info(f'coords for your {i} ship')
        print(grid)

        x = input('x: ')
        y = input('y: ')

        if not validate_coords(x, y):
            continue

        x = int(x)
        y = int(y)

        if grid[x][y] != 0:
            log.error('bad coords, already have a ship there try again')
            continue

        grid[x][y] = 1

        i += 1

    return grid

def set_computer_board(grid):
    log.info('setting computer board')
    i = 1
    while True:
        if i > NUM_SHIPS:
            break
        x = random.randint(0, MAP_SIZE - 1)
        y = random.randint(0, MAP_SIZE - 1)
        if grid[x][y] != 0:
            continue
        grid[x][y] = 1

        i += 1

    log.good('done')
    return grid

def guess(guess_grid, player_grid):
    while True:
        x = input('x: ')
        y = input('y: ')
        if validate_coords(x, y):
            break

    x = int(x)
    y = int(y)

    if player_grid[x][y] == 1:
        log.good('hit')
        guess_grid[x][y] = 8
        return guess_grid

    guess_grid[x][y] = 6
    return guess_grid

def computer_turn(level, player_grid):
    #if level == 'dumb':
    while True:
        x = random.randint(0, MAP_SIZE - 1)
        y = random.randint(0, MAP_SIZE - 1)

        if player_grid[x][y] != 6 and player_grid[x][y] != 8:
            break

    if player_grid[x][y] == 1:
        log.good('hit')
        player_grid[x][y] = 8
        return player_grid

    player_grid[x][y] = 6
    return player_grid

def validate_coords(x, y):
    try:
        x = int(x)
        y = int(y)
    except ValueError:
        log.error('bad coords, try again')
        return False

    if x > MAP_SIZE - 1 or y > MAP_SIZE - 1:
        log.error('bad coords, try again')
        return False

    if x < 0 or y < 0 :
        log.error('bad coords, try again')
        return False

    return True

def game():
    # setting up everything
    p1_board = np.zeros([MAP_SIZE, MAP_SIZE], dtype = int)
    p2_board = np.zeros([MAP_SIZE, MAP_SIZE], dtype = int)

    p1_board = set_player_board(p1_board)
    log.separator('=')
    p2_board = set_computer_board(p2_board)
    log.separator('=')

    p1_guess = np.zeros([MAP_SIZE, MAP_SIZE], dtype = int)

    log.info('game starting')
    log.separator('=')

    turn = 1
    while True:
        log.separator('=')
        log.info(f'turn {turn}')
        print(p1_guess)
        log.separator('-')
        print(p1_board)

        p1_guess = guess(p1_guess, p2_board)
        p1_board = computer_turn('dumb', p1_board)

        turn += 1

game()


from pytorch_lightning import Trainer
from pytorch_lightning.loggers import TensorBoardLogger
from pytorch_lightning.callbacks import (
    ModelCheckpoint,
    LearningRateMonitor
)

from src.pl_models import NormalModel
from src.config import base_config

if __name__ == "__main__":
    epochs = 200
    lr = 0.1
    cutout = True
    auto_augment = True
    batch_size = 256
    network = "resnet34"
    datamodule_name = "cifar100"
    gradient_clip_val = None

    finetune_model = NormalModel(
        network=network,
        epochs=epochs,
        lr=lr,
        datamodule_name=datamodule_name,
        cutout=cutout,
        auto_augment=auto_augment,
        batch_size=batch_size
    )

    checkpoint_dir_path = (
        base_config.checkpoints_dir_path /
        f"{finetune_model.name}"
    )

    every_epoch_callback = ModelCheckpoint(
        dirpath=checkpoint_dir_path,
        filename=f"normal-{network}-{datamodule_name}-lr={lr}-gradient_clip_val={gradient_clip_val}-cutout={cutout}-auto_augment={auto_augment}-epoch={{epoch}}"
    )
    best_accuracy_callback = ModelCheckpoint(
        monitor="train_acc",
        mode="max",
        dirpath=checkpoint_dir_path,
        filename=f"normal-{network}-{datamodule_name}-lr={lr}-gradient_clip_val={gradient_clip_val}-cutout={cutout}-auto_augment={auto_augment}-epoch={{epoch}}-acc={{train_acc:.2f}}",
        save_top_k=1,
        save_weights_only=True
    )
    lr_monitor = LearningRateMonitor(
        logging_interval="step",
        log_momentum=True
    )
    _name = f"normal-{network}-{datamodule_name}-epoch={epochs}-lr={lr}-gradient_clip_val={gradient_clip_val}-cutout={cutout}-auto_augment={auto_augment}"
    logger = TensorBoardLogger(
        save_dir=f"tb_logs/normal-{network}-{datamodule_name}",
        name=_name
    )

    finetune_trainer = Trainer(
        callbacks=[every_epoch_callback, best_accuracy_callback, lr_monitor],
        max_epochs=finetune_model.hparams.epochs,
        gpus=1,
        auto_select_gpus=True,
        logger=logger,
        gradient_clip_val=gradient_clip_val,
    )

    finetune_trainer.fit(
        model=finetune_model,
        datamodule=finetune_model.datamodule
    )