from typing import List, Optional

from twitchio import PartialUser, Client, Channel, CustomReward, parse_timestamp

__all__ = (
    "PoolError",
    "PoolFull",
    "PubSubMessage",
    "PubSubBitsMessage",
    "PubSubBitsBadgeMessage",
    "PubSubChatMessage",
    "PubSubBadgeEntitlement",
    "PubSubChannelPointsMessage",
    "PubSubModerationAction",
    "PubSubModerationActionModeratorAdd",
    "PubSubModerationActionBanRequest",
    "PubSubModerationActionChannelTerms",
    "PubSubChannelSubscribe",
)

class PubSubError(Exception):
    pass

class ConnectionFailure(PubSubError):
    pass

class PoolError(PubSubError):
    pass

class PoolFull(PoolError):
    pass

class PubSubChatMessage:
    """
    A message received from twitch.

    Attributes
    -----------
    content: :class:`str`
        The content received
    id: :class:`str`
        The id of the payload
    type: :class:`str`
        The payload type
    """

    __slots__ = "content", "id", "type"

    def __init__(self, content: str, id: str, type: str):
        self.content = content
        self.id = id
        self.type = type

class PubSubBadgeEntitlement:
    """
    A badge entitlement

    Attributes
    -----------
    new: :class:`int`
        The new badge
    old: :class:`int`
        The old badge
    """

    __slots__ = "new", "old"

    def __init__(self, new: int, old: int):
        self.new = new
        self.old = old

class PubSubMessage:
    """
    A message from the pubsub websocket

    Attributes
    -----------
    topic: :class:`str`
        The topic subscribed to
    """

    __slots__ = "topic", "_data"

    def __init__(self, client: Client, topic: Optional[str], data: dict):
        self.topic = topic
        self._data = data

class PubSubBitsMessage(PubSubMessage):
    """
    A Bits message

    Attributes
    -----------
    message: :class:`PubSubChatMessage`
        The message sent along with the bits.
    badge_entitlement: Optional[:class:`PubSubBadgeEntitlement`]
        The badges received, if any.
    bits_used: :class:`int`
        The amount of bits used.
    channel_id: :class:`int`
        The channel the bits were given to.
    user: Optional[:class:`twitchio.PartialUser`]
        The user giving the bits. Can be None if anonymous.
    version: :class:`str`
        The event version.
    """

    __slots__ = "badge_entitlement", "bits_used", "channel_id", "context", "anonymous", "message", "user", "version"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)

        data = data["message"]
        self.message = PubSubChatMessage(data["data"]["chat_message"], data["message_id"], data["message_type"])
        self.badge_entitlement = (
            PubSubBadgeEntitlement(
                data["data"]["badge_entitlement"]["new_version"], data["data"]["badge_entitlement"]["old_version"]
            )
            if data["data"]["badge_entitlement"]
            else None
        )
        self.bits_used: int = data["data"]["bits_used"]
        self.channel_id: int = int(data["data"]["channel_id"])
        self.user = (
            PartialUser(client._http, data["data"]["user_id"], data["data"]["user_name"])
            if data["data"]["user_id"]
            else None
        )
        self.version: str = data["version"]

class PubSubBitsBadgeMessage(PubSubMessage):
    """
    A Badge message

    Attributes
    -----------
    user: :class:`twitchio.PartialUser`
        The user receiving the badge.
    channel: :class:`twitchio.Channel`
        The channel the user received the badge on.
    badge_tier: :class:`int`
        The tier of the badge
    message: :class:`str`
        The message sent in chat.
    timestamp: :class:`datetime.datetime`
        The time the event happened
    """

    __slots__ = "user", "channel", "badge_tier", "message", "timestamp"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)
        data = data["message"]
        self.user = PartialUser(client._http, data["user_id"], data["user_name"])
        self.channel: Channel = client.get_channel(data["channel_name"]) or Channel(
            name=data["channel_name"], websocket=client._connection
        )
        self.badge_tier: int = data["badge_tier"]
        self.message: str = data["chat_message"]
        self.timestamp = parse_timestamp(data["time"])

class PubSubChannelPointsMessage(PubSubMessage):
    """
    A Channel points redemption

    Attributes
    -----------
    timestamp: :class:`datetime.datetime`
        The timestamp the event happened.
    channel_id: :class:`int`
        The channel the reward was redeemed on.
    id: :class:`str`
        The id of the reward redemption.
    user: :class:`twitchio.PartialUser`
        The user redeeming the reward.
    reward: :class:`twitchio.CustomReward`
        The reward being redeemed.
    input: Optional[:class:`str`]
        The input the user gave, if any.
    status: :class:`str`
        The status of the reward.
    """

    __slots__ = "timestamp", "channel_id", "user", "id", "reward", "input", "status"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)

        redemption = data["message"]["data"]["redemption"]

        self.timestamp = parse_timestamp(redemption["redeemed_at"])
        self.channel_id: int = int(redemption["channel_id"])
        self.id: str = redemption["id"]
        self.user = PartialUser(client._http, redemption["user"]["id"], redemption["user"]["display_name"])
        self.reward = CustomReward(client._http, redemption["reward"], PartialUser(client._http, self.channel_id, None))
        self.input: Optional[str] = redemption.get("user_input")
        self.status: str = redemption["status"]

class PubSubModerationAction(PubSubMessage):
    """
    A basic moderation action.

    Attributes
    -----------
    action: :class:`str`
        The action taken.
    args: List[:class:`str`]
        The arguments given to the command.
    created_by: :class:`twitchio.PartialUser`
        The user that created the action.
    message_id: Optional[:class:`str`]
        The id of the message that created this action.
    target: :class:`twitchio.PartialUser`
        The target of this action.
    from_automod: :class:`bool`
        Whether this action was done automatically or not.
    """

    __slots__ = "action", "args", "created_by", "message_id", "target", "from_automod"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)
        self.action: str = data["message"]["data"]["moderation_action"]
        self.args: List[str] = data["message"]["data"]["args"]
        self.created_by = PartialUser(
            client._http, data["message"]["data"]["created_by_user_id"], data["message"]["data"]["created_by"]
        )
        self.message_id: Optional[str] = data["message"]["data"].get("msg_id")
        self.target = (
            PartialUser(
                client._http, data["message"]["data"]["target_user_id"], data["message"]["data"]["target_user_login"]
            )
            if data["message"]["data"]["target_user_id"]
            else None
        )
        self.from_automod: bool = data["message"]["data"].get("from_automod", False)

class PubSubModerationActionBanRequest(PubSubMessage):
    """
    A Ban/Unban event

    Attributes
    -----------
    action: :class:`str`
        The action taken.
    args: List[:class:`str`]
        The arguments given to the command.
    created_by: :class:`twitchio.PartialUser`
        The user that created the action.
    target: :class:`twitchio.PartialUser`
        The target of this action.
    """

    __slots__ = "action", "args", "created_by", "message_id", "target"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)
        self.action: str = data["message"]["data"]["moderation_action"]
        self.args: List[str] = data["message"]["data"]["moderator_message"]
        self.created_by = PartialUser(
            client._http, data["message"]["data"]["created_by_id"], data["message"]["data"]["created_by_login"]
        )
        self.target = (
            PartialUser(
                client._http, data["message"]["data"]["target_user_id"], data["message"]["data"]["target_user_login"]
            )
            if data["message"]["data"]["target_user_id"]
            else None
        )

class PubSubModerationActionChannelTerms(PubSubMessage):
    """
    A channel Terms update.

    Attributes
    -----------
    type: :class:`str`
        The type of action taken.
    channel_id: :class:`int`
        The channel id the action occurred on.
    id: :class:`str`
        The id of the Term.
    text: :class:`str`
        The text of the modified Term.
    requester: :class:`twitchio.PartialUser`
        The requester of this Term.
    """

    __slots__ = "type", "channel_id", "id", "text", "requester", "expires_at", "updated_at"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)
        self.type: str = data["message"]["data"]["type"]
        self.channel_id = int(data["message"]["data"]["channel_id"])
        self.id: str = data["message"]["data"]["id"]
        self.text: str = data["message"]["data"]["text"]
        self.requester = PartialUser(
            client._http, data["message"]["data"]["requester_id"], data["message"]["data"]["requester_login"]
        )

        self.expires_at = (
            parse_timestamp(data["message"]["data"]["expires_at"]) if data["message"]["data"]["expires_at"] else None
        )
        self.updated_at = (
            parse_timestamp(data["message"]["data"]["updated_at"]) if data["message"]["data"]["updated_at"] else None
        )

class PubSubChannelSubscribe(PubSubMessage):
    """
    Channel subscription

    Attributes
    -----------
    channel: :class:`twitchio.Channel`
        Channel that has been subscribed or subgifted.
    context: :class:`str`
        Event type associated with the subscription product.
    user: Optional[:class:`twitchio.PartialUser`]
        The person who subscribed or sent a gift subscription. Can be None if anonymous.
    message: :class:`str`
        Message sent with the sub/resub.
    emotes: Optional[List[:class:`dict`]]
        Emotes sent with the sub/resub.
    is_gift: :class:`bool`
        If this sub message was caused by a gift subscription.
    recipient: Optional[:class:`twitchio.PartialUser`]
        The person the who received the gift subscription.
    sub_plan: :class:`str`
        Subscription Plan ID.
    sub_plan_name: :class:`str`
        Channel Specific Subscription Plan Name.
    time: :class:`datetime.datetime`
        Time when the subscription or gift was completed. RFC 3339 format.
    cumulative_months: :class:`int`
        Cumulative number of tenure months of the subscription.
    streak_months: Optional[:class:`int`]
        Denotes the user's most recent (and contiguous) subscription tenure streak in the channel.
    multi_month_duration: Optional[:class:`int`]
        Number of months gifted as part of a single, multi-month gift OR number of months purchased as part of a multi-month subscription.
    """

    __slots__ = (
        "channel",
        "context",
        "user",
        "message",
        "emotes",
        "is_gift",
        "recipient",
        "sub_plan",
        "sub_plan_name",
        "time",
        "cumulative_months",
        "streak_months",
        "multi_month_duration",
    )

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)

        subscription = data["message"]

        self.channel: Channel = client.get_channel(subscription["channel_name"]) or Channel(
            name=subscription["channel_name"], websocket=client._connection
        )
        self.context: str = subscription["context"]
        try:
            self.user = PartialUser(client._http, int(subscription["user_id"]), subscription["user_name"])
        except KeyError:
            self.user = None

        self.message: str = subscription["sub_message"]["message"]
        try:
            self.emotes = subscription["sub_message"]["emotes"]
        except KeyError:
            self.emotes = None

        self.is_gift: bool = subscription["is_gift"]
        try:
            self.recipient = PartialUser(
                client._http, int(subscription["recipient_id"]), subscription["recipient_user_name"]
            )
        except KeyError:
            self.recipient = None

        self.sub_plan: str = subscription["sub_plan"]
        self.sub_plan_name: str = subscription["sub_plan_name"]
        self.time = parse_timestamp(subscription["time"])
        try:
            self.cumulative_months = int(subscription["cumulative_months"])
        except KeyError:
            self.cumulative_months = None
        try:
            self.streak_months = int(subscription["streak_months"])
        except KeyError:
            self.streak_months = None
        try:
            self.multi_month_duration = int(subscription["multi_month_duration"])
        except KeyError:
            self.multi_month_duration = None

class PubSubModerationActionModeratorAdd(PubSubMessage):
    """
    A moderator add event.

    Attributes
    -----------
    channel_id: :class:`int`
        The channel id the moderator was added to.
    moderation_action: :class:`str`
        Redundant.
    target: :class:`twitchio.PartialUser`
        The person who was added as a mod.
    created_by: :class:`twitchio.PartialUser`
        The person who added the mod.
    """

    __slots__ = "channel_id", "target", "moderation_action", "created_by"

    def __init__(self, client: Client, topic: str, data: dict):
        super().__init__(client, topic, data)
        self.channel_id = int(data["message"]["data"]["channel_id"])
        self.moderation_action: str = data["message"]["data"]["moderation_action"]
        self.target = PartialUser(
            client._http, data["message"]["data"]["target_user_id"], data["message"]["data"]["target_user_login"]
        )
        self.created_by = PartialUser(
            client._http, data["message"]["data"]["created_by_user_id"], data["message"]["data"]["created_by"]
        )

_mod_actions = {
    "approve_unban_request": PubSubModerationActionBanRequest,
    "deny_unban_request": PubSubModerationActionBanRequest,
    "channel_terms_action": PubSubModerationActionChannelTerms,
    "moderator_added": PubSubModerationActionModeratorAdd,
    "moderation_action": PubSubModerationAction,
}

def _find_mod_action(client: Client, topic: str, data: dict):
    typ = data["message"]["type"]
    if typ in _mod_actions:
        return _mod_actions[typ](client, topic, data)

    else:
        raise ValueError(f"unknown pubsub moderation action '{typ}'")

_mapping = {
    "channel-bits-events-v2": ("pubsub_bits", PubSubBitsMessage),
    "channel-bits-badge-unlocks": ("pubsub_bits_badge", PubSubBitsBadgeMessage),
    "channel-subscribe-events-v1": ("pubsub_subscription", PubSubChannelSubscribe),
    "chat_moderator_actions": ("pubsub_moderation", _find_mod_action),
    "channel-points-channel-v1": ("pubsub_channel_points", PubSubChannelPointsMessage),
    "whispers": ("pubsub_whisper", None),
}

def create_message(client, msg: dict):
    topic = msg["data"]["topic"].split(".")[0]
    r = _mapping[topic]
    return r[0], r[1](client, topic, msg["data"])


# https://leetcode.com/problems/trim-a-binary-search-tree/

"""
Time complexity:- O(N)
Space Complexity:- O(H)  H = height of BST (call stack )
"""

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def trimBST(self, root, low, high):
        # Base case: If the root is None, return None (no tree).
        if not root:
            return None

        # If the current node's value is greater than 'high', trim the right subtree.
        if root.val > high:
            return self.trimBST(root.left, low, high)

        # If the current node's value is less than 'low', trim the left subtree.
        if root.val < low:
            return self.trimBST(root.right, low, high)

        # If the current node's value is within the [low, high] range, recursively trim both left and right subtrees.
        else:
            root.left = self.trimBST(root.left, low, high)
            root.right = self.trimBST(root.right, low, high)
            return root  # Return the trimmed tree rooted at the current node.


from django.shortcuts import render, redirect
from django.urls import reverse
from django.contrib.auth.decorators import login_required

from .models import ListingComment, Listing, Bid, Category
from .forms import CreateListingForm
import os
import boto3

def home(request):
    listings = Listing.objects.filter(is_active=True)
    categories = Category.objects.all()
    return render(request, "auction/home.html", {
        'listings': listings,
        'categories': categories
    })

@login_required
def createListing(request):
    if request.method == 'POST':
        form = CreateListingForm(request.POST , request.FILES)
        if form.is_valid():
            listing = form.save(commit=False)
            listing.owner = request.user
            price = form.cleaned_data['price'] or 1
            bid = Bid(bid=price, bid_owner=request.user)
            bid.save()
            listing.bid_price = bid

            if request.FILES['image']:
                image_file = request.FILES['image']
                # Connect to S3
                s3 = boto3.client('s3')
                # Upload the image file to S3
                s3.upload_fileobj(image_file, os.getenv('AWS_STORAGE_BUCKET_NAME'), 'static/auction_images/' + image_file.name)

                # Get the URL of the uploaded image
                url = f"https://s3.amazonaws.com/{os.getenv('AWS_STORAGE_BUCKET_NAME')}/{'static/auction_images/' + image_file.name}"
                listing.image_url = url
            listing.save()

            return redirect(reverse('auction:home'))
        else:
            print(form.errors)

    form = CreateListingForm()
    return render(request, 'auction/createListing.html', {
        'form': form
    })

def category(request):
    if request.method == 'POST':
        category = request.POST['category']
        category_object = Category.objects.get(category_name=category)
        categories = Category.objects.exclude(category_name=category)
        listings = Listing.objects.filter(is_active=True, category=category_object)
        return render(request, 'auction/category.html', {
            'listings': listings,
            'categories': categories,
            'category': category
        })

@login_required
def listing(request, listing_id):
    listing = Listing.objects.get(id=listing_id)
    comments = ListingComment.objects.filter(listing=listing)
    if listing in request.user.user_watchlists.all():
        watchlist = True
    else:
        watchlist = False

    return render(request, 'auction/listing.html', {
        'listing': listing,
        'watchlist': watchlist,
        'comments': comments
    })

@login_required
def addWatchlist(request):
    if request.method == 'POST':
        listing = Listing.objects.get(id=request.POST['listing_id'])
        listing.watchlist.add(request.user)
        listing.save()
        return redirect(reverse('auction:listing', args = (listing.id,)))

@login_required
def removeWatchlist(request):
    if request.method == 'POST':
        listing = Listing.objects.get(id=request.POST['listing_id'])
        listing.watchlist.remove(request.user)
        listing.save()
        return redirect(reverse('auction:listing', args = (listing.id,)))

@login_required
def watchlist(request):
    watchlists = request.user.user_watchlists.all()

    return render(request, 'auction/watchlist.html', {
        'watchlists': watchlists
    })

@login_required
def addComment(request):
    if request.method == 'POST':
        id = request.POST['listing_id']
        listing = Listing.objects.get(id=id)
        content = request.POST['comment']
        comment = ListingComment(content=content, listing=listing, author=request.user)
        comment.save()

        return redirect(reverse('auction:listing', args = (listing.id,)))

@login_required
def addBid(request):
    if request.method == 'POST':
        id = request.POST['listing_id']
        listing = Listing.objects.get(id=id)
        bid = float(request.POST['bid'])
        current_bid = listing.bid_price.bid
        comments = ListingComment.objects.filter(listing=listing)
        if listing in request.user.user_watchlists.all():
            watchlist = True
        else:
            watchlist = False

        if bid > current_bid:
            newBid = Bid(bid=bid, bid_owner=request.user)
            newBid.save()
            listing.bid_price = newBid
            listing.save()

            return render(request, 'auction/listing.html', {
                'listing': listing,
                'comments': comments,
                'update': True,
                'watchlist': watchlist
            })

        else:
            return render(request, 'auction/listing.html', {
                'listing': listing,
                'comments': comments,
                'update': False,
                'watchlist': watchlist
            })

@login_required
def removeListing(request, listing_id):
    if request.method == 'POST':
        listing = Listing.objects.get(id=listing_id)
        listing.delete()
        return redirect(reverse('auction:home'))

@login_required
def sellListing(request, listing_id):
    if request.method == 'POST':
        listing = Listing.objects.get(id=listing_id)
        listing.is_active = False
        listing.save()
        buyer = listing.bid_price.bid_owner
        comments = ListingComment.objects.filter(listing=listing)

        return render(request, 'auction/listing.html', {
            'listing': listing,
            'comments': comments,
            'message': f'Sold to {buyer} for ${listing.bid_price.bid}'
        })


import rdflib
from rdflib import Graph
from scipy.special import comb, perm
from itertools import combinations

g = Graph()
g.parse(r'/Users/shenghua/Desktop/ontology/ontology.owl')
deleted_str=r"http://www.semanticweb.org/zhou/ontologies/2020/3/untitled-ontology-19#"
len_deleted_st=len(deleted_str)

query = """
SELECT * WHERE {
        ?s rdfs:range ?o .
}
"""

query_class = """
SELECT ?o WHERE {
        ?s rdfs:subClassOf ?o .
}
"""

query1 = """SELECT ?downp ?downq ?action WHERE {
    ?action rdfs:domain ?dp.
    ?action rdfs:range ?rq.
    ?dcp rdfs:subClassOf ?dp.
    ?rcq rdfs:subClassOf ?rq.
    ?downp rdfs:subClassOf ?dcp.
    ?downq rdfs:subClassOf ?rcq.

}
"""

query2 = """SELECT  ?dp ?rq ?action WHERE {
    ?action rdfs:domain ?dcp.
    ?action rdfs:range ?rcq.
    ?dp rdfs:subClassOf ?dcp.
    ?rq rdfs:subClassOf ?rcq.

}
"""

query3 = """SELECT ?dcp ?downq ?action WHERE {
    ?action rdfs:domain ?dp.
    ?action rdfs:range ?rq.
    ?dcp rdfs:subClassOf ?dp.
    ?rcq rdfs:subClassOf ?rq.
    ?downq rdfs:subClassOf ?rcq.

}
"""

query4 = """SELECT  ?downp ?rcq ?action WHERE {
    ?action rdfs:domain ?dp.
    ?action rdfs:range ?rq.
    ?dcp rdfs:subClassOf ?dp.
    ?rcq rdfs:subClassOf ?rq.
    ?downp rdfs:subClassOf ?dcp.

}
"""

#print (g.subject_objects(predicate=None))

a=[]
for row in g.query(query):
    for i in range(0,len(row)):
        if (str(row[0])[len_deleted_st:])=='detect':
            #print(str(row[1])[len_deleted_st:])
            a.append(str(row[1])[len_deleted_st:])
#print (set(a))

detected_elements=set(a)
print ("detected_elements:")
print (detected_elements)

allclass=[]
for row in g.query(query_class):
    allclass.append(str(row[0])[len_deleted_st:])
all_high_level_class=set(allclass)
print (all_high_level_class)

track=[]
for row in g.query(query):
    for i in range(0,len(row)):
        if (str(row[0])[len_deleted_st:])=='track':
            #print(str(row[1])[len_deleted_st:])
            track.append(str(row[1])[len_deleted_st:])
#print (set(a))

tracked_elements=set(track)
print ("tracked_elements:")
print (tracked_elements)

detected_or_tracked_elements=tracked_elements.union(detected_elements)

d=[]
for row in g.query(query1): #3-3
    for i in range(0,len(row)):

        if  ((str(row[2])[len_deleted_st:len_deleted_st+6])=='affect')and ((str(row[0])[len_deleted_st:]) !=(str(row[1])[len_deleted_st:]) )and ((str(row[0])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[1])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[0])[len_deleted_st:]) not in all_high_level_class) and ((str(row[1])[len_deleted_st:]) not in all_high_level_class):
            #print(str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:])
            d.append((str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:]))
            #print(len(d))
affected_elements_3_3=set(d)
print("affected_elements_3_3")
print(affected_elements_3_3)

d=[]
for row in g.query(query2): #2-2
    print (row)
    for i in range(0,len(row)):
        if  ((str(row[2])[len_deleted_st:len_deleted_st+6])=='affect')and ((str(row[0])[len_deleted_st:]) !=(str(row[1])[len_deleted_st:]) )and ((str(row[0])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[1])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[0])[len_deleted_st:]) not in all_high_level_class) and ((str(row[1])[len_deleted_st:]) not in all_high_level_class):
            #print(str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:])
            d.append((str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:]))
            print(d)
            #print(len(d))
affected_elements_2_2=set(d)
print("affected_elements_2_2")
print(affected_elements_2_2)

d=[]

for row in g.query(query3): #2-3
    for i in range(0,len(row)):
        if  ((str(row[2])[len_deleted_st:len_deleted_st+6])=='affect')and ((str(row[0])[len_deleted_st:]) !=(str(row[1])[len_deleted_st:]) )and ((str(row[0])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[1])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[0])[len_deleted_st:]) not in all_high_level_class) and ((str(row[1])[len_deleted_st:]) not in all_high_level_class):
            #print(str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:])
            d.append((str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:]))
            #print(len(d))
affected_elements_2_3=set(d)
print("affected_elements_2_3")
print(affected_elements_2_3)

d=[]
for row in g.query(query4): #3-2
    for i in range(0,len(row)):
        if  ((str(row[2])[len_deleted_st:len_deleted_st+6])=='affect')and ((str(row[0])[len_deleted_st:]) !=(str(row[1])[len_deleted_st:]) )and ((str(row[0])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[1])[len_deleted_st:]) in (detected_or_tracked_elements)) and ((str(row[0])[len_deleted_st:]) not in all_high_level_class) and ((str(row[1])[len_deleted_st:]) not in all_high_level_class):
            #print(str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:])
            d.append((str(row[0])[len_deleted_st:],str(row[1])[len_deleted_st:]))
            #print(len(d))
affected_elements_3_2=set(d)
print("affected_elements_3_2")
print(affected_elements_3_2)

affected_elements=((affected_elements_3_3.union(affected_elements_2_2)).union(affected_elements_3_2)).union(affected_elements_2_3)
set(affected_elements)
print ("affected_elements")
for i in affected_elements:
    print(i)
print (affected_elements)
print (len(affected_elements))
potential_applications=[]
number_of_potential_applications=0
for j in range(1, len(affected_elements)+1):
    number_of_potential_applications=number_of_potential_applications+comb(len(affected_elements), i)

print (number_of_potential_applications)
for p in list(combinations(affected_elements, 3)):
    potential_applications.append(p)

3. Shared codes/Codes for SPARQL query in the CV-TM ontology/Query of CV-TM Ontology.py


from ..Model import BootQModel
from Agent import Agent
import random
from chainer import cuda
try:
    import cupy
except:
    pass
import numpy as np

import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

class BootQAgent(Agent):
    """
    Deep Exploration via Bootstrapped DQN

    Args:
        _shard (class): necessary, shared part of q func
        _head (class): necessary, head part of q func
        _env (Env): necessary, env to learn, should be rewritten from Env
        _is_train (bool): default True
        _optimizer (chainer.optimizers): not necessary, if not then func won't be updated
        _replay (Replay): necessary for training
        _K (int): how many heads to use
        _mask_p (float): p to be passed when train for each head
        _gpu (bool): whether to use gpu
        _gamma (float): reward decay
        _batch_size (int): how much tuples to pull from replay
        _epsilon (float): init epsilon, p for choosing randomly
        _epsilon_decay (float): epsilon *= epsilon_decay
        _epsilon_underline (float): epsilon = max(epsilon_underline, epsilon)
        _grad_clip (float): clip grad, 0 is no clip
    """

    def __init__(self, _shared, _head, _env, _is_train=True,
                 _optimizer=None, _replay=None,
                 _K=10, _mask_p=0.5,
                 _gpu=False, _gamma=0.99, _batch_size=32,
                 _epsilon=0.5, _epsilon_decay=0.995, _epsilon_underline=0.01,
                 _grad_clip=1.):

        super(BootQAgent, self).__init__()

        self.is_train = _is_train

        self.q_func = BootQModel(_shared, _head, _K)
        if _gpu:
            self.q_func.to_gpu()
        self.env = _env
        if self.is_train:
            self.target_q_func = BootQModel(_shared, _head, _K)
            if _gpu:
                self.target_q_func.to_gpu()
            self.target_q_func.copyparams(self.q_func)

            if _optimizer:
                self.q_opt = _optimizer
                self.q_opt.setup(self.q_func)
            self.replay = _replay

        self.config.K = _K
        self.config.mask_p = _mask_p
        self.config.gpu = _gpu
        self.config.gamma = _gamma
        self.config.batch_size = _batch_size
        self.config.epsilon = _epsilon
        self.config.epsilon_decay = _epsilon_decay
        self.config.epsilon_underline = _epsilon_underline
        self.config.grad_clip = _grad_clip

    def startNewGame(self):
        super(BootQAgent, self).startNewGame()
        # randomly choose head
        self.use_head = random.randint(0, self.config.K - 1)
        logger.info('Use head: ' + str(self.use_head))

    def step(self):
        if not self.env.in_game:
            return False

        # get current state
        cur_state = self.env.getState()
        # choose action in step
        action = self.chooseAction(self.q_func, cur_state)
        # do action and get reward
        reward = self.env.doAction(action)

        logger.info('Action: ' + str(action) + '; Reward: %.3f' % (reward))

        if self.is_train:
            # get new state
            next_state = self.env.getState()
            # store replay_tuple into memory pool
            self.replay.push(
                cur_state, action, reward, next_state,
                np.random.binomial(1, self.config.mask_p,
                                   (self.config.K)).tolist()
            )

        return self.env.in_game

    def forward(self, _cur_x, _next_x, _state_list):
        # get cur outputs
        cur_output = self.func(self.q_func, _cur_x, True)
        # get next outputs, NOT target
        next_output = self.func(self.q_func, _next_x, False)

        # choose next action for each output
        next_action = [
            self.env.getBestAction(
                o.data,
                _state_list
            ) for o in next_output  # for each head in Model
        ]

        # get next outputs, target
        next_output = self.func(self.target_q_func, _next_x, False)
        return cur_output, next_output, next_action

    def grad(self, _cur_output, _next_output, _next_action,
             _batch_tuples, _err_list, _err_count, _k):
        # alloc
        if self.config.gpu:
            _cur_output.grad = cupy.zeros_like(_cur_output.data)
        else:
            _cur_output.grad = np.zeros_like(_cur_output.data)

        # compute grad from each tuples
        for i in range(len(_batch_tuples)):
            # if use bootstrap and masked
            if not _batch_tuples[i].mask[_k]:
                continue

            cur_action_value = \
                _cur_output.data[i][_batch_tuples[i].action].tolist()
            reward = _batch_tuples[i].reward
            target_value = reward
            # if not empty position, not terminal state
            if _batch_tuples[i].next_state.in_game:
                next_action_value = \
                    _next_output.data[i][_next_action[i]].tolist()
                target_value += self.config.gamma * next_action_value
            loss = cur_action_value - target_value
            _cur_output.grad[i][_batch_tuples[i].action] = 2 * loss

            _err_list[i] += abs(loss)
            _err_count[i] += 1

    def doTrain(self, _batch_tuples, _weights):
        cur_x = self.getCurInputs(_batch_tuples)
        next_x = self.getNextInputs(_batch_tuples)
        # if bootstrap, they are all list for heads
        cur_output, next_output, next_action = self.forward(
            cur_x, next_x, [t.next_state for t in _batch_tuples])
        # compute grad for each head
        err_list = [0.] * len(_batch_tuples)
        err_count = [0.] * len(_batch_tuples)
        for k in range(self.config.K):
            self.grad(cur_output[k], next_output[k], next_action[k],
                      _batch_tuples, err_list, err_count, k)
            if _weights is not None:
                if self.config.gpu:
                    _weights = cuda.to_gpu(_weights)
                self.gradWeight(cur_output[k], _weights)
            if self.config.grad_clip:
                self.gradClip(cur_output[k], self.config.grad_clip)
            # backward
            cur_output[k].backward()

        # adjust grads of shared
        for param in self.q_func.shared.params():
            param.grad /= self.config.K

        # avg err
        for i in range(len(err_list)):
            if err_count[i] > 0:
                err_list[i] /= err_count[i]
            else:
                err_list[i] = None
        return err_list

    def chooseAction(self, _model, _state):
        if self.is_train:
            # update epsilon
            self.updateEpsilon()
            random_value = random.random()
            if random_value < self.config.epsilon:
                # randomly choose
                return self.env.getRandomAction(_state)
            else:
                # use model to choose
                x_data = self.env.getX(_state)
                output = self.func(_model, x_data, False)
                output = output[self.use_head]
                logger.info(str(output.data))
                return self.env.getBestAction(output.data, [_state])[0]
        else:
            x_data = self.env.getX(_state)
            output = self.func(_model, x_data, False)
            action_dict = {}
            for o in output:
                action = self.env.getBestAction(o.data, [_state])[0]
                if action not in action_dict.keys():
                    action_dict[action] = 1
                else:
                    action_dict[action] += 1
            logger.info(str(action_dict))
            max_k = -1
            max_v = 0
            for k, v in zip(action_dict.keys(), action_dict.values()):
                if v > max_v:
                    max_k = k
                    max_v = v
            return max_k


# 2839 : 설탕 배달 *** 해결 x

while True :
  n = int(input("킬로그램 수 : "))
  k5 = int(n / 5)
  k3 = int((n - 5*k5) / 3)

  if n % 5 == 0 :
    print(n / 5)
  elif (3*k3 + 5*k5) == n :
    print(k3 + k5)
  elif (3*k3 + 5*k5) != n :
    if k5 <= 2 :
      if (n-5*(k5-1)) % 3 == 0 :
        print( (n-5*(k5-1)) / 3 + k5-1)
      # else : 3으로도 안나눠떨어질 때
          #수행문장
      for i in range(1, k5) :
        if (n-5*(k5-i)) % 3 == 0 :
          print( (n-5*(k5-i)) / 3 + k5-i)

  else :
    print("-1")

  # 1) 5로 다 나눠지는지 확인
  # 2) 5로 최대한 나눠보고 3의 배수를 늘려감
  # 3) 3으로만 다 나눠지는지 확인
  # 4) 그래도 안되면 -1 출력


import tensorflow as tf
from tensorflow import keras
import numpy as np
import os
import sys
sys.path.append(os.getcwd())
from utils.prepareReviewDataset import intToWord, return_processed_data_and_labels

def decode_review(text):
	return " ".join([intToWord.get(i, "?") for i in text])

train_data, train_labels, test_data, test_labels = return_processed_data_and_labels(250)

model = keras.Sequential()
model.add(keras.layers.Embedding(88000, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation="relu"))
model.add(keras.layers.Dense(1, activation="sigmoid"))

model.summary()  # prints a summary of the model

model.compile(optimizer="adam", loss="binary_crossentropy", metrics = ["accuracy"])

x_val = train_data[:10000]
x_train = train_data[10000:]

y_val = train_labels[:10000]
y_train = train_labels[10000:]

fitModel = model.fit(x_train, y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1)

def saveTheModel():
	model.save("model.h5")

def printModelEvaluation():
	results = model.evaluate(test_data, test_labels)
	print(results)

def testModelOnTestData():
	test_review = test_data[0]
	predict = model.predict([test_review])
	print("Review: ")
	print(decode_review(test_review))
	print("Prediction: " + str(predict[0]))
	print("Actual: " + str(test_labels[0]))


import os
import connexion
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_bcrypt import Bcrypt

basedir = os.path.abspath(os.path.dirname(__file__))

# Create the Connexion application instance

connex_app = connexion.App(__name__, specification_dir=basedir)

# Get the underlying Flask app instance

app = connex_app.app
bcrypt = Bcrypt(app)

# Configure the SQLAlchemy part of the app instance

app.config['SQLALCHEMY_ECHO'] = True

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(basedir, 'database.db')

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

app.config["DEBUG"] = True

# Create the SQLAlchemy db instance

db = SQLAlchemy(app)

# Initialize Marshmallow

ma = Marshmallow(app)

SECRET_KEY="\xb3\x88e\x0e\xab\xa93\x01x\x82\xd1\xe0\x1b\xb6f;\x1a\x91d\x91\xc1-I\x00"
TIME_FOR_TOKEN_DAYS = 0
TIME_FOR_TOKEN_SECONDS = 600
BCRYPT_LOG_ROUNDS = 13


import re
import sys

from .ply import lex
from .ply.lex import TOKEN

class CLexer(object):
    """ A lexer for the C- language. After building it, set the
        input text with input(), and call token() to get new
        tokens.
        The public attribute filename can be set to an initial
        filaneme, but the lexer will update it upon #line
        directives.
    """
    def __init__(self, error_func, on_lbrace_func, on_rbrace_func,
                 type_lookup_func):
        """ Create a new Lexer.
            error_func:
                An error function. Will be called with an error
                message, line and column as arguments, in case of
                an error during lexing.
            on_lbrace_func, on_rbrace_func:
                Called when an LBRACE or RBRACE is encountered
                (likely to push/pop type_lookup_func's scope)
            type_lookup_func:
                A type lookup function. Given a string, it must
                return True IFF this string is a name of a type
                that was defined with a typedef earlier.
        """
        self.error_func = error_func
        self.on_lbrace_func = on_lbrace_func
        self.on_rbrace_func = on_rbrace_func
        self.type_lookup_func = type_lookup_func
        self.filename = ''

        # Keeps track of the last token returned from self.token()
        self.last_token = None

        # Allow either "# line" or "# <num>" to support GCC's
        # cpp output
        #
        self.line_pattern = re.compile(r'([ \t]*line\W)|([ \t]*\d+)')
        self.pragma_pattern = re.compile(r'[ \t]*pragma\W')

    def build(self, **kwargs):
        """ Builds the lexer from the specification. Must be
            called after the lexer object is created.
            This method exists separately, because the PLY
            manual warns against calling lex.lex inside
            __init__
        """
        self.lexer = lex.lex(object=self, **kwargs)

    def reset_lineno(self):
        """ Resets the internal line number counter of the lexer.
        """
        self.lexer.lineno = 1

    def input(self, text):
        self.lexer.input(text)

    def token(self):
        self.last_token = self.lexer.token()
        return self.last_token

    def find_tok_column(self, token):
        """ Find the column of the token in its line.
        """
        last_cr = self.lexer.lexdata.rfind('\n', 0, token.lexpos)
        return token.lexpos - last_cr

    def _error(self, msg, token):
        location = self._make_tok_location(token)
        self.error_func(msg, location[0], location[1])
        self.lexer.skip(1)

    def _make_tok_location(self, token):
        return (token.lineno, self.find_tok_column(token))

    ##
    ## Reserved keywords
    ##
    keywords = (
        'BOOL', 'BREAK', 'ELSE', 'FALSE', 'FOR', 'IF', 'INT',
        'READ', 'RETURN', 'STRING', 'TRUE', 'VOID', 'WHILE', 'WRITE'
    )

    keyword_map = {}
    for keyword in keywords:
        if keyword == '_BOOL':
            keyword_map['_Bool'] = keyword
        elif keyword == '_COMPLEX':
            keyword_map['_Complex'] = keyword
        else:
            keyword_map[keyword.lower()] = keyword

    ##
    ## All the tokens recognized by the lexer
    ##
    tokens = keywords + (
        # Identifiers
        'ID',

        # Type identifiers (identifiers previously defined as
        # types with typedef)
        'TYPEID',

        # String literals
        'STRING_LITERAL',
        'WSTRING_LITERAL',

        # Operators
        'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
        'AND', 'OR', 'NOT', 'LSHIFT', 'RSHIFT',

        # Relations
        'EQ', 'NE', 'LT', 'LE', 'GT', 'GE',

        # Assignment
        'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL',
        'PLUSEQUAL', 'MINUSEQUAL',
        'LSHIFTEQUAL','RSHIFTEQUAL',
        'ANDEQUAL', 'XOREQUAL', 'OREQUAL',

        # Increment/decrement
        'PLUSPLUS', 'MINUSMINUS',

        # Conditional operator (?)
        'CONDOP',

        # Delimeters
        'LPAREN', 'RPAREN',         # ( )
        'LBRACKET', 'RBRACKET',     # [ ]
        'LBRACE', 'RBRACE',         # { }
        'COMMA', 'PERIOD',          # . ,
        'SEMI', 'COLON',            # ; :

        # Ellipsis (...)
        'ELLIPSIS',

        # pre-processor
        'PPHASH',       # '#'
        'PPPRAGMA',     # 'pragma'
        'PPPRAGMASTR',
    )


import unittest

class TestImageGen(unittest.TestCase):
    def test_image_gen(self):
        from src.dataio import GridIO, FlowIO
        from src.create_particles import Particle, LaserSheet, CreateParticles
        from src.ccd_projection import CCDProjection
        from src.intensity import Intensity
        from src.image_gen import ImageGen

        # Read-in the grid and flow file
        grid = GridIO('../data/shocks/interpolated_data/mgrd_to_p3d.x')
        grid.read_grid()
        grid.compute_metrics()
        flow = FlowIO('../data/shocks/interpolated_data/mgrd_to_p3d_particle.q')
        flow.read_flow()

        # Set particle data
        p = Particle()
        p.min_dia = 144e-9  # m
        p.max_dia = 573e-9  # m
        p.mean_dia = 281e-9  # m
        p.std_dia = 97e-9  # m
        p.density = 810  # kg/m3
        p.n_concentration = 25
        p.compute_distribution()

        # Read-in the laser sheet
        laser = LaserSheet(grid)
        # z-location
        laser.position = 0.00025  # in m
        laser.thickness = 0.0001  # in m (Data obtained from LaVision)
        laser.pulse_time = 1e-9
        laser.compute_bounds()

        # path to save files
        path = '../data/shocks/interpolated_data/particle_snaps/'

        for i in range(1):
            # Create particle locations array
            ia_bounds = [None, None, None, None]
            loc = CreateParticles(grid, flow, p, laser, ia_bounds)
            # x_min, x_max, y_min, y_max --> ia_bounds
            loc.ia_bounds = [0.0016, 0.0025, 0.0002, 0.0004]  # in m
            loc.in_plane = 70
            loc.compute_locations()
            loc.compute_locations2()

            # Create particle projections (Simulating data from EUROPIV)
            proj = CCDProjection(loc)
            proj.dpi = 72
            proj.xres = 1024
            proj.yres = 1024
            # Set distance based on similar triangles relationship
            proj.d_ccd = proj.xres * 25.4e-3 / proj.dpi  # in m
            proj.d_ia = 0.0009  # in m; ia_bounds (max - min)
            proj.compute()

            cache = (proj.projections[:, 2], proj.projections[:, 2],
                     proj.projections[:, 0], proj.projections[:, 1],
                     2.0, 2.0, 1.0, 1.0)
            intensity = Intensity(cache, proj)
            intensity.setup()
            intensity.compute()

            snap = ImageGen(intensity)
            snap.snap(snap_num=1)
            # snap.save_snap(fname=path + str(i) + '_1.tif')
            snap.check_data(snap_num=1)
            print('Done with image 1 for pair number ' + str(i) + '\n')

            cache2 = (proj.projections2[:, 2], proj.projections2[:, 2],
                     proj.projections2[:, 0], proj.projections2[:, 1],
                     2.0, 2.0, 1.0, 1.0)
            intensity2 = Intensity(cache2, proj)
            intensity2.setup()
            intensity2.compute()
            #
            snap2 = ImageGen(intensity2)
            snap2.snap(snap_num=2)
            # snap2.save_snap(fname=path + str(i) + '_2.tif')
            snap2.check_data(snap_num=2)

            print('Done with image 2 for pair number ' + str(i) + '\n')

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


from_path = "D:/PasaOpasen.github.io/images/Миша Светлов/вторая съемка/отбор2"
to_path = "D:/PasaOpasen.github.io/images/Миша Светлов/вторая съемка/отбор2ориги"
where = "C:/Users/qtckp/YandexDisk/Загрузки/ДИМА"

import glob
import os
import shutil

files = [ os.path.splitext(os.path.basename(file))[0] + '.cr2' for file in glob.glob(os.path.join(from_path,'*'))]

print(files)

for file in files:
    shutil.copyfile(os.path.join(where, file), os.path.join(to_path, file))

images/Миша Светлов/вторая съемка/migrate.py


# Autor: João PauLo Falcão
# Github: https://github.com/jplfalcao
# Data de criação: 09/10/2023
# Data de modificação:
# Versão: 1.0

# Importando a biblioteca
import yt_dlp

# Endereço do vídeo a ser baixado
url = input("Digite a url do vídeo: ")

# Especificando o formato '.mp4' para o vídeo
ydl_opts = {
    'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4'
}

# Usando a classe YoutubeDL para baixar o vídeo
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

print("Vídeo baixado com sucesso!")


# Approach 1: Coloring by Depth-First Search

# Time: O(N + E), N = no. of node_idxs, E = no. of edges
# Space: O(N)

class Solution:
    def isBipartite(self, graph: List[List[int]]) -> bool:
        color = {}

        for node_idx in range(len(graph)):
            if node_idx not in color:
                stack = [node_idx]
                color[node_idx] = 0

                while stack:
                    node_idx = stack.pop()
                    for neighbor in graph[node_idx]:
                        if neighbor not in color:
                            stack.append(neighbor)
                            color[neighbor] = color[node_idx] ^ 1
                        elif color[neighbor] == color[node_idx]:
                            return False

        return True


#!/usr/bin/env python
def read_input():
    with open('./inputs/day04') as f:
        return [l.strip() for l in f.readlines()]

def _to_range(pair):
    return range(int(pair[0]), int(pair[1]) + 1)

def get_pairs():
    for line in read_input():
        yield (
            set(_to_range(p.split('-')))
            for p in line.split(',')
        )

def part1():
    total = 0
    for p1, p2 in get_pairs():
        if p1 >= p2 or p1 <= p2:
            total += 1
    print(f'part 1: {total}')

def part2():
    total = 0
    for p1, p2 in get_pairs():
        if p1 & p2:
            total += 1
    print(f'part 2: {total}')

if __name__ == '__main__':
    part1()
    part2()


# -*- coding: utf-8 -*-
from __future__ import print_function
from os import sep
from os.path import dirname, normpath
from pickle import HIGHEST_PROTOCOL

#-------------------------------------------------------------------------
# Paths
#-------------------------------------------------------------------------
PROGRAM_DIR = dirname(__file__)  # location of const.py !
PROTO_DIR   = PROGRAM_DIR + sep + 'proto' + sep
DATA_DIR    = normpath(PROGRAM_DIR + sep + '..' + sep + 'data')
print('Program and data directory set to:', PROGRAM_DIR, DATA_DIR)
CSV_DIR     = DATA_DIR    + sep + 'csv'
INI_DIR     = DATA_DIR    + sep + 'datafiles'
FIGS_DIR    = DATA_DIR    + sep + 'datafiles'

#-------------------------------------------------------------------------
# Default file and directory names
#-------------------------------------------------------------------------
DEFAULTS_ININAME   = 'defaults.ini'
CONSTANTS_ININAME  = 'constants.ini'
MEASUREMENTS_ININAME  = 'measurements.ini'
PLOTSTYLE_ININAME  = 'plotstyles.ini'
MASKS_DIRNAME      = 'masks'
DUMP_DATA_FILENAME = 'data.dat'

#-------------------------------------------------------------------------
# Plotting
#-------------------------------------------------------------------------
# Dumping data format: This specifies the format used for data dumping.
# For compatibility with python 2.x the value of '2' is used. In general,
# if compatibility is not needed, the HIGHEST_PROTOCOL value could be used
DUMP_DATA_VERSION=2
DIFFPROG = "diff"


company_motto = "Copeland's Corporate Company helps you capably cope with the constant cacophony of daily life"

# Find the second to last character in company_motto.
second_to_last = company_motto[-2:-1]
print(second_to_last) # f

# create a slice of the last 4 characters in company_motto.
final_word = company_motto[-4:]
print(final_word) # life

# get_length() that takes a string as an input and returns the number of characters in that string.
# Do this by iterating through the string, don’t cheat and use len()

def get_length(input):
  char_num = 0
  for letter in input:
    #print(letter)
    char_num += 1
  return char_num

print(get_length("Albus")) # 5

# Find / count characters within a string

favorite_fruit = "blueberry"
counter = 0
for character in favorite_fruit:
  if character == "b":
    counter = counter + 1
print(counter) # 2

def letter_check(word, letter):
  for character in word:
    if character == letter:
      return True
  return False
 # This function should return True if the word contains the letter and False if it does not.

def letter_check(word, letter):
  for char in word:
    if char == letter:
      return True
  return False

print(letter_check("Albus", "u")) # True

#  "letter in word" is a boolean expression that is True if the string letter is in the string word. Here are some examples. It not only works with letters, but with entire strings as well.

print("melon" in "watermelon") # True
print("melon" in "butterfly")  # False

# Write a function called contains that takes two arguments, big_string and little_string and returns True if big_string contains little_string. For example contains("watermelon", "melon") should return True and contains("watermelon", "berry") should return False.

def contains_long(big_string, little_string):
  if little_string in big_string:
    return True
  return False

# Better solution:
def contains(big_string, little_string):
  return little_string in big_string

# Write a function called common_letters that takes two arguments, string_one and string_two and then returns a list with all of the letters they have in common.

def common_letters(string_one, string_two):
  common = []
  for letter in string_one:
    if (letter in string_two) and not (letter in common):
      common.append(letter)
  return common

print(common_letters("butterfly", "fly")) # ['f', 'l', 'y']

print(common_letters("mississippi", "pizza")) # ['i', 'p']

print(common_letters("mississippi", "bear")) # []


# -*- coding:utf-8 -*-
import cv2
import os
from glob import glob
import numpy as np
import shutil

'''处理原图片得到人物脸部图片并按比例分配train和test用于训练模型'''

SRC = "Raw"  # 待处理的文件路径
DST = "data2"  # 处理后的文件路径
TRAIN_PER = 5  # train的图片比例
TEST_PER = 1  # test的图片比例

def rename_file(path, new_name="", start_num=0, file_type=""):
    if not os.path.exists(path):
        return
    count = start_num
    files = os.listdir(path)
    for file in files:
        old_path = os.path.join(path, file)
        if os.path.isfile(old_path):
            if file_type == "":
                file_type = os.path.splitext(old_path)[1]
            new_path = os.path.join(path, new_name + str(count) + file_type)

            if not os.path.exists(new_path):
                os.rename(old_path, new_path)
                count = count + 1
    # print("Renamed %d file(s)" % (count - start_num))

def get_faces(src, dst, cascade_file="lbpcascade_animeface.xml"):
    if not os.path.isfile(cascade_file):
        raise RuntimeError("%s: not found" % cascade_file)

    # Create classifier
    cascade = cv2.CascadeClassifier(cascade_file)

    files = [y for x in os.walk(src) for y in glob(os.path.join(x[0], '*.*'))]  # 妙啊,一句话得到一个文件夹中所有文件

    for image_file in files:
        image_file = image_file.replace('\\', '/')  # 解决Windows下的文件路径问题
        target_path = "/".join(image_file.strip("/").split('/')[1:-1])
        target_path = os.path.join(dst, target_path) + "/"
        if not os.path.exists(target_path):
            os.makedirs(target_path)
        count = len(os.listdir(target_path)) + 1

        image = cv2.imdecode(np.fromfile(image_file, dtype=np.uint8), -1)  # 解决中文路径读入图片问题
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        gray = cv2.equalizeHist(gray)
        faces = cascade.detectMultiScale(gray,
                                         # detector options
                                         scaleFactor=1.05,  # 指定每个图像缩放比例缩小图像大小的参数
                                         minNeighbors=4,  # 此参数将影响检测到的面孔。值越高，检测结果越少，但质量越高
                                         minSize=(24, 24)  # 最小对象大小。小于此值的对象将被忽略
                                         )
        for (x, y, w, h) in faces:
            crop_img = image[y:y + h, x:x + w]
            crop_img = cv2.resize(crop_img, (96, 96))  # 重置为96*96
            # filename = os.path.basename(image_file).split('.')[0]
            cv2.imencode('.jpg', crop_img)[1].tofile(os.path.join(target_path, str(count) + ".jpg"))

    print("All images are cropped")

def divide_train_test(src, train_percentage=5, test_percentage=1):
    if not os.path.exists(src):
        print("folder %s is not exist" % src)
        return
    dirs = os.listdir(src)

    test_dir = os.path.join(src, "test")
    train_dir = os.path.join(src, "train")
    if not os.path.exists(test_dir):
        os.mkdir(test_dir)
    if not os.path.exists(train_dir):
        os.mkdir(train_dir)

    for dir_name in dirs:
        if dir_name != "test" and dir_name != "train":
            current_dir = os.path.join(src, dir_name)
            test_dir = os.path.join(src, "test", dir_name)
            train_dir = os.path.join(src, "train", dir_name)
            if not os.path.exists(test_dir):
                os.mkdir(test_dir)
            if not os.path.exists(train_dir):
                os.mkdir(train_dir)

            if os.path.isdir(current_dir):
                images = os.listdir(current_dir)
                image_num = len(images)
                for image in images:
                    filename = os.path.basename(image).split('.')[0]
                    if filename.isdigit():
                        percentage = train_percentage + test_percentage
                        test_num = (image_num / percentage) * test_percentage + 1
                        if int(filename) <= test_num:
                            if not os.path.exists(os.path.join(test_dir, image)):
                                shutil.move(os.path.join(current_dir, image), os.path.join(test_dir))
                            else:
                                os.remove(os.path.join(current_dir, image))
                        else:
                            if not os.path.exists(os.path.join(train_dir, image)):
                                shutil.move(os.path.join(current_dir, image), os.path.join(train_dir))
                            else:
                                os.remove(os.path.join(current_dir, image))
            shutil.rmtree(current_dir)

    for dirs in os.listdir(src):
        for name in os.listdir(os.path.join(src, dirs)):
            if os.path.isdir(os.path.join(src, dirs, name)):
                rename_file(os.path.join(src, dirs, name))

    print("Set all cropped images to train and test")

def main():
    get_faces(SRC, DST)
    divide_train_test(src=DST, train_percentage=TRAIN_PER, test_percentage=TEST_PER)

if __name__ == '__main__':
    main()


from urllib.request import urlopen

from pdfminer.high_level import extract_text

def pdf_to_text(data):
    with urlopen(data) as wFile:
        text = extract_text(wFile)
    return text

docUrl = 'https://diavgeia.gov.gr/doc/ΩΕΚ64653ΠΓ-2ΞΡ'
print(pdf_to_text(docUrl))


__all__ = [
    'points_to_morton',
    'morton_to_points',
    'points_to_corners',
    'coords_to_trilinear',
    'unbatched_points_to_octree',
    'quantize_points'
]

import torch

from kaolin import _C

def quantize_points(x, level):
    r"""Quantize :math:`[-1, 1]` float coordinates in to
    :math:`[0, (2^{level})-1]` integer coords.

    If a point is out of the range :math:`[-1, 1]` it will be clipped to it.

    Args:
        x (torch.FloatTensor): Floating point coordinates,
                               must be of last dimension 3.
        level (int): Level of the grid

    Returns
        (torch.ShortTensor): Quantized 3D points, of same shape than x.
    """
    res = 2 ** level
    qpts = torch.floor(torch.clamp(res * (x + 1.0) / 2.0, 0, res - 1.)).short()
    return qpts

def unbatched_points_to_octree(points, level, sorted=False):
    r"""Convert (quantized) 3D points to an octree.

    This function assumes that the points are all in the same frame of reference
    of :math:`[0, 2^level]`. Note that SPC.points does not satisfy this constraint.

    Args:
        points (torch.ShortTensor):
            The Quantized 3d points. This is not exactly like SPC points hierarchies
            as this is only the data for a specific level.
        level (int): Max level of octree, and the level of the points.
        sorted (bool): True if the points are unique and sorted in morton order.

    Returns:
        (torch.ByteTensor):
            the generated octree,
            of shape :math:`(2^\text{level}, 2^\text{level}, 2^\text{level})`.
    """
    if not sorted:
        unique = torch.unique(points.contiguous(), dim=0).contiguous()
        morton = torch.sort(points_to_morton(unique).contiguous())[0]
        points = morton_to_points(morton.contiguous())
    return _C.ops.spc.points_to_octree(points.contiguous(), level)

def points_to_morton(points):
    r"""Convert (quantized) 3D points to morton codes.

    Args:
        points (torch.ShortTensor):
            Quantized 3D points. This is not exactly like SPC points hierarchies
            as this is only the data for a specific level,
            of shape :math:`(\text{num_points}, 3)`.

    Returns:
        (torch.LongTensor):
            The morton code of the points,
            of shape :math:`(\text{num_points})`

    Examples:
        >>> inputs = torch.tensor([
        ...     [0, 0, 0],
        ...     [0, 0, 1],
        ...     [0, 0, 2],
        ...     [0, 0, 3],
        ...     [0, 1, 0]], device='cuda', dtype=torch.int16)
        >>> points_to_morton(inputs)
        tensor([0, 1, 8, 9, 2], device='cuda:0')
    """
    shape = list(points.shape)[:-1]
    points = points.reshape(-1, 3)
    return _C.ops.spc.points_to_morton_cuda(points.contiguous()).reshape(*shape)

def morton_to_points(morton):
    r"""Convert morton codes to points.

    Args:
        morton (torch.LongTensor): The morton codes of quantized 3D points,
                                   of shape :math:`(\text{num_points})`.

    Returns:
        (torch.ShortInt):
            The points quantized coordinates,
            of shape :math:`(\text{num_points}, 3)`.

    Examples:
        >>> inputs = torch.tensor([0, 1, 8, 9, 2], device='cuda')
        >>> morton_to_points(inputs)
        tensor([[0, 0, 0],
                [0, 0, 1],
                [0, 0, 2],
                [0, 0, 3],
                [0, 1, 0]], device='cuda:0', dtype=torch.int16)
    """
    shape = list(morton.shape)
    shape.append(3)
    morton = morton.reshape(-1)
    return _C.ops.spc.morton_to_points_cuda(morton.contiguous()).reshape(*shape)

def points_to_corners(points):
    r"""Calculates the corners of the points assuming each point is the 0th bit corner.

    Args:
        points (torch.ShortTensor): Quantized 3D points,
                                    of shape :math:`(\text{num_points}, 3)`.

    Returns:
        (torch.ShortTensor):
            Quantized 3D new points,
            of shape :math:`(\text{num_points}, 8, 3)`.

    Examples:
        >>> inputs = torch.tensor([
        ...     [0, 0, 0],
        ...     [0, 2, 0]], device='cuda', dtype=torch.int16)
        >>> points_to_corners(inputs)
        tensor([[[0, 0, 0],
                 [0, 0, 1],
                 [0, 1, 0],
                 [0, 1, 1],
                 [1, 0, 0],
                 [1, 0, 1],
                 [1, 1, 0],
                 [1, 1, 1]],
        <BLANKLINE>
                [[0, 2, 0],
                 [0, 2, 1],
                 [0, 3, 0],
                 [0, 3, 1],
                 [1, 2, 0],
                 [1, 2, 1],
                 [1, 3, 0],
                 [1, 3, 1]]], device='cuda:0', dtype=torch.int16)
    """
    shape = list(points.shape)
    shape.insert(-1, 8)
    return _C.ops.spc.points_to_corners_cuda(points.contiguous()).reshape(*shape)

def coords_to_trilinear(coords, points):
    r"""Calculates the coefficients for trilinear interpolation.

    To interpolate with the coefficients, do:
    ``torch.sum(features * coeffs, dim=-1)``
    with ``features`` of shape :math:`(\text{num_points}, 8)`

    Args:
        coords (torch.FloatTensor): Floating point 3D points,
                                    of shape :math:`(\text{num_points}, 3)`.
        points (torch.ShortTensor): Quantized 3D points (the 0th bit of the voxel x is in),
                                    of shape :math:`(\text{num_points}, 3)`.

    Returns:
        (torch.FloatTensor):
            The trilinear interpolation coefficients,
            of shape :math:`(\text{num_points}, 8)`.
    """
    shape = list(points.shape)
    shape[-1] = 8
    points = points.reshape(-1, 3)
    coords = coords.reshape(-1, 3)
    return _C.ops.spc.coords_to_trilinear_cuda(coords.contiguous(), points.contiguous()).reshape(*shape)


from unittest.mock import Mock

from .imapclient_test import IMAPClientTest

class TestFolderStatus(IMAPClientTest):
    def test_basic(self):
        self.client._imap.status.return_value = (
            "OK",
            [b"foo (MESSAGES 3 RECENT 0 UIDNEXT 4 UIDVALIDITY 1435636895 UNSEEN 0)"],
        )

        out = self.client.folder_status("foo")

        self.client._imap.status.assert_called_once_with(
            b'"foo"', "(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)"
        )
        self.assertDictEqual(
            out,
            {
                b"MESSAGES": 3,
                b"RECENT": 0,
                b"UIDNEXT": 4,
                b"UIDVALIDITY": 1435636895,
                b"UNSEEN": 0,
            },
        )

    def test_literal(self):
        self.client._imap.status.return_value = (
            "OK",
            [(b"{3}", b"foo"), b" (UIDNEXT 4)"],
        )

        out = self.client.folder_status("foo", ["UIDNEXT"])

        self.client._imap.status.assert_called_once_with(b'"foo"', "(UIDNEXT)")
        self.assertDictEqual(out, {b"UIDNEXT": 4})

    def test_extra_response(self):
        # In production, we've seen folder names containing spaces come back
        # like this and be broken into two components in the tuple.
        server_response = [b"My files (UIDNEXT 24369)"]
        mock = Mock(return_value=server_response)
        self.client._command_and_check = mock

        resp = self.client.folder_status("My files", ["UIDNEXT"])
        self.assertEqual(resp, {b"UIDNEXT": 24369})

        # We've also seen the response contain mailboxes we didn't
        # ask for. In all known cases, the desired mailbox is last.
        server_response = [b"sent (UIDNEXT 123)\nINBOX (UIDNEXT 24369)"]
        mock = Mock(return_value=server_response)
        self.client._command_and_check = mock

        resp = self.client.folder_status("INBOX", ["UIDNEXT"])
        self.assertEqual(resp, {b"UIDNEXT": 24369})


import random,argparse,sys
parser = argparse.ArgumentParser()
import numpy as np

class PlannerEncoder:
    def __init__(self, opponent, p,q) -> None:
        self.p = p; self.q = q

        self.idx_to_states = {}
        self.opp_action_probs = {}
        with open(opponent,'r') as file:
            i = 0
            for line in file:
                parts = line.split()
                if parts[0] == 'state':
                    continue
                if len(parts[0]) == 7:
                    self.idx_to_states[i] = parts[0]
                    self.opp_action_probs[parts[0]] = [float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4])]
                i+=1
        self.idx_to_states[i] = 'lost'   # both of these are terminal states
        self.idx_to_states[i+1] = 'goal'
        self.states_to_idx = {}
        for i in self.idx_to_states:
            self.states_to_idx[self.idx_to_states[i]] = i
        self.S = len(self.idx_to_states)
        self.A = 10
        # Next step is to calculate probs based on different situations
    def player_pos(self, player, action):
            new = None
            if action ==0:
                new = player -1
                if (new-1)//4 == (player-1)//4 and new > 0 and new < 17:
                    player = new
            elif action == 1:
                new = player +1
                if (new-1)//4 == (player-1)//4 and new > 0 and new < 17:
                    player = new
            elif action ==2:
                new = player - 4
                if new > 0 and new < 17:
                    player = new
            elif action ==3:
                new = player + 4
                if new > 0 and new < 17:
                    player = new
            return player
    def state_after_action(self, curr_state, a):
        b1_int = int(curr_state[:2])
        b2_int = int(curr_state[2:4])
        r_int = int(curr_state[4:6])
        ball_int = int(curr_state[-1])
        if a <4:
            b1_int = self.player_pos(b1_int, a)
        elif a < 8:
            b2_int = self.player_pos(b2_int, a - 4)
        elif a == 8:
            if ball_int ==1:
                ball_int = 2
            elif ball_int ==2:
                ball_int = 1
        elif a == 9:
            return 'goal'

        b1_str = str(b1_int) ; b2_str = str(b2_int)
        r_str = str(r_int)
        ball_str = str(ball_int)
        if len(b1_str)==1:
            b1_str = '0' + b1_str
        if len(b2_str)==1:
            b2_str = '0' + b2_str
        if len(r_str)==1:
            r_str = '0' + r_str
        new_state = b1_str + b2_str + r_str + ball_str
        return new_state

    def cordinates(self, state):
        b1 = int(state[:2]); b2 = int(state[2:4]); r = int(state[-3:-1])
        b1_cor = ( (b1 -1)//4 , (b1-1)%4 )
        b2_cor = ( (b2 -1)//4 , (b2-1)%4 )
        r_cor = ( (r -1)//4 , (r-1)%4 )
        return [b1_cor, b2_cor, r_cor]
    def transition_function(self, current_s, next_s, action):
        ball_pos = int(current_s[-1])
        if action <4:
            if ball_pos == 1:
                b1_old = current_s[:2] ; r_old = current_s[-3:-1]
                b1_new = next_s[:2] ; r_new = next_s[-3:-1]
                if b1_new == r_new:
                    return (0.5 - self.p, 0.5 + self.p)
                elif b1_old == r_new and b1_new == r_old:
                    return (0.5 - self.p, 0.5 + self.p)
                else:
                    return (1- self.p, self.p)
            elif ball_pos == 2:
                return (1- self.p, self.p)
        elif action <8:
            if ball_pos == 1:
                return (1-self.p, self.p)
            elif ball_pos == 2:
                b2_old = current_s[2:4] ; r_old = current_s[-3:-1]
                b2_new = next_s[2:4] ; r_new = next_s[-3:-1]
                if b2_new == r_new:
                    return (0.5 - self.p, 0.5 + self.p)
                elif b2_old == r_new and b2_new == r_old:
                    return (0.5 - self.p, 0.5 + self.p)
                else:
                    return (1- self.p, self.p)
        if action ==8:
            b1_cor, b2_cor, r_cor = self.cordinates(next_s)
            val = self.q - 0.1*max( abs(b1_cor[0] - b2_cor[0]), abs(b1_cor[1] - b2_cor[1]))
            if b1_cor[0] == r_cor[0] and b2_cor[0] == r_cor[0]:
                return (0.5*val, 1 - 0.5*val)
            elif b1_cor == r_cor or b2_cor == r_cor:
                return (0.5*val, 1 - 0.5*val)
            elif ((b1_cor[1]- r_cor[1])/(b1_cor[0] - r_cor[0] + 1e-3)) == ((r_cor[1] - b2_cor[1])/(r_cor[0]- b2_cor[0] + 1e-3)):
                return (0.5*val, 1 - 0.5*val)
            else:
                return (val, 1- val)
        if action ==9:
            b1_cor, b2_cor, r_cor = self.cordinates(next_s)
            ball_pos = int(current_s[-1])
            if ball_pos ==1:
                val = self.q - 0.2*(3 - b1_cor[1]) # NOTE my x,y are reverse to the one used in the assgn description
                # I use like the matrix 0,1 axis
                if r_cor[0]>0 and r_cor[0]<3 and r_cor[1]>1:
                    return (0.5*val, 1- 0.5*val)
                else:
                    return( val, 1-val)
            elif ball_pos ==2:
                val = self.q - 0.2*(3 - b2_cor[1]) # NOTE
                if r_cor[0]>0 and r_cor[0]<3 and r_cor[1]>1:
                    return (0.5*val, 1- 0.5*val)
                else:
                    return( val, 1-val)

    def calculate_trans_probs(self):
        self.trans_probs = np.zeros((self.S, self.A, self.S))
        for s in range(self.S - 2): # we don't start from lost and goal state
            current_s = self.idx_to_states[s]
            for a in range(self.A):
                if a <9:
                    new_state = self.state_after_action(current_s, a)
                    if new_state != current_s:
                        r_int = int(current_s[-3:-1])
                        for i, prob_opp in enumerate(self.opp_action_probs[current_s]):
                            # now for the current_s you will get a reaction from the opponent
                            if prob_opp !=0:
                                r_str = str(self.player_pos(r_int, i)) # 'i' would give the action for R
                                if len(r_str)==1:
                                    r_str = '0' + r_str # NOTE: I hope the prob's are zero when the R is at the edge
                                next_s = new_state[:4] + r_str + new_state[-1]
                                # Now let's call a helper function to give prob. # It looks if there is tackling or intergecting etc...
                                # it's inputs would be current_s and next_s and the action taking place.
                                prob_s, prob_f = self.transition_function(current_s, next_s, a)
                                self.trans_probs[self.states_to_idx[current_s], a, self.states_to_idx[next_s]] = prob_opp*prob_s
                                self.trans_probs[self.states_to_idx[current_s], a, self.states_to_idx['lost']] = prob_opp*prob_f
                    else:
                        self.trans_probs[self.states_to_idx[current_s], a, self.states_to_idx['lost']] = 1 # regardless of what R does if you take a non feasible action then lossing is 1

                elif a ==9: # this has to be separate because state_after_action function gives 'goal' for this so u can't slice like before.
                    new_state = current_s[:]
                    for i, prob_opp in enumerate(self.opp_action_probs[current_s]):
                            if prob_opp != 0:
                                r_int = int(current_s[-3:-1])
                                r_str = str(self.player_pos(r_int, i)) # 'i' would give the action for R
                                if len(r_str)==1:
                                    r_str = '0' + r_str # NOTE: I hope the prob's are zero when the R is at the edge
                                next_s = new_state[:4] + r_str + new_state[-1]

                                prob_s, prob_f = self.transition_function(current_s, next_s, a)
                                self.trans_probs[self.states_to_idx[current_s], a, self.states_to_idx['goal']] = prob_opp*prob_s
                                self.trans_probs[self.states_to_idx[current_s], a, self.states_to_idx['lost']] = prob_opp*prob_f
        self.rewards = np.zeros((self.S, self.A, self.S))
        self.rewards[:,:,8192] = -1
        self.rewards[:,:,8193] = 1

    def save_transition_probabilities_and_rewards(self, filename):
        self.calculate_trans_probs()
        trans_probs = self.trans_probs
        rewards = self.rewards
        num_states, num_actions, _ = trans_probs.shape

        with open(filename, 'w') as file:
            file.write(f"numStates {num_states}\n")
            file.write(f"numActions {num_actions}\n")
            file.write("end 8192 8193\n")

            for s in range(num_states - 2):  # Exclude terminal states 'lost' and 'goal'
                for a in range(num_actions):
                    for s_prime in range(num_states):
                        prob = trans_probs[s, a, s_prime]
                        reward = rewards[s, a, s_prime]

                        if prob != 0 or reward != 0:
                            file.write(f"transition {s} {a} {s_prime} {prob} {reward}\n")

            file.write("mdptype episodic\n")
            file.write("discount 0.9\n")

            # Example usage:

if __name__ == "__main__":
    parser.add_argument("--opponent",type=str,default='./data/football/test-1.txt')
    parser.add_argument("--p", type=float)
    parser.add_argument("--q", type=float)

    args = parser.parse_args()

    if not (args.p <=1.0 and args.p >=0.0):
        print("p is a probability, should be btw 0,1")
        sys.exit(0)
    if not (args.q<=1.0 and args.q >=0.0):
        print("q is a probability, should be btw 0,1")
        sys.exit(0)

    enco = PlannerEncoder(args.opponent, args.p, args.q)
    enco.save_transition_probabilities_and_rewards('t-2.txt')


import socket
import random

server_address = ('127.0.0.1', 5001)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(server_address)

while True:
    data, client_address = server_socket.recvfrom(1024)

    if random.randint(0, 1):
        server_socket.sendto(data, client_address)
        print('data:', data, 'client address', client_address)
        print('sock name', server_socket.getsockname())

    else:
        print('server is down')


import pytest
import datetime
import pytz

from mixer.backend.django import mixer

from telegram_message_api.helpers import (
    ParsedData, ParseText, CategoryData,
)

@pytest.mark.parametrize(
    'text', [
        '150 test',
        '150 test 150',
        '150',
    ]
)
def test_parsetext_dataclass(text):
    """Testing a ParseText parse text method"""

    result = ParseText(text)()

    if result:
        assert result.amount == '150'
        assert result.expense == 'test'
    else:
        assert result == None

def test_categorydata_dataclass(db):
    """Testing a CategoryData"""

    category = mixer.blend('core.category')
    result = CategoryData(
        expense_text='150 test',
        category=category
    )()

    tz = pytz.timezone("Europe/Moscow")
    now = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")

    assert result == {
                        'amount': '150',
                        'created': now,
                        'category': category,
                        'expense_text': '150 test',
                     }


import pandas as pd
import tensorflow as tf
import argparse

from . import data

TRAIN_URL = data.TRAIN_URL
TEST_URL = data.TEST_URL
CSV_COLUMN_NAMES = data.CSV_COLUMN_NAMES
LABELS = data.LABELS

def maybe_download():
    train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
    test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)

    return train_path, test_path

def load_data(y_name='Labels'):
    """Returns the dataset as (train_x, train_y), (test_x, test_y)."""
    train_path, test_path = maybe_download()

    train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
    train_x, train_y = train, train.pop(y_name)

    test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)
    test_x, test_y = test, test.pop(y_name)

    return (train_x, train_y), (test_x, test_y)

def train_input_fn(features, labels, batch_size):
    """An input function for training"""
    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))

    # Shuffle, repeat, and batch the examples.
    dataset = dataset.shuffle(1000).repeat().batch(batch_size)

    # Return the dataset.
    return dataset

def eval_input_fn(features, labels, batch_size):
    """An input function for evaluation"""
    features = dict(features)
    if labels is None:
        # No labels, use only features.
        inputs = features
    else:
        inputs = (features, labels)

    # Convert the inputs to a Dataset.
    dataset = tf.data.Dataset.from_tensor_slices(inputs)

    # Batch the examples
    assert batch_size is not None, "batch_size must not be None"
    dataset = dataset.batch(batch_size)

    # Return the dataset.
    return dataset

parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=100, type=int, help='batch size')
parser.add_argument('--train_steps', default=1000,
                    type=int, help='number of training steps')

globalClassifier = None
globalArgs = None

def main(argv):
    args = parser.parse_args(argv[1:])

    # Fetch the data
    (train_x, train_y), (test_x, test_y) = load_data()

    # Feature columns describe how to use the input.
    my_feature_columns = []
    for key in train_x.keys():
        my_feature_columns.append(tf.feature_column.numeric_column(key=key))

    # Build 2 hidden layer DNN with 10, 10 units respectively.
    classifier = tf.estimator.DNNClassifier(
        feature_columns=my_feature_columns, hidden_units=[10, 10], n_classes=25)

    # Train the Model.
    classifier.train(input_fn=lambda: train_input_fn(
        train_x, train_y, args.batch_size), steps=args.train_steps)

    # Evaluate the model.
    eval_result = classifier.evaluate(
        input_fn=lambda: eval_input_fn(test_x, test_y, args.batch_size))

    # Set global variables
    global globalClassifier
    global globalArgs
    globalClassifier = classifier
    globalArgs = args

    print('\nTest set accuracy: {accuracy:0.3f}\n'.format(**eval_result))

def getModelData():
    return globalClassifier, globalArgs


from __future__ import division

from HTMLParser import HTMLParser
import os
import re

from .https_if_available import build_opener

re_url = re.compile(r'^(([a-zA-Z_-]+)://([^/]+))(/.*)?$')

def resolve_link(link, url):
    m = re_url.match(link)
    if m is not None:
        if not m.group(4):
            # http://domain -> http://domain/
            return link + '/'
        else:
            return link
    elif link[0] == '/':
        # /some/path
        murl = re_url.match(url)
        return murl.group(1) + link
    else:
        # relative/path
        if url[-1] == '/':
            return url + link
        else:
            return url + '/' + link

class ListingParser(HTMLParser):
    """Parses an HTML file and build a list of links.

    Links are stored into the 'links' set. They are resolved into absolute
    links.
    """
    def __init__(self, url):
        HTMLParser.__init__(self)

        if url[-1] != '/':
            url += '/'
        self.__url = url
        self.links = set()

    def handle_starttag(self, tag, attrs):
        if tag == 'a':
            for key, value in attrs:
                if key == 'href':
                    if not value:
                        continue
                    value = resolve_link(value, self.__url)
                    self.links.add(value)
                    break

def download_directory(url, target, insecure=False):
    def mkdir():
        if not mkdir.done:
            try:
                os.mkdir(target)
            except OSError:
                pass
            mkdir.done = True
    mkdir.done = False

    opener = build_opener(insecure=insecure)
    response = opener.open(url)

    if response.info().type == 'text/html':
        contents = response.read()

        parser = ListingParser(url)
        parser.feed(contents)
        for link in parser.links:
            link = resolve_link(link, url)
            if link[-1] == '/':
                link = link[:-1]
            if not link.startswith(url):
                continue
            name = link.rsplit('/', 1)[1]
            if '?' in name:
                continue
            mkdir()
            download_directory(link, os.path.join(target, name), insecure)
        if not mkdir.done:
            # We didn't find anything to write inside this directory
            # Maybe it's a HTML file?
            if url[-1] != '/':
                end = target[-5:].lower()
                if not (end.endswith('.htm') or end.endswith('.html')):
                    target = target + '.html'
                with open(target, 'wb') as fp:
                    fp.write(contents)
    else:
        buffer_size = 4096
        with open(target, 'wb') as fp:
            chunk = response.read(buffer_size)
            while chunk:
                fp.write(chunk)
                chunk = response.read(buffer_size)

###############################################################################

import unittest

class TestLinkResolution(unittest.TestCase):
    def test_absolute_link(self):
        self.assertEqual(
                resolve_link('http://website.org/p/test.txt',
                             'http://some/other/url'),
                'http://website.org/p/test.txt')
        self.assertEqual(
                resolve_link('http://website.org',
                             'http://some/other/url'),
                'http://website.org/')

    def test_absolute_path(self):
        self.assertEqual(
                resolve_link('/p/test.txt', 'http://some/url'),
                'http://some/p/test.txt')
        self.assertEqual(
                resolve_link('/p/test.txt', 'http://some/url/'),
                'http://some/p/test.txt')
        self.assertEqual(
                resolve_link('/p/test.txt', 'http://site'),
                'http://site/p/test.txt')
        self.assertEqual(
                resolve_link('/p/test.txt', 'http://site/'),
                'http://site/p/test.txt')

    def test_relative_path(self):
        self.assertEqual(
                resolve_link('some/file', 'http://site/folder'),
                'http://site/folder/some/file')
        self.assertEqual(
                resolve_link('some/file', 'http://site/folder/'),
                'http://site/folder/some/file')
        self.assertEqual(
                resolve_link('some/dir/', 'http://site/folder'),
                'http://site/folder/some/dir/')

class TestParser(unittest.TestCase):
    def test_parse(self):
        parser = ListingParser('http://a.remram.fr/test')
        parser.feed("""
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>
Index of /test</title>
Index of /test

	Name
	Last modified	Size
	Description

Parent Directory	 	  -

	a
11-Sep-2013 15:46  	  3

bb	11-Sep-2013 15:46
  3

	cc/
11-Sep-2013 15:46  	  -

dd/
11-Sep-2013 15:46  	  -

        """)
        links = set(l for l in parser.links if '?' not in l)
        self.assertEqual(links, set([
                'http://a.remram.fr/',
                'http://a.remram.fr/test/a',
                'http://a.remram.fr/bb',
                'http://a.remram.fr/cc/',
                'http://a.remram.fr/dd',
        ]))