#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 16 20:10:25 2018

@author: anjali
"""

import connection as conn
import pandas as pd

def read_table(table_name):
    engine = conn.connect()
    datafull = pd.read_sql_table(table_name, engine)
    return datafull, engine

def create_final_df(record):
    df = pd.DataFrame(columns=['posting_date','posting_year','posting_month',
                               'source_no','location_code',
                               'inventory_posting_group',
                               'source_posting_group','quantity',
                               'source_type','branch_code',
                               'unc_donor_code','unc_donor_class',
                               'fbc_donor_class','vendor_type'])

    #clean data
    posting_date = record['Posting_Date']
    posting_date = posting_date.replace("\"", "").strip()
    if "-" in posting_date:
        split_string = posting_date.split("-")
        year = split_string[0]
        month = split_string[1]
    elif "/" in posting_date:
        split_string = posting_date.split("/")
        year_str = split_string[2].split(" ")
        year = year_str[0]
        month = split_string[0]
        if len(month) == 1:
            month = str(0) + month
    #print(year)
    #print(month)

    location_code = record['Location_Code'].lower().replace("\"", "").strip()

    inventory_posting_grp = record['Inventory_Posting_Group'].lower().replace("\"", "").strip()

    source_posting_grp = record['Source_Posting_Group'].lower().replace("\"", "").strip()

    source_type = record['Source_Type']
    if source_type is not None:
        source_type = source_type.lower().replace("\"", "").strip()

    branch_code = record['Branch_Code'].lower().replace("\"", "").strip()

    unc_donor_code = record['UNC_Donor_ID_Code']

    unc_donor_class = record['UNC_Donor_Class_of_Trade_Code'].lower().replace("\"", "").strip()

    fbc_donor_class = record['FBC_Donor_Class_of_Trade'].lower().replace("\"", "").strip()

    vendor_type = record['Vendor_Type'].lower().replace("\"", "").strip()

    #insert data to dataframe
    list_data = pd.DataFrame([[posting_date, year, month,
                               int(record['Source_No_']),
                               location_code, inventory_posting_grp,
                               source_posting_grp, int(record['Quantity']),
                               source_type, branch_code, int(unc_donor_code),
                               unc_donor_class, fbc_donor_class,vendor_type]],
                               columns=['posting_date','posting_year',
                                         'posting_month',
                                         'source_no','location_code',
                                         'inventory_posting_group',
                                         'source_posting_group','quantity',
                                         'source_type','branch_code',
                                         'unc_donor_code','unc_donor_class',
                                         'fbc_donor_class','vendor_type'])
    df = df.append(list_data, ignore_index=True)
    return df

def add_to_table(df, engine, final_name):
    df.to_sql(name=final_name, con=engine, if_exists='append', index=False)

def clean_purchase_data():
    purchase_data_df, engine = read_table('purchase_data_0617')
    print("Records fetched = " + str(len(purchase_data_df)))

    for count in range(len(purchase_data_df)):
        record = purchase_data_df.iloc[count]
        df = create_final_df(record)
        add_to_table(df, engine, 'purchase_data')

    print("Finished inserting data to purchase_data")

def clean_distribution_data():
    dist_data_df, engine = read_table('distribution_data_0617')
    print("Records fetched = " + str(len(dist_data_df)))

    for count in range(len(dist_data_df)):
        record = dist_data_df.iloc[count]
        df = create_final_df(record)
        add_to_table(df, engine, 'distribution_data')

    print("Finished inserting data to distribution_data")

def clean_transfer_data():
    dist_data_df, engine = read_table('transfer_data_0617')
    print("Records fetched = " + str(len(dist_data_df)))

    for count in range(len(dist_data_df)):
        record = dist_data_df.iloc[count]
        df = create_final_df(record)
        add_to_table(df, engine, 'transfer_data')

    print("Finished inserting data to transfer_data")

def clean_all_data():
    dist_data_df, engine = read_table('FY_data_0617')
    print("Records fetched = " + str(len(dist_data_df)))

    for count in range(len(dist_data_df)):
        record = dist_data_df.iloc[count]
        df = create_final_df(record)
        add_to_table(df, engine, 'FY_data')

    print("Finished inserting data to FY_data")

#clean_purchase_data()
#clean_distribution_data()
#clean_transfer_data()
#clean_all_data()


# -*- coding: utf-8 -*-
"""
Created on Sat Apr 15 20:42:32 2023

@author: joseph.m.pedersen

A script for sending Outlook emails via Python. (basic template)

Stack Overflow posts I looked up for this:

https://stackoverflow.com/questions/6332577/send-outlook-email-via-python

https://stackoverflow.com/questions/36400683/adding-attachment-to-email-through-outlook-python

Outlook item types:
https://learn.microsoft.com/en-us/office/vba/api/outlook.olitemtype
"""

import win32com.client as win32

outlook = win32.Dispatch('outlook.application')

# create new mail message
mail = outlook.CreateItem(0) # OlItemType 0 is an email
mail.To = 'put_your_email_address_here@gmail.com'
mail.Subject = 'Message sent by Python'

# Create either `mail.HTMLBody` or `mail.Body` (not both)
#mail.HTMLBody = """
HTML Message body
"""
mail.Body = """Dear Me,

I am using Python to send you an email.  This is just for practice.

Best regards,
You
"""

# To attach file(s) to the email (optional):
# list the paths to attachments (use empty list for no attachments)
attachments = [r'C:\Users\YourFirst.YourLast\Desktop'
               r'\YourFolder\file1.txt',
               r'C:\Users\YourFirst.YourLast\Desktop'
               r'\YourFolder\file2.txt',]

# add each attachment
for file_path in attachments:
    mail.Attachments.Add(file_path)

# send the message
mail.Send()


from sparknlp.common import *

class GraphExtraction(AnnotatorModel):
    """Extracts a dependency graph between entities.

    The GraphExtraction class takes e.g. extracted entities from a
    :class:`.NerDLModel` and creates a dependency tree which describes how the
    entities relate to each other. For that a triple store format is used. Nodes
    represent the entities and the edges represent the relations between those
    entities. The graph can then be used to find relevant relationships between
    words.

    Both the :class:`.DependencyParserModel` and
    :class:`.TypedDependencyParserModel` need to be
    present in the pipeline. There are two ways to set them:

    #. Both Annotators are present in the pipeline already. The dependencies are
       taken implicitly from these two Annotators.
    #. Setting :meth:`.setMergeEntities` to ``True`` will download the
       default pretrained models for those two Annotators automatically. The
       specific models can also be set with :meth:`.setDependencyParserModel`
       and :meth:`.setTypedDependencyParserModel`:

        >>> graph_extraction = GraphExtraction() \\
        ...     .setInputCols(["document", "token", "ner"]) \\
        ...     .setOutputCol("graph") \\
        ...     .setRelationshipTypes(["prefer-LOC"]) \\
        ...     .setMergeEntities(True)
        >>>     #.setDependencyParserModel(["dependency_conllu", "en",  "public/models"])
        >>>     #.setTypedDependencyParserModel(["dependency_typed_conllu", "en",  "public/models"])

    ================================= ======================
    Input Annotation types            Output Annotation type
    ================================= ======================
    ``DOCUMENT, TOKEN, NAMED_ENTITY`` ``NODE``
    ================================= ======================

    Parameters
    ----------
    relationshipTypes
        Paths to find between a pair of token and entity
    entityTypes
        Paths to find between a pair of entities
    explodeEntities
        When set to true find paths between entities
    rootTokens
        Tokens to be consider as root to start traversing the paths. Use it
        along with explodeEntities
    maxSentenceSize
        Maximum sentence size that the annotator will process, by default 1000.
        Above this, the sentence is skipped
    minSentenceSize
        Minimum sentence size that the annotator will process, by default 2.
        Below this, the sentence is skipped.
    mergeEntities
        Merge same neighboring entities as a single token
    includeEdges
        Whether to include edges when building paths
    delimiter
        Delimiter symbol used for path output
    posModel
        Coordinates (name, lang, remoteLoc) to a pretrained POS model
    dependencyParserModel
        Coordinates (name, lang, remoteLoc) to a pretrained Dependency Parser
        model
    typedDependencyParserModel
        Coordinates (name, lang, remoteLoc) to a pretrained Typed Dependency
        Parser model

    Examples
    --------
    >>> import sparknlp
    >>> from sparknlp.base import *
    >>> from sparknlp.annotator import *
    >>> from pyspark.ml import Pipeline
    >>> documentAssembler = DocumentAssembler() \\
    ...     .setInputCol("text") \\
    ...     .setOutputCol("document")
    >>> sentence = SentenceDetector() \\
    ...     .setInputCols(["document"]) \\
    ...     .setOutputCol("sentence")
    >>> tokenizer = Tokenizer() \\
    ...     .setInputCols(["sentence"]) \\
    ...     .setOutputCol("token")
    >>> embeddings = WordEmbeddingsModel.pretrained() \\
    ...     .setInputCols(["sentence", "token"]) \\
    ...     .setOutputCol("embeddings")
    >>> nerTagger = NerDLModel.pretrained() \\
    ...     .setInputCols(["sentence", "token", "embeddings"]) \\
    ...     .setOutputCol("ner")
    >>> posTagger = PerceptronModel.pretrained() \\
    ...     .setInputCols(["sentence", "token"]) \\
    ...     .setOutputCol("pos")
    >>> dependencyParser = DependencyParserModel.pretrained() \\
    ...     .setInputCols(["sentence", "pos", "token"]) \\
    ...     .setOutputCol("dependency")
    >>> typedDependencyParser = TypedDependencyParserModel.pretrained() \\
    ...     .setInputCols(["dependency", "pos", "token"]) \\
    ...     .setOutputCol("dependency_type")
    >>> graph_extraction = GraphExtraction() \\
    ...     .setInputCols(["document", "token", "ner"]) \\
    ...     .setOutputCol("graph") \\
    ...     .setRelationshipTypes(["prefer-LOC"])
    >>> pipeline = Pipeline().setStages([
    ...     documentAssembler,
    ...     sentence,
    ...     tokenizer,
    ...     embeddings,
    ...     nerTagger,
    ...     posTagger,
    ...     dependencyParser,
    ...     typedDependencyParser,
    ...     graph_extraction
    ... ])
    >>> data = spark.createDataFrame([["You and John prefer the morning flight through Denver"]]).toDF("text")
    >>> result = pipeline.fit(data).transform(data)
    >>> result.select("graph").show(truncate=False)
    +-----------------------------------------------------------------------------------------------------------------+
    |graph                                                                                |
    +-----------------------------------------------------------------------------------------------------------------+
    |[[node, 13, 18, prefer, [relationship -> prefer,LOC, path1 -> prefer,nsubj,morning,flat,flight,flat,Denver], []]]|
    +-----------------------------------------------------------------------------------------------------------------+

    See Also
    --------
    GraphFinisher : to output the paths in a more generic format, like RDF
    """
    name = "GraphExtraction"

    inputAnnotatorTypes = [AnnotatorType.DOCUMENT, AnnotatorType.TOKEN, AnnotatorType.NAMED_ENTITY]

    optionalInputAnnotatorTypes = [AnnotatorType.DEPENDENCY, AnnotatorType.LABELED_DEPENDENCY]

    outputAnnotatorType = AnnotatorType.NODE

    relationshipTypes = Param(Params._dummy(),
                              "relationshipTypes",
                              "Find paths between a pair of token and entity",
                              typeConverter=TypeConverters.toListString)

    entityTypes = Param(Params._dummy(),
                        "entityTypes",
                        "Find paths between a pair of entities",
                        typeConverter=TypeConverters.toListString)

    explodeEntities = Param(Params._dummy(),
                            "explodeEntities",
                            "When set to true find paths between entities",
                            typeConverter=TypeConverters.toBoolean)

    rootTokens = Param(Params._dummy(),
                       "rootTokens",
                       "Tokens to be consider as root to start traversing the paths. Use it along with explodeEntities",
                       typeConverter=TypeConverters.toListString)

    maxSentenceSize = Param(Params._dummy(),
                            "maxSentenceSize",
                            "Maximum sentence size that the annotator will process. Above this, the sentence is skipped",
                            typeConverter=TypeConverters.toInt)

    minSentenceSize = Param(Params._dummy(),
                            "minSentenceSize",
                            "Minimum sentence size that the annotator will process. Above this, the sentence is skipped",
                            typeConverter=TypeConverters.toInt)

    mergeEntities = Param(Params._dummy(),
                          "mergeEntities",
                          "Merge same neighboring entities as a single token",
                          typeConverter=TypeConverters.toBoolean)

    mergeEntitiesIOBFormat = Param(Params._dummy(),
                                   "mergeEntitiesIOBFormat",
                                   "IOB format to apply when merging entities",
                                   typeConverter=TypeConverters.toString)

    includeEdges = Param(Params._dummy(),
                         "includeEdges",
                         "Whether to include edges when building paths",
                         typeConverter=TypeConverters.toBoolean)

    delimiter = Param(Params._dummy(),
                      "delimiter",
                      "Delimiter symbol used for path output",
                      typeConverter=TypeConverters.toString)

    posModel = Param(Params._dummy(),
                     "posModel",
                     "Coordinates (name, lang, remoteLoc) to a pretrained POS model",
                     typeConverter=TypeConverters.toListString)

    dependencyParserModel = Param(Params._dummy(),
                                  "dependencyParserModel",
                                  "Coordinates (name, lang, remoteLoc) to a pretrained Dependency Parser model",
                                  typeConverter=TypeConverters.toListString)

    typedDependencyParserModel = Param(Params._dummy(),
                                       "typedDependencyParserModel",
                                       "Coordinates (name, lang, remoteLoc) to a pretrained Typed Dependency Parser model",
                                       typeConverter=TypeConverters.toListString)

    def setRelationshipTypes(self, value):
        """Sets paths to find between a pair of token and entity.

        Parameters
        ----------
        value : List[str]
            Paths to find between a pair of token and entity
        """
        return self._set(relationshipTypes=value)

    def setEntityTypes(self, value):
        """Sets paths to find between a pair of entities.

        Parameters
        ----------
        value : List[str]
            Paths to find between a pair of entities
        """
        return self._set(entityTypes=value)

    def setExplodeEntities(self, value):
        """Sets whether to find paths between entities.

        Parameters
        ----------
        value : bool
            Whether to find paths between entities.
        """
        return self._set(explodeEntities=value)

    def setRootTokens(self, value):
        """Sets tokens to be considered as the root to start traversing the paths.

        Use it along with explodeEntities.

        Parameters
        ----------
        value : List[str]
            Sets Tokens to be consider as root to start traversing the paths.
        """
        return self._set(rootTokens=value)

    def setMaxSentenceSize(self, value):
        """Sets Maximum sentence size that the annotator will process, by
        default 1000.

        Above this, the sentence is skipped.

        Parameters
        ----------
        value : int
            Maximum sentence size that the annotator will process
        """
        return self._set(maxSentenceSize=value)

    def setMinSentenceSize(self, value):
        """Sets Minimum sentence size that the annotator will process, by
        default 2.

        Below this, the sentence is skipped.

        Parameters
        ----------
        value : int
            Minimum sentence size that the annotator will process
        """
        return self._set(minSentenceSize=value)

    def setMergeEntities(self, value):
        """Sets whether to merge same neighboring entities as a single token.

        Parameters
        ----------
        value : bool
            Whether to merge same neighboring entities as a single token.
        """
        return self._set(mergeEntities=value)

    def setMergeEntitiesIOBFormat(self, value):
        """Sets IOB format to apply when merging entities.

        Parameters
        ----------
        value : str
            IOB format to apply when merging entities. Values IOB or IOB2
        """
        return self._set(mergeEntitiesIOBFormat=value)

    def setIncludeEdges(self, value):
        """Sets whether to include edges when building paths.

        Parameters
        ----------
        value : bool
            Whether to include edges when building paths
        """
        return self._set(includeEdges=value)

    def setDelimiter(self, value):
        """Sets delimiter symbol used for path output.

        Parameters
        ----------
        value : str
            Delimiter symbol used for path output
        """
        return self._set(delimiter=value)

    def setPosModel(self, value):
        """Sets Coordinates (name, lang, remoteLoc) to a pretrained POS model.

        Parameters
        ----------
        value : List[str]
            Coordinates (name, lang, remoteLoc) to a pretrained POS model
        """
        return self._set(posModel=value)

    def setDependencyParserModel(self, value):
        """Sets Coordinates (name, lang, remoteLoc) to a pretrained Dependency
        Parser model.

        Parameters
        ----------
        value : List[str]
            Coordinates (name, lang, remoteLoc) to a pretrained Dependency
            Parser model
        """
        return self._set(dependencyParserModel=value)

    def setTypedDependencyParserModel(self, value):
        """Sets Coordinates (name, lang, remoteLoc) to a pretrained Typed
        Dependency Parser model.

        Parameters
        ----------
        value : List[str]
            Coordinates (name, lang, remoteLoc) to a pretrained Typed Dependency
            Parser model
        """
        return self._set(typedDependencyParserModel=value)

    @keyword_only
    def __init__(self, classname="com.johnsnowlabs.nlp.annotators.GraphExtraction", java_model=None):
        super(GraphExtraction, self).__init__(
            classname=classname,
            java_model=java_model
        )
        self._setDefault(
            maxSentenceSize=1000,
            minSentenceSize=2
        )


"""
"""

import os
from hashlib import md5
import cPickle as pickle
from functools import wraps
import unittest
import shutil
import requests
import httpretty

DEFAULT_CACHE_DIR = "cache"

class HTTPCache(object):
	"""
	"""

	def __init__(self, cache_dir=DEFAULT_CACHE_DIR):
		"""
		"""
		self.cache_dir = cache_dir

	def __repr__(self):
		return "<%s dir=%r>" % (
			self.__class__.__name__,
			self.cache_dir)

	def _hash(self, url, params=None, data=None):
		"""
		"""
		params = params or {}
		data = data or {}

		key = "".join(map(str, [url, params, data]))
		return md5(key).hexdigest()

	def _build_cache_path(self, *args, **kwargs):
		"""
		"""
		return os.path.join(
			self.cache_dir, self._hash(*args, **kwargs))

	def _serialize(self, resp):
		"""
		"""
		return pickle.dumps(resp)

	def _deserialize(self, data):
		"""
		"""
		return pickle.loads(data)

	def __delitem__(self, req):
		"""
		"""
		if not isinstance(req, tuple):
			req = (req, )

		os.remove(self._build_cache_path(*req))

	def __getitem__(self, req):
		"""
		"""
		if not isinstance(req, tuple):
			req = (req, )

		if not req in self:
			return

		path = self._build_cache_path(*req)
		with open(path, "rb") as f:
			return self._deserialize(f.read())

	def __setitem__(self, req, resp):
		"""
		"""
		if not isinstance(req, tuple):
			req = (req, )

		if self.cache_dir:
			if not os.path.isdir(self.cache_dir):
				os.makedirs(self.cache_dir)

		path = self._build_cache_path(*req)
		with open(path, "wb") as f:
			f.write(self._serialize(resp))

	def __contains__(self, req):
		"""
		"""
		if not isinstance(req, tuple):
			req = (req, )

		return os.path.isfile(
			self._build_cache_path(*req))

def cached(f):
	"""
	"""
	@wraps(f)
	def inner(
		url,
		data=None,
		params=None,
		cache=None,
		*args,
		**kwargs):
		if cache is None:
			cache = HTTPCache()

		params = params or {}
		data = data or {}

		req = (url, params, data)
		if req in cache:
			return cache[req]

		resp = f(
			url,
			data=data,
			params=params,
			*args,
			**kwargs)
		cache[req] = resp
		return resp

	return inner

@cached
def post(*args, **kwargs):
	"""
	"""
	return requests.post(*args, **kwargs)

@cached
def get(*args, **kwargs):
	"""
	"""
	return requests.get(*args, **kwargs)

class TestHTTPCache(unittest.TestCase):
	"""
	"""

	@classmethod
	def setUpClass(cls):
		"""
		"""
		cls._cache = HTTPCache("test_cache")

		httpretty.register_uri(
			httpretty.GET,
			"http://a.com",
			body="a" * 5)

		httpretty.register_uri(
			httpretty.POST,
			"http://b.com",
			body="b" * 5)

	@classmethod
	def tearDownClass(cls):
		"""
		"""
		shutil.rmtree(cls._cache.cache_dir)

	def setUp(self):
		"""
		"""
		httpretty.enable()

	def tearDown(self):
		"""
		"""
		httpretty.reset()
		httpretty.disable()

	def test_1_sends_request_if_not_in_cache(self):
		"""
		"""
		resp = get(
			"http://a.com",
			cache=self._cache)
		self.assertTrue(httpretty.has_request())

		resp = post(
			"http://b.com",
			data={"b": 2},
			cache=self._cache)
		self.assertTrue(httpretty.has_request())

	def test_2_loads_response_from_cache(self):
		"""
		"""
		resp = get(
			"http://a.com",
			cache=self._cache)
		cached = self._cache["http://a.com"]

		self.assertFalse(httpretty.has_request())
		self.assertEquals(cached.text, "a" * 5)

		resp = post(
			"http://b.com",
			data={"b": 2},
			cache=self._cache)
		cached = self._cache[("http://b.com", {}, {"b": 2})]

		self.assertFalse(httpretty.has_request())
		self.assertEquals(cached.text, "b" * 5)

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


import install_requirements
import casino
import pygame
import sys
import os
import math
import time
import tkinter as tk
from tkinter import messagebox

pygame.init()
cardBack = pygame.image.load(os.path.join('png', 'cardBack.png'))
screen = pygame.display.set_mode((1300, 900))
pygame.display.set_caption('Black Jack')
clock = pygame.time.Clock()
myfont = pygame.font.SysFont('monospace', 70)
smallFont = pygame.font.SysFont('monospace', 30)
bg = pygame.image.load(os.path.join('back', 'background.jpg'))
screen.fill((0,128,0))
clock = pygame.time.Clock()
deck = casino.cards()
cardList = deck.getCards()
d = casino.dealer(cardList)
p = casino.player(cardList)

pygame.display.flip()

onTable = []
topCards = []

cardImg = [None]
    # Load 52 Images
two_clubs = pygame.image.load(os.path.join('png', '2_of_clubs.png'))
two_diamonds = pygame.image.load(os.path.join('png', '2_of_diamonds.png'))
two_hearts = pygame.image.load(os.path.join('png', '2_of_hearts.png'))
two_spades = pygame.image.load(os.path.join('png', '2_of_spades.png'))

three_clubs = pygame.image.load(os.path.join('png', '3_of_clubs.png'))
three_spades = pygame.image.load(os.path.join('png', '3_of_spades.png'))
three_diamonds = pygame.image.load(os.path.join('png', '3_of_diamonds.png'))
three_hearts = pygame.image.load(os.path.join('png', '3_of_hearts.png'))

four_clubs = pygame.image.load(os.path.join('png', '4_of_clubs.png'))
four_spades = pygame.image.load(os.path.join('png', '4_of_spades.png'))
four_diamonds = pygame.image.load(os.path.join('png', '4_of_diamonds.png'))
four_hearts = pygame.image.load(os.path.join('png', '4_of_hearts.png'))

five_clubs = pygame.image.load(os.path.join('png', '5_of_clubs.png'))
five_spades = pygame.image.load(os.path.join('png', '5_of_spades.png'))
five_diamonds = pygame.image.load(os.path.join('png', '5_of_diamonds.png'))
five_hearts = pygame.image.load(os.path.join('png', '5_of_hearts.png'))

six_clubs = pygame.image.load(os.path.join('png', '6_of_clubs.png'))
six_spades = pygame.image.load(os.path.join('png', '6_of_spades.png'))
six_diamonds = pygame.image.load(os.path.join('png', '6_of_diamonds.png'))
six_hearts = pygame.image.load(os.path.join('png', '6_of_hearts.png'))

seven_clubs = pygame.image.load(os.path.join('png', '7_of_clubs.png'))
seven_spades = pygame.image.load(os.path.join('png', '7_of_spades.png'))
seven_diamonds = pygame.image.load(os.path.join('png', '7_of_diamonds.png'))
seven_hearts = pygame.image.load(os.path.join('png', '7_of_hearts.png'))

eight_clubs = pygame.image.load(os.path.join('png', '8_of_clubs.png'))
eight_spades = pygame.image.load(os.path.join('png', '8_of_spades.png'))
eight_diamonds = pygame.image.load(os.path.join('png', '8_of_diamonds.png'))
eight_hearts = pygame.image.load(os.path.join('png', '8_of_hearts.png'))

nine_clubs = pygame.image.load(os.path.join('png', '9_of_clubs.png'))
nine_spades = pygame.image.load(os.path.join('png', '9_of_spades.png'))
nine_diamonds = pygame.image.load(os.path.join('png', '9_of_diamonds.png'))
nine_hearts = pygame.image.load(os.path.join('png', '9_of_hearts.png'))

ten_clubs = pygame.image.load(os.path.join('png', '10_of_clubs.png'))
ten_spades = pygame.image.load(os.path.join('png', '10_of_diamonds.png'))
ten_diamonds = pygame.image.load(os.path.join('png', '10_of_hearts.png'))
ten_hearts = pygame.image.load(os.path.join('png', '10_of_spades.png'))

jack_clubs = pygame.image.load(os.path.join('png', 'jack_of_clubs.png'))
jack_spades = pygame.image.load(os.path.join('png', 'jack_of_spades.png'))
jack_diamonds = pygame.image.load(os.path.join('png', 'jack_of_diamonds.png'))
jack_hearts = pygame.image.load(os.path.join('png', 'jack_of_hearts.png'))

queen_clubs = pygame.image.load(os.path.join('png', 'queen_of_clubs.png'))
queen_spades = pygame.image.load(os.path.join('png', 'queen_of_spades.png'))
queen_diamonds = pygame.image.load(os.path.join('png', 'queen_of_diamonds.png'))
queen_hearts = pygame.image.load(os.path.join('png', 'queen_of_hearts.png'))

king_clubs = pygame.image.load(os.path.join('png', 'king_of_clubs.png'))
king_spades = pygame.image.load(os.path.join('png', 'king_of_spades.png'))
king_diamonds = pygame.image.load(os.path.join('png', 'king_of_diamonds.png'))
king_hearts = pygame.image.load(os.path.join('png', 'king_of_hearts.png'))

ace_clubs = pygame.image.load(os.path.join('png', 'ace_of_clubs.png'))
ace_spades = pygame.image.load(os.path.join('png', 'ace_of_spades.png'))
ace_diamonds = pygame.image.load(os.path.join('png', 'ace_of_diamonds.png'))
ace_hearts = pygame.image.load(os.path.join('png', 'ace_of_hearts.png'))

cardImg.append([ace_clubs, ace_diamonds, ace_hearts, ace_spades])
cardImg.append([two_clubs, two_diamonds, two_hearts, two_spades])
cardImg.append([three_clubs, three_diamonds, three_hearts, three_spades])
cardImg.append([four_clubs, four_diamonds, four_hearts, four_spades])
cardImg.append([five_clubs, five_diamonds, five_hearts, five_spades])
cardImg.append([six_clubs, six_diamonds, six_hearts, six_spades])
cardImg.append([seven_clubs, seven_diamonds, seven_hearts, seven_spades])
cardImg.append([eight_clubs, eight_diamonds, eight_hearts, eight_spades])
cardImg.append([nine_clubs, nine_diamonds, nine_hearts, nine_spades])
cardImg.append([ten_clubs, ten_diamonds, ten_hearts, ten_spades])
cardImg.append([jack_clubs, jack_diamonds, jack_hearts, jack_spades])
cardImg.append([queen_clubs, queen_diamonds, queen_hearts, queen_spades])
cardImg.append([king_clubs, king_diamonds, king_hearts, king_spades])

one = pygame.image.load(os.path.join('chips', '1.png'))
two = pygame.image.load(os.path.join('chips', '2.png'))
five = pygame.image.load(os.path.join('chips', '5.png'))
ten = pygame.image.load(os.path.join('chips', '10.png'))
twenty = pygame.image.load(os.path.join('chips', '20.png'))

didBet = False
betChips = 0
chips = []
betArray = []
playerChips = 50

chips.append([one, 20, 225, 1])
chips.append([two, 20, 300, 2])
chips.append([five, 20, 375, 5])
chips.append([ten, 20, 450, 10])
chips.append([twenty, 20, 525, 20])

def lost():
    screen.fill((0,128,0))
    label = myfont.render('Press any key to play again', 1, (255,255,255))
    label2 = myfont.render('Out of Chips...', 1, (255,255,255))
    screen.blit(label, (100, 450))
    screen.blit(label2, (350, 350))
    pygame.display.update()
    while True:
        ev = pygame.event.poll()
        if ev.type == pygame.KEYDOWN:
            firstStart()
            break
        if ev.type == pygame.QUIT:
            pygame.quit()

def bet():
    global betChips
    global playerChips
    label = myfont.render('Please place your bet: ', 1, (255,255,255))
    screen.blit(label, (230, 430))
    updateChips()
    pygame.display.update()
    while True:
        label = smallFont.render('Press space when finished', 1, (255, 255, 255))
        screen.blit(label, (430, 850))
        updateChips()
        pygame.display.update()
        ev = pygame.event.poll()
        if ev.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            for i in range(len(chips)):
                if pos[0] > chips[i][1] and pos[0] < chips[i][1] + 50:
                    if pos[1] > chips[i][2] and pos[1] < chips[i][2] + 50:
                        if playerChips - chips[i][3] >= 0:
                            betChips += chips[i][3]
                            dealChips(chips[i][0], 525 + i * 50, 550, chips[i][1], chips[i][2])
                            playerChips -= chips[i][3]
                        else:
                            root = tk.Tk()
                            messagebox.showinfo('Not enough chips!', ('You do not have enough \n chips to bet that amount, \n your current amount of chips is ' + str(playerChips)))
                            try:
                                root.destroy()
                            except:
                                pass
        if ev.type == pygame.QUIT:
            pygame.quit()
        if ev.type == pygame.KEYDOWN:
            if betChips >= 1:
                pygame.draw.rect(screen, (0, 128, 0), (429, 849, 600, 100))
                break

def drawChip(img, x, y):
    w = 50
    h = 50
    newIMG = pygame.transform.scale(img, (w, h))
    screen.blit(newIMG, (x,y))

def firstStart():
    global playerChips
    reset()
    playerChips = 50
    screen.fill((0,128,0))
    label = myfont.render('Welcome to Black Jack!', 1, (255, 255, 255))
    label2 = myfont.render('Press space to start', 1, (255,255,255))
    screen.blit(label2, (225, 550))
    screen.blit(label, (175, 400))
    pygame.display.update()
    pygame.init()

    while True:
        clock.tick(60)
        ev = pygame.event.poll()
        if ev.type == pygame.QUIT:
            pygame.quit()
        if ev.type == pygame.KEYDOWN:
            dealplayer(675, 650)
            dealplayer(500, 650)
            dealplayer(675, 50)
            dealplayer(500, 50)
            bet()
            main()

def restart():
    global playerChips
    screen.fill((0,128,0))
    pygame.display.update()
    pygame.init()

    if playerChips == 0:
        lost()

    while True:
        clock.tick(60)
        dealplayer(675, 650)
        dealplayer(500, 650)
        dealplayer(675, 50)
        dealplayer(500, 50)
        bet()
        main()

def reset():
    global onTable
    global cardImg
    global topCards
    global didBet
    global betChips
    global betArray
    betArray = []
    onTable = []
    topCards = []
    didBet = False
    betChips = 0
    time.sleep(1)

def dealChips(img, x, y, s, w):
    endx = x
    endy = y
    movex = s
    movey = w
    x_dist = x - s
    y_dist = y - w
    constant_x = x_dist / 50
    constant_y = y_dist / 30

    for i in range(100):
        if movey >= endy and movex >= endx:
            break
        else:
            screen.fill((0, 128, 0))
            drawChip(img, movex, movey)
            if movex <= endx:
                movex += constant_x
            if movey <= endy:
                movey += constant_y

        for d in range(len(onTable)):
            drawCard(onTable[d][0], onTable[d][1], onTable[d][2])

        for i in range(len(chips)):
            drawChip(chips[i][0], chips[i][1], chips[i][2])

        for q in range(len(betArray)):
            drawChip(betArray[q][0], betArray[q][1], betArray[q][2])

        clock.tick(50)
        drawCard(cardBack, 15, 15)
        updateChips()
        pygame.display.update()

    betArray.append([img, movex, movey])

def dealplayer(x,y):
    endx = x
    endy = y
    movex = 0
    movey = 0

    h = math.sqrt(endx**2 + endy**2)

    for i in range(round(h / 10)):
        screen.fill((0, 128, 0))
        movex += endx / (h/10)
        movey += endy / (h/10)
        drawCard(cardBack, movex, movey)
        for d in range(len(onTable)):
            drawCard(onTable[d][0], onTable[d][1], onTable[d][2])

        for i in range(len(chips)):
            drawChip(chips[i][0], chips[i][1], chips[i][2])

        for w in range(len(betArray)):
            drawChip(betArray[w][0], betArray[w][1], betArray[w][2])

        clock.tick(50)
        drawCard(cardBack, 15, 15)
        updateChips()
        pygame.display.update()

    onTable.append([cardBack, x, y])

def dealplayerHit(hit,x,y):
    endx = x
    endy = y
    movex = 0
    movey = 0

    h = math.sqrt(endx**2 + endy**2)

    for i in range(round(h / 10)):
        screen.fill((0, 128, 0))
        updateChips()
        movex += endx / (h/10)
        movey += endy / (h/10)
        drawCard(cardBack, movex, movey)
        for d in range(len(onTable)):
            drawCard(onTable[d][0], onTable[d][1], onTable[d][2])
        for i in range(len(chips)):
            drawChip(chips[i][0], chips[i][1], chips[i][2])

        for w in range(len(betArray)):
            drawChip(betArray[w][0], betArray[w][1], betArray[w][2])
        drawCard(cardBack, 15, 15)
        clock.tick(50)
        pygame.display.update()

    onTable.append([hit, x, y])

def cardImage(n, suit):

    if suit == 'C':
        return cardImg[n][0]
    elif suit == 'D':
        return cardImg[n][1]
    elif suit == 'H':
        return cardImg[n][2]
    elif suit == 'S':
        return cardImg[n][3]

def updateChips():
    global playerChips
    pygame.draw.rect(screen, (0,128,0), (39, 585, 200, 40), 0)
    label = smallFont.render('Chips: ' + str(playerChips), 1, (255,255,255))
    screen.blit(label, (10, 585))

def updateScore(turn=False):
    dScore = d.getScore()
    pScore = p.getScore()
    score1 = smallFont.render(str(dScore), 1, (255,255,255))
    score2 = smallFont.render(str(pScore), 1, (255, 255, 255))
    screen.blit(score2, (1150, 700))
    if turn:
        screen.blit(score1, (1150, 50))

def drawCard(img, x, y):
    white = (255, 255, 255)
    w = 130
    h = 181
    pygame.draw.rect(screen, white, (x - 5, y - 4, w + 10, h + 8), 0)
    newIMG = pygame.transform.scale(img, (w, h))
    screen.blit(newIMG, (x,y))

def main():
    # DRAWING AND INIT
    # VARIABLES
    global d
    global p
    global playerChips
    deck = casino.cards()
    cardList = deck.getCards()
    d = casino.dealer(cardList)
    p = casino.player(cardList)
    playerCards = p.deal()
    dealerCards = d.deal()
    allowHit = False
    playerReveal = False
    playerTurn = True
    playerStay = False
    onTable[2] = [cardImage(dealerCards[0][0], dealerCards[0][1]), 675, 50]
    onTable[3] = [cardBack, 500, 50]
    while True:

        pygame.display.update()
        clock.tick(60)
        # PLAYER DECISION
        if playerReveal == False:
            drawCard(cardBack, 675, 650)
            drawCard(cardBack, 500, 650)
            label = smallFont.render('Press space to reveal cards', 1, (255,255,255))
            screen.blit(label, (430, 850))
            ev = pygame.event.poll()
            if ev.type == pygame.QUIT:
                pygame.quit()
            if ev.type == pygame.KEYDOWN:
                if ev.key == pygame.K_SPACE:
                    # Show cards
                    playerReveal = True
                    allowHit = True
                    drawCard(cardImage(playerCards[0][0], playerCards[0][1]), 675, 650)
                    drawCard(cardImage(playerCards[1][0], playerCards[1][1]), 500, 650)
                    onTable[0] = [cardImage(playerCards[0][0], playerCards[0][1]), 675, 650]
                    onTable[1] = [cardImage(playerCards[1][0], playerCards[1][1]), 500, 650]
                    pygame.draw.rect(screen, (0, 128, 0), (429, 849, 550, 100))
            pygame.display.update()
        else:
            label = smallFont.render('Press space to hit and tab to stay', 1, (255, 255, 255))
            screen.blit(label, (350, 850))
            updateScore()
            pygame.display.update()

            ev = pygame.event.poll()
            if ev.type == pygame.QUIT:
                pygame.quit()
            if ev.type == pygame.KEYDOWN:
                if ev.key == pygame.K_TAB:
                    playerStay = True
                    updateScore(True)
                if ev.key == pygame.K_SPACE:

                    if allowHit:
                        hitCard = p.hit()
                        if len(p.cards) == 3:
                            dealplayerHit(cardImage(hitCard[0], hitCard[1]), 325, 650)
                            drawCard(cardImage(hitCard[0], hitCard[1]), 325, 650)
                            updateScore()
                        elif len(p.cards) == 4:
                            dealplayerHit(cardImage(hitCard[0], hitCard[1]), 850, 650)
                            drawCard(cardImage(hitCard[0], hitCard[1]), 850, 650)
                            updateScore()
                        elif len(p.cards) == 5:
                            dealplayerHit(cardImage(hitCard[0], hitCard[1]), 150, 650)
                            drawCard(cardImage(hitCard[0], hitCard[1]), 150, 650)
                            updateScore()
                        elif len(p.cards) == 6:
                            dealplayerHit(cardImage(hitCard[0], hitCard[1]), 1025, 650)
                            drawCard(cardImage(hitCard[0], hitCard[1]), 1025, 650)
                            updateScore()
                    allowHit = True
                    pygame.display.update()

            if p.getScore() > 21:
                label = myfont.render('You Went Over 21 :(', 1, (255,255,255))
                screen.blit(label, (300, 430))
                allowHit = False
                updateChips()
                pygame.display.update()
                time.sleep(1)
                pygame.draw.rect(screen, (0,128,0), (0, 640, 1300,200))
                pygame.draw.rect(screen, (0, 128, 0), (200, 40, 1300, 200))
                pygame.display.update()
                break

            elif p.getScore() == 21 and len(p.cards) == 2:
                allowHit = False
                playerChips += betChips * 3
                label = myfont.render('BLACK JACK!', 1, (255, 255, 255))
                screen.blit(label, (420, 430))
                updateChips()
                pygame.display.update()
                time.sleep(1)
                pygame.draw.rect(screen, (0, 128, 0), (0, 640, 1300, 200))
                pygame.draw.rect(screen, (0, 128, 0), (200, 40, 1300, 200))
                pygame.display.update()
                break

            elif playerStay:
                playerTurn = False
                allowHit = False
                updateScore()
                pygame.display.update()

# ---------------------------------------------------------------------------------------------------------
        # DEALER

        if playerTurn == False:
            drawCard(cardImage(dealerCards[1][0], dealerCards[1][1]), 500, 50)
            try:
                ind = onTable.index([cardBack, 500, 50])
                onTable[ind] = [cardImage(dealerCards[1][0], dealerCards[1][1]), 500, 50]
            except:
                pass
            updateScore()
            if len(d.cards) > 2:
                dealplayerHit(cardImage(dealerCards[2][0], dealerCards[2][1]), 325, 50)
                drawCard(cardImage(dealerCards[2][0], dealerCards[2][1]), 325, 50)
                pygame.display.update()
                time.sleep(0.3)
            if len(d.cards) > 3:
                dealplayerHit(cardImage(dealerCards[3][0], dealerCards[3][1]), 850, 50)
                drawCard(cardImage(dealerCards[3][0], dealerCards[3][1]), 850, 50)
                pygame.display.update()
                time.sleep(0.3)
            if len(d.cards) > 4:
                dealplayerHit(cardImage(dealerCards[4][0], dealerCards[4][1]), 150, 50)
                drawCard(cardImage(dealerCards[4][0], dealerCards[4][1]), 150, 50)
                pygame.display.update()
                time.sleep(0.3)
            if len(d.cards) > 5:
                dealplayerHit(cardImage(dealerCards[5][0], dealerCards[5][1]), 1025, 50)
                drawCard(cardImage(dealerCards[5][0], dealerCards[5][1]), 1025, 50)
                pygame.display.update()
                time.sleep(0.3)
            updateScore(True)

            if d.getScore() > p.getScore():
                if d.getScore() < 22:
                    label = myfont.render('You Lost', 1, (255,255,255))
                    screen.blit(label, (510, 430))
                    updateChips()
                    pygame.display.update()
                    break
                else:
                    playerChips += betChips * 2
                    label = myfont.render('Dealer Bust\'s, You Win', 1, (255,255,255))
                    screen.blit(label, (230, 430))
                    updateChips()
                    pygame.display.update()
                    break
            elif d.getScore() < p.getScore():
                playerChips += betChips * 2
                label = myfont.render('Winner!', 1, (255,255,255))
                screen.blit(label, (475, 430))
                updateChips()
                pygame.display.update()
                break
            else:
                playerChips += betChips
                label = myfont.render('Tie', 1, (255,255,255))
                screen.blit(label, (600, 450))
                updateChips()
                pygame.display.update()
                break
        else:
            drawCard(cardImage(dealerCards[0][0], dealerCards[0][1]), 675, 50)
            drawCard(cardBack, 500, 50)
    time.sleep(1)

    reset()
    restart()

firstStart()


#!/usr/bin/env python
import rospy
import math
import numpy as np
from std_msgs.msg import String
from geometry_msgs.msg import Pose
from pinak_hw3.msg import qvals

def fwd_kinematics(data):
    print("Recieved following values in degrees:",data.q1,data.q2,data.q3)
    q1 = data.q1*math.pi/180
    q2 = data.q2*math.pi/180
    q3 = data.q3*math.pi/180
    a1 = np.array([[math.cos(q1),0, -math.sin(q1),0],[math.sin(q1),0,math.cos(q1),0],[0,-1,0,1],[0,0,0,1]])
    a2 = np.array([[math.cos(q2), -math.sin(q2),0,math.cos(q2)],[math.sin(q2),math.cos(q2),0,math.sin(q2)],[0,0,1,0],[0,0,0,1]])
    a3 = np.array([[math.cos(q3), -math.sin(q3),0,math.cos(q3)],[math.sin(q3),math.cos(q3),0,math.sin(q3)],[0,0,1,0],[0,0,0,1]])
    temp = np.matmul(a1,a2)
    T = np.matmul(temp,a3)
    print("T is:",T)
    print("The end effector pose is:",T[0:-1,[-1]])

    # print(a1,a2,a3)
def inv_kinematics(data):
    print("Recieved following values for Pose:",data.position.x,data.orientation)
    Xc = data.position.x
    Yc = data.position.y
    Zc = data.position.z
    q1 = math.atan2(Yc,Xc)
    s = Zc-1
    d = (Xc**2+Yc**2+s**2-2)/2
    q3 = math.atan2(math.sqrt(1-d**2),d)
    q2 = math.atan2(s-math.sin(q3),(Xc**2+Yc**2))

    print("q1:",q1*180/math.pi,q2*180/math.pi,q3*180/math.pi)

def listener():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # name are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('fwdkinematics_node', anonymous=True)

    rospy.Subscriber('qvalues', qvals, fwd_kinematics)
    rospy.Subscriber('Pose',Pose, inv_kinematics)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    listener()


from sklearn import svm
import pandas as pd
import time
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

time_1 = time.time()
print('start read data')
raw_data = pd.read_csv('../data/train_finish.csv', header=0)
data = raw_data.values
imgs = data[0::, 1::]
labels = data[::, 0]
# 选取 2/3 数据作为训练集， 1/3 数据作为测试集
train_features, test_features, train_labels, test_labels = train_test_split(imgs, labels, test_size=0.33, random_state=23323)
time_2 = time.time()
print('read data cost', time_2 - time_1, ' seconds\n')

# 获取一个支持向量机模型
predictor = svm.SVC(gamma='scale', C=1.0, decision_function_shape='ovr', kernel='rbf')
# 把数据带入
print('start predict')
time_3 = time.time()
predictor.fit(train_features[:6000], train_labels[:6000])
# 预测结果
result = predictor.predict(test_features[:3000])
# 准确率估计
score = accuracy_score(test_labels[:3000], result)
print ("svm: the accruacy socre is ", score)
time_4 = time.time()
print('predict data cost', time_4 - time_3, ' seconds')
print('all cost', time_4 - time_1, ' seconds')


import base64
print("Enter the encoding to be used")
print("1 for base64")
print("2 for utf-16")
print("3 for utf-32")
en=int(input())
str_input=input("Enter the string to encode")

if en==1:
    str_base64_en = base64.b64encode(str_input.encode())
    print("Encoded string",str_base64_en)
elif en==2:
    str_utf_8=str_input.encode('utf-16','strict')
    print("Encoded string",str_utf_8)

elif en==3:
    str_utf_32=str_input.encode('utf-32','strict')
    print("Encoded string",str_utf_32)

if en==1:
    str_base64_de=base64.b64decode(str_base64_en)
    print("Decoded string",str_base64_de)
elif en==2:
    str_utf_8_de=str_utf_8.decode('utf-16','strict')
    print("Decode string",str_utf_8_de)
elif en==3:
    str_utf_32_de=str_utf_32.decode('utf-32','strict')
    print("Decode string",str_utf_32_de)


import re
import sys
from pathlib import Path
sys.path.append('..')

from gmsfem.petsc.p1case import *
from gmsfem.subdiv import *
from gmsfem.utils import get_simple_kappa
from mpi4py import MPI
from petsc4py import PETSc

scomm = MPI.COMM_SELF
wcomm = MPI.COMM_WORLD
rank = wcomm.Get_rank()
size = wcomm.Get_size()

## Init Stage
# ---------------
n_el = 32            # num of cells in a coarse block along 1D
n_blocks = 4         # num of coarse blocks along 1D

M_off = 10           # dimensionality of offline (online) space
eta = 1e3            # permeability coefficient's bursts
# ---------------
n_nbh = (n_blocks-1)**2
height = M_off*n_nbh

#assert size == n_nbh, ('This is the implementation with equal'
#        ' number of processes and number of coarse neighborhoods')

col = rank % (n_blocks-1)
row = rank // (n_blocks-1)

mesh = UnitSquareMesh(scomm, 2*n_el, 2*n_el)
mesh.translate(Point(col*.5, row*.5))
mesh.scale(2./n_blocks)
V = FunctionSpace(mesh, 'P', 1)

RHS = Expression('sin(2*pi*x[0])*sin(2*pi*x[1])', pi=pi, degree=1)
K = get_simple_kappa(eta, n_el*n_blocks, comm=scomm, seed=123)
W = K.function_space()

rhs = project(RHS, V)
k = project(K, V)

core = GMsFEUnit(rank, n_el, n_blocks)

wcomm.barrier()
if rank == 0: clear_cache()
wcomm.barrier()

##  Offline Stage
t_off =- MPI.Wtime()
# -----------------
Nv = core.snapshotSpace(k)
# -----------------
t_off += MPI.Wtime()

## Online Stage
t_on =- MPI.Wtime()
# -----------------
Nv,_ = core.modelReduction(k, Nv, M_off)
Nv_i = core.multiscaleDOFs(k, Nv)
ms_dofs = zero_extrapolate(Nv_i, V, W, col, row)
## -----------------
t_on += MPI.Wtime()

pairs = overlap_map(n_blocks-1)
mask = (pairs >= size).sum(1).astype(bool)
pairs = pairs[~mask]

def communications(rank):
    imask = (pairs[:, 0] == rank)
    omask = (pairs[:, 1] == rank)
    send_to = pairs[omask][:, 0]
    recv_from = pairs[imask][:, 1]
    return send_to, recv_from

## Global Coupling
t_sr =- MPI.Wtime()
## ----------------
send_to, recv_from = communications(rank)
recvbuf = np.zeros((len(recv_from), *Nv_i.shape)) # empty

for dest in send_to:
    wcomm.Isend([Nv_i, MPI.DOUBLE], dest)
for i, src in enumerate(recv_from):
    wcomm.Recv(recvbuf[i], src)
## ----------------
t_sr += MPI.Wtime()

t_gc =- MPI.Wtime()
## ----------------
A = PETSc.Mat(wcomm)
A.createAIJ((height, height))
A.setUp()

b = PETScVector(wcomm, height)

A_ii, b_i = core.diagonalBlock(k, Nv_i, rhs)
I = np.arange(rank*M_off, (rank+1)*M_off, dtype='i4')
A.setValues(I, I, A_ii.getDenseArray().flatten())
b.set_local(b_i.getArray())

for j, Nv_j in zip(recv_from, recvbuf):
    if rank >= size or j >= size: continue
    A_ij = core.offdiagonalBlock(k, Nv_i, Nv_j, j-rank)
    I = np.arange(rank*M_off, (rank+1)*M_off, dtype='i4')
    J = np.arange(j*M_off, (j+1)*M_off, dtype='i4')
    A.setValues(I, J, A_ij.getDenseArray().flatten())
    A.setValues(J, I, A_ij.getDenseArray().T.flatten())

A.assemble()
A = PETScMatrix(A)
## ----------------
t_gc += MPI.Wtime()

# The next line supposes that you have petsc with superlu_dist installed
# `LUSolver` in dolfinx may not exist - the code below has never been tested
solver = LUSolver(wcomm, A, 'superlu_dist')
solver.parameters['symmetric'] = True

u = PETScVector(wcomm, height)
solver.solve(u, b)
u = u.gather_on_zero()

# TODO: compile ms_dofs matrix and get the product of the latter and the dofs

if rank == 0:
    np.save('solution.bin', u)
    print(f'OFFLINE STAGE: {t_off:.3}s')
    print(f'ONLINE STAGE: {t_on:.3}s')
    print(f'SEND-RECV: {t_sr:.3}s')
    print(f'GLOBAL COUPLING: {t_gc:.3}s')


import argparse
import os
import shutil
from pathlib import Path

import numpy as np
import torch
import torch.backends.cudnn as cudnn
from torch.utils.data import DataLoader, random_split
from torch.utils.tensorboard import SummaryWriter

from models.Compression.MCM import MCM
from models.Compression.common import scaler, distributed, model_utils, pos_embed
from models.Compression.loss import rd_loss
from utils.dataloader import get_image_dataset
from utils.engine import train_one_epoch, val_one_epoch

def save_checkpoint(state, is_best, filename):
    filename1 = filename[:-8] + '_epoch' + str(state['epoch']) + filename[-8:]
    torch.save(state, filename1)
    if is_best:
        shutil.copyfile(filename1, filename[:-8] + "_best" + filename[-8:])

def get_args_parser():
    parser = argparse.ArgumentParser(
        'MAE fine-tuning for image compression', add_help=False)

    # Dataset
    parser.add_argument("-d", "--dataset", type=str,
                        required=True, help="Training dataset path")

    # Training Options
    parser.add_argument("-e", "--epochs", default=100, type=int,
                        help="Number of epochs (default: %(default)s)")
    parser.add_argument("--start_epoch", default=0, type=int)
    parser.add_argument("--accum_iter", default=1, type=int,
                        help="Accumulate gradient iterations for effective batch size")
    parser.add_argument("--learning-rate", "-lr", default=1e-4, type=float,
                        help="Learning rate (default: %(default)s)")
    parser.add_argument("--lambda", dest="lmbda", type=float, default=1e-4,
                        help="Bit-rate distortion parameter (default: %(default)s)")
    parser.add_argument("--batch_size", type=int, default=16,
                        help="Batch size (default: %(default)s)")
    parser.add_argument("--test-batch-size", type=int, default=8,
                        help="Test batch size (default: %(default)s)")
    parser.add_argument("--aux-learning-rate", default=1e-4, type=float,
                        help="Auxiliary loss learning rate (default: %(default)s)")

    # Miscellaneous Options
    parser.add_argument("--cuda", action="store_true", help="Use cuda")
    parser.add_argument("--save", action="store_true", default=True,
                        help="Save model to disk")
    parser.add_argument("--save_path", type=str,
                        default="ckpt/model.pth.tar", help="Where to Save model")
    parser.add_argument("--seed", default=0, type=int,
                        help="Set random seed for reproducibility")
    parser.add_argument("--clip_max_norm", default=1.0, type=float,
                        help="Gradient clipping max norm (default: %(default)s")

    # Checkpoints and Logging
    parser.add_argument("--checkpoint", type=str, default='',
                        help="Path to a checkpoint")
    parser.add_argument('--resume', default='', help='Resume from checkpoint')
    parser.add_argument('--output_dir', default='',
                        help='Path where to save, empty for no saving')
    parser.add_argument('--log_dir', default='',
                        help='Path where to store TensorBoard logs')

    # Hardware and Data Loading Options
    parser.add_argument('--device', default='cuda',
                        help='Device to use for training/testing')
    parser.add_argument('--num_workers', default=1, type=int)
    parser.add_argument('--pin_mem', action='store_true',
                        help='Pin CPU memory in DataLoader for more efficient transfer to GPU')
    parser.add_argument('--no_pin_mem', action='store_false', dest='pin_mem')
    parser.set_defaults(pin_mem=True)

    # Model Options
    parser.add_argument('--num_keep_patches', type=int, default=144,
                        help='Number of keep patches to input the model')

    # Augmentation parameters
    parser.add_argument("--input_size", type=int, default=224, required=True,
                        help="Size of the input image")
    parser.add_argument('--color_jitter', type=float, default=None, metavar='PCT',
                        help='Color jitter factor (enabled only when not using Auto/RandAug)')
    parser.add_argument('--aa', type=str, default='rand-m9-mstd0.5-inc1', metavar='NAME',
                        help='Use AutoAugment policy. "v0" or "original". " + "(default: rand-m9-mstd0.5-inc1)'),

    # * Random Erase params
    parser.add_argument('--reprob', type=float, default=0.25, metavar='PCT',
                        help='Random erase prob (default: 0.25)')
    parser.add_argument('--remode', type=str, default='pixel',
                        help='Random erase mode (default: "pixel")')
    parser.add_argument('--recount', type=int, default=1,
                        help='Random erase count (default: 1)')

    return parser

def main(args):
    print('Job directory: {}'.format(os.path.dirname(os.path.realpath(__file__))))
    print("{}".format(args).replace(', ', ',\n'))

    # Set up device and random seed
    device = torch.device(args.device)
    seed = args.seed + distributed.get_rank()
    torch.manual_seed(seed)
    np.random.seed(seed)

    # Data preprocessing and dataset creation
    cudnn.benchmark = True
    train_dataset = get_image_dataset(mode="train",
                                      dataset_path=args.dataset)

    val_dataset = get_image_dataset(mode="val",
                                    dataset_path=args.dataset)

    # Setting up data samplers
    num_tasks = distributed.get_world_size()  # GPU's RAM
    global_rank = distributed.get_rank()  # GPU
    sampler_train = torch.utils.data.DistributedSampler(
        train_dataset,
        num_replicas=num_tasks,
        rank=global_rank,
        shuffle=True
    )
    print("Sampler_train = %s" % str(sampler_train))

    sampler_val = torch.utils.data.SequentialSampler(val_dataset)

    # Configuring a writer for logging
    if global_rank == 0 and args.log_dir is not None:
        os.makedirs(args.log_dir, exist_ok=True)
        writer = SummaryWriter(log_dir=args.log_dir)
    else:
        writer = None

    # Set up dataloader
    train_dataloader = DataLoader(
        train_dataset,
        sampler=sampler_train,
        batch_size=args.batch_size,
        num_workers=args.num_workers,
        pin_memory=args.pin_mem,
        drop_last=True,
    )

    val_dataloader = DataLoader(
        val_dataset,
        sampler=sampler_val,
        batch_size=args.test_batch_size,
        num_workers=args.num_workers,
        pin_memory=args.pin_mem,
        drop_last=False
    )

    mcm = MCM(num_keep_patches=args.num_keep_patches)

    '''load mae encoder model'''
    if args.checkpoint:
        checkpoint = torch.load(args.checkpoint, map_location='cpu')
        checkpoint_model = checkpoint['model']

        state_dict = mcm.state_dict()
        for k in ['head.weight', 'head.bias']:
            if k in checkpoint_model and checkpoint_model[k].shape != state_dict[k].shape:
                print(f"Removing key {k} from pretrained checkpoint")
                del checkpoint_model[k]

        # interpolate position embedding
        pos_embed.interpolate_pos_embed(mcm, checkpoint_model)
        # msg = mcm.load_state_dict(checkpoint_model)
        # print(msg)

    mcm.to(device)
    loss_scaler = scaler.NativeScaler()
    optimizer, aux_optimizer = model_utils.configure_optimizers(mcm, args)
    model_utils.load_model(args=args, model=mcm, optimizer=optimizer,
                           aux_optimizer=aux_optimizer, loss_scaler=loss_scaler)

    criterion = rd_loss.RateDistortionLoss(lmbda=args.lmbda)
    best_loss = 1e10

    print(f"Start training for {args.epochs} epochs")
    for epoch in range(args.start_epoch, args.epochs, 5):
        train_one_epoch(mcm, criterion, train_dataloader, optimizer, aux_optimizer, epoch, loss_scaler,
                        args.clip_max_norm, writer=writer, args=args)
        out = val_one_epoch(epoch, val_dataloader, mcm, criterion)

        if args.output_dir:
            if out['loss'] < best_loss:
                model_utils.save_model(args=args, epoch=epoch, model=mcm, optimizer=optimizer,
                                       aux_optimizer=aux_optimizer,
                                       loss_scaler=loss_scaler)
                best_loss = out['loss']

if __name__ == "__main__":
    args = get_args_parser()
    args = args.parse_args()
    if args.output_dir:
        Path(args.output_dir).mkdir(parents=True, exist_ok=True)
    main(args)


from tkinter import *
from tkinter.font import Font

root = Tk()
root.title('Codemy.com - Custom Fonts')
root.iconbitmap('c:/gui/codemy.ico')
root.geometry("500x500")

# Define Our Font
bigFont = Font(
	family="Times",
	size=40,
	weight="bold",
	slant="roman",
	underline=0,
	overstrike=0)

# Define Out Font
mediumFont = Font(
	family="Helvetica",
	size=24,
	weight="normal",
	slant="italic",
	underline=1,
	overstrike=0)

# Define A Button
my_button1 = Button(root, text="Big Text", font=bigFont)
my_button1.pack(pady=20)

# Label
my_label = Label(root, text="more big text", font=mediumFont)
my_label.pack(pady=20)

root.mainloop()


import numpy as np
import torch
import torch.nn as nn
from torch.autograd import Variable
from networks import perceptual_conv_real_224_l0, perceptual_conv_real_224_l1
# from logger import Logger
from datetime import datetime
import argparse
import os
import random
import glob
from tensorboardX import SummaryWriter
import time
from datetime import datetime
from arguments import get_args
from copy import deepcopy
from recordtype import recordtype
import math

current_time = datetime.now().strftime('%b%d_%H-%M-%S')

def shift(grid, d, axis=None, fill = 0.5):
    grid = np.roll(grid, d, axis=axis)
    if axis == 0:
        if d > 0:
            grid[:d,:] = fill
        elif d < 0:
            grid[d:,:] = fill
    elif axis == 1:
        if d > 0:
            grid[:,:d] = fill
        elif d < 0:
            grid[:,d:] = fill
    return grid

def softmax(w, t = 1.0):
    e = np.exp(np.array(w) / t)
    dist = e / np.sum(e)
    return dist

def softermax(w, t = 1.0):
    w = np.array(w)
    w = w - w.min() + np.exp(1)
    e = np.log(w)
    dist = e / np.sum(e)
    return dist

def to_index(a, N, mm):
    a_max = mm[1]
    a_min = mm[0]
    return int(np.floor(N*(a_max-a)/(a_max-a_min)))

def to_real(i, mm, n):
    u = (mm[1]-mm[0])/n
    u0 = u/2
    return mm[1]-u*i - u0

def wrap(phase):
    # wrap into [-pi, pi]
    phase = ( phase + np.pi) % (2 * np.pi ) - np.pi
    return phase

Pose2d = recordtype("Pose2d", "theta x y")
Grid = recordtype("Grid", "head row col")

class Lidar():
    def __init__(self, ranges, angle_min, angle_max,
                 range_min, range_max):
        # self.ranges = np.clip(ranges, range_min, range_max)
        self.ranges = ranges
        self.angle_min = angle_min
        self.angle_max = angle_max
        num_data = len(self.ranges)
        self.angle_increment = (self.angle_max-self.angle_min)/num_data #math.increment

class LocalizationNode:
    def __init__(self):
        args = get_args()
        self.writer = SummaryWriter(log_dir='runs3a_224/'
            + 'lrpm0_' + str(args.lrpm0)+'_'
            + 'lrpm1_' + str(args.lrpm1)+'_'
            + 'layers0_' + str(args.layers0)+'_'
            + 'layers1_' + str(args.layers1)+'_'
            + 'bs_' + str(args.batch_size)+'_'
            + 'epochs_' + str(args.epochs)+'_'
            + 'cells' + str(args.cells)+'_'
            + args.criti
            +'_'+current_time)

        self.modelfile='likelihood_models/'+'model224_3a' + 'lrpm0_' + str(args.lrpm0)+'_' \
        + 'lrpm1_' + str(args.lrpm1)+'_' \
        + 'layers0_' + str(args.layers0)+'_' \
        + 'layers1_' + str(args.layers1)+'_' \
        + 'bs_' + str(args.batch_size)+'_' \
        + 'cells_' + str(args.cells)+'_' \
        + args.criti \
        +'_'+current_time

        self.batch_size = args.batch_size
        self.grid_rows = 11
        self.map_rows = 224
        self.thresh = Variable(torch.Tensor([args.thresh]))
        self.layers0 = args.layers0
        self.layers1 = args.layers1
        self.epochs = args.epochs
        self.criti = args.criti
        self.cells = args.cells

        self.likeli_model_l0 = perceptual_conv_real_224_l0(self.layers0)
        self.likeli_model_l1 = perceptual_conv_real_224_l1(self.layers1)

        args.gpu = True
        if args.gpu == True and torch.cuda.is_available():
            self.device = torch.device("cuda")
            torch.set_default_tensor_type(torch.cuda.FloatTensor)
        else:
            self.device = torch.device("cpu")
            torch.set_default_tensor_type(torch.FloatTensor)

        if self.device == torch.device("cuda") and torch.cuda.device_count() > 1:
            print ("Use", torch.cuda.device_count(), 'GPUs')
            self.likeli_model_l0 = nn.DataParallel(self.likeli_model_l0).cuda()
            self.likeli_model_l1 = nn.DataParallel(self.likeli_model_l1).cuda()
        else:
            print ("Use CPU")

        self.optimizer0 = torch.optim.Adam(list(self.likeli_model_l0.parameters()), lr=args.lrpm0)
        self.optimizer1 = torch.optim.Adam(list(self.likeli_model_l1.parameters())+list(self.likeli_model_l0.parameters()), lr=args.lrpm1)
        if self.criti == 'mse':
            self.criterion = nn.MSELoss()
        elif self.criti == 'kld':
            self.criterion = nn.KLDivLoss()

        self.args = args
        self.start_time = time.time()

        #if self.args.gpu == True and torch.cuda.is_available():
        if (self.args.gpu) and torch.cuda.is_available():
            self.device = torch.device("cuda" )
            torch.set_default_tensor_type(torch.cuda.FloatTensor)
        else:
            self.device = torch.device("cpu")
            torch.set_default_tensor_type(torch.FloatTensor)

        self.grid_rows, self.grid_cols, self.grid_dirs = 11, 11, 4

        self.map_rows, self.map_cols = 224, 224

        self.max_scan_range = 3.5
        self.min_scan_range = 0.1

        self.map_2d = np.load('/home/sai/tb3-anl/dal/env_map.npy')
        self.map_2d = (255 - self.map_2d)/255
        self.taken = np.arange(self.map_2d.size)[self.map_2d.flatten()==1]
        # self.laser_1d = None

        self.xlim = (-self.args.xlim, self.args.xlim)
        self.ylim = (-self.args.xlim, self.args.xlim)

        self.longest = float(self.grid_dirs/2 + self.grid_rows-1 + self.grid_cols-1)  #longest possible manhattan distance

        self.cell_size = (self.xlim[1]-self.xlim[0])/self.grid_rows
        self.heading_resol = 2*np.pi/self.grid_dirs

        self.collision = False

        self.scans_over_map = np.zeros((self.grid_rows,self.grid_cols,360))
        self.scans_over_map_high = np.zeros((self.map_rows, self.map_cols, 360))

        self.scan_2d = np.zeros((self.map_rows, self.map_cols))

        self.likelihood = torch.ones((self.grid_dirs,self.grid_rows, self.grid_cols),device=torch.device(self.device))
        self.likelihood = self.likelihood / self.likelihood.sum()

        self.gt_likelihood = np.ones((self.grid_dirs,self.grid_rows,self.grid_cols))
        self.gt_likelihood_high = np.ones((self.grid_dirs, self.map_rows, self.map_cols))
        self.gt_likelihood_unnormalized = np.ones((self.grid_dirs,self.grid_rows,self.grid_cols))
        self.gt_likelihood_unnormalized_high = np.ones((self.grid_dirs, self.grid_rows, self.grid_cols))

        self.turtle_loc = np.zeros((self.map_rows,self.map_cols))

        # what to do
        # current pose: where the robot really is. motion incurs errors in pose
        self.current_pose = Pose2d(0,0,0)
        self.goal_pose = Pose2d(0,0,0)
        self.last_pose = Pose2d(0,0,0)
        self.perturbed_goal_pose = Pose2d(0,0,0)
        self.start_pose = Pose2d(0,0,0)
        #grid pose
        self.true_grid = Grid(head=0,row=0,col=0)
        self.bel_grid = Grid(head=0,row=0,col=0)

    def loop(self):

        self.map_2d = np.load('/home/sai/tb3-anl/dal/env_map.npy')
        # self.get_synth_scan()
        # np.save('/home/sai/montreal_synth_scan.npy', self.scans_over_map_high)
        self.scans_over_map_high = np.load('/home/sai/montreal_synth_scan.npy')

        turtle_can = [ltc for ltc in range(self.map_rows*self.map_cols) if ltc not in self.taken]

        ## Perumtation of possible locations(so that we access random locations for each map
        turtle_can = np.random.permutation(turtle_can)

        for btc in range(100): #epochs

            ## getting locations where turtle can be placed

            ## Get first n random locations and save the six variables
            my_input = np.zeros((self.batch_size, 5, 224, 224))
            gt_likli_low_train = np.zeros((self.batch_size, 4, 11, 11))
            gt_likli_high_train = np.zeros((self.batch_size, 4, 224, 224))
            for j in range(int(turtle_can.shape[0]/self.batch_size)):
                for i in range(self.batch_size): #batch_size

                # new turtle location (random)
                    turtle_bin = turtle_can[j*self.batch_size +  i]

                    self.true_grid.row = turtle_bin//self.map_rows
                    self.true_grid.col = turtle_bin% self.map_cols
                    self.true_grid.head = np.random.randint(self.grid_dirs)
                    self.goal_pose.x = to_real(self.true_grid.row, self.xlim, self.map_rows)
                    self.goal_pose.y = to_real(self.true_grid.col, self.ylim, self.map_cols)
                    self.goal_pose.theta = wrap(self.true_grid.head*self.heading_resol)

                    self.perturbed_goal_pose.x = self.goal_pose.x
                    self.perturbed_goal_pose.y = self.goal_pose.y
                    self.perturbed_goal_pose.theta = self.goal_pose.theta

                    self.teleport_turtle()

                    self.get_lidar()
                # if self.args.shade:
                #     self.get_scan_2d()
                # else:
                    #self.get_scan_2d_noshade()
                    self.get_scan_2d_n_headings()
                ### 2. update likelihood from observation
                    self.generate_map_trans()

                # if self.args.dirac_delta_gtl:
                #     self.get_gt_likelihood_dirac()
                    if self.args.gtl_src == 'ld':
                        self.get_gt_likelihood()
                    elif self.args.gtl_src == 'hd-corr':
                        self.get_gt_likelihood_corr()
                    elif self.args.gtl_src == 'hd-cos':
                        self.get_gt_likelihood_cossim()
                    else:
                        raise Exception('GTL source required: --gtl-src= [low-dim-map, high-dim-map]')
                #self.normalize_gtl()
                    my_input[i,0,:,:] = self.map_2d
                    my_input[i,1:5,:,:] = self.scan_2d
                    gt_likli_low_train[i,:,:,:] = self.gt_likelihood
                    gt_likli_high_train[i,:,:,:] = self.gt_likelihood_high
                self.do_train(my_input, gt_likli_low_train, gt_likli_high_train, btc*turtle_can.shape[0] + j * self.batch_size + i)

            self.writer.close()

            ## Getting the new environment
            print("Done with the for loop.")
            self.current_state = "new_env_pose"
            return

        else:
            print("undefined state name %s"%self.current_state)
            self.current_state = None
            exit()

        return

    def teleport_turtle(self):
        self.current_pose.x = self.perturbed_goal_pose.x
        self.current_pose.y = self.perturbed_goal_pose.y
        self.current_pose.theta = self.perturbed_goal_pose.theta

    def normalize_gtl(self):
        gt = self.gt_likelihood
        gt_high = self.gt_likelihood_high
        self.gt_likelihood_unnormalized = np.copy(self.gt_likelihood)
        self.gt_likelihood_unnormalized_high = np.copy(self.gt_likelihood_high)
        if self.args.gtl_output == "softmax":
            gt = softmax(gt, self.args.temperature)
            gt_high = softmax(gt_high, self.args.temperature)
            # gt = torch.from_numpy(softmax(gt)).float().to(self.device)
        elif self.args.gtl_output == "softermax":
            gt = softermax(gt)
            gt_high = softermax(gt_high)
            # gt = torch.from_numpy(softmin(gt)).float().to(self.device)
        elif self.args.gtl_output == "linear":
            gt = np.clip(gt, 1e-5, 1.0)
            gt_high = np.clip(gt_high, 1e-5, 1.0)
            gt=gt/gt.sum()
            gt_high = gt_high/gt_high.sum()
            # gt = torch.from_numpy(gt/gt.sum()).float().to(self.device)
        self.gt_likelihood = torch.tensor(gt).float().to(self.device)
        self.gt_likelihood_high = torch.tensor(gt_high).float().to(self.device)

    def get_gt_likelihood_cossim(self):
        offset = 360/self.grid_dirs
        y= np.array(self.scan_data_at_unperturbed.ranges)[::self.args.pm_scan_step]
        # y= np.array(self.scan_data.ranges)[::self.args.pm_scan_step]
        y = np.clip(y, self.min_scan_range, self.max_scan_range)
        # y[y==np.inf]= self.max_scan_range
        for heading in range(self.grid_dirs):  ## that is, each direction
            #compute cosine similarity at each loc
            X = np.roll(self.scans_over_map, int(-offset*heading),axis=2)[:,:,::self.args.pm_scan_step]
            for i_ld in range(self.grid_rows):
                for j_ld in range(self.grid_cols):
                    if (i_ld*self.grid_cols+j_ld == self.taken).any():
                        self.gt_likelihood[heading,i_ld,j_ld]= 0.0
                    else:
                        x = X[i_ld,j_ld,:]
                        x = np.clip(x, self.min_scan_range, self.max_scan_range)

                        self.gt_likelihood[heading,i_ld,j_ld]= self.get_cosine_sim(x,y)

        for heading in range(self.grid_dirs):  ## that is, each direction
            #compute cosine similarity at each loc
            X = np.roll(self.scans_over_map_high, int(-offset*heading),axis=2)[:,:,::self.args.pm_scan_step]
            for i_ld in range(self.map_rows):
                for j_ld in range(self.map_cols):
                    if (i_ld*self.map_cols+j_ld == self.taken).any():
                        self.gt_likelihood_high[heading,i_ld,j_ld]= 0.0
                    else:
                        x = X[i_ld,j_ld,:]
                        x = np.clip(x, self.min_scan_range, self.max_scan_range)

                        self.gt_likelihood_high[heading,i_ld,j_ld]= self.get_cosine_sim(x,y)

    def get_gt_likelihood_corr(self):
        offset = 360/self.grid_dirs
        # y= np.array(self.scan_data_at_unperturbed.ranges)[::self.args.pm_scan_step]
        y= np.array(self.scan_data.ranges)[::self.args.pm_scan_step]
        y = np.clip(y, self.min_scan_range, self.max_scan_range)
        # y[y==np.inf]= self.max_scan_range
        for heading in range(self.grid_dirs):  ## that is, each direction
            #compute cosine similarity at each loc
            X = np.roll(self.scans_over_map, int(-offset*heading),axis=2)[:,:,::self.args.pm_scan_step]
            for i_ld in range(self.grid_rows):
                for j_ld in range(self.grid_cols):
                    if (i_ld*self.grid_cols+j_ld == self.taken).any():
                        self.gt_likelihood[heading,i_ld,j_ld]= 0.0
                    else:
                        x = X[i_ld,j_ld,:]
                        x = np.clip(x, self.min_scan_range, self.max_scan_range)
                        self.gt_likelihood[heading,i_ld,j_ld]= self.get_corr(x,y)

        for heading in range(self.grid_dirs):  ## that is, each direction
            #compute cosine similarity at each loc
            X = np.roll(self.scans_over_map_high, int(-offset*heading),axis=2)[:,:,::self.args.pm_scan_step]
            for i_ld in range(self.map_rows):
                for j_ld in range(self.map_cols):
                    if (i_ld*self.map_cols+j_ld == self.taken).any():
                        self.gt_likelihood_high[heading,i_ld,j_ld]= 0.0
                    else:
                        x = X[i_ld,j_ld,:]
                        x = np.clip(x, self.min_scan_range, self.max_scan_range)

                        self.gt_likelihood_high[heading,i_ld,j_ld]= self.get_corr(x,y)

    def generate_map_trans(self):
        self.grid_center = ((self.grid_rows-1)/2, (self.grid_cols-1)/2)
        self.map_trans = self.map_2d
        self.map_trans = shift(self.map_trans, int(self.grid_center[0]-self.true_grid.row), axis = 0, fill=1.0)
        self.map_trans = shift(self.map_trans, int(self.grid_center[1]-self.true_grid.col), axis = 1, fill=1.0)
        self.map_trans = np.rot90(self.map_trans, -self.true_grid.head)

    def get_cosine_sim(self,x,y):
        # numpy arrays.
         return sum(x*y)/np.linalg.norm(y,2)/np.linalg.norm(x,2)

    def get_corr(self,x,y):
        mx=np.mean(x)
        my=np.mean(y)
        corr=sum((x-mx)*(y-my))/np.linalg.norm(y-my,2)/np.linalg.norm(x-mx,2)
        return 0.5*(corr+1.0)
        # return np.clip(corr, 1e-10, 1.0)

    def get_gt_likelihood(self):
        # self.true_grid.head, self.true_grid.row, self.true_grid.col --> virtual scan input from map
        # self.map_design shift as row,col and rotate as head

        for i in range(self.grid_rows):
            for j in range(self.grid_cols):
                for o in range(self.grid_dirs):
                    cand = self.map_2d
                    cand = shift(cand, int(self.grid_center[0]-i), axis = 0, fill=-1.0)
                    cand = shift(cand, int(self.grid_center[1]-j), axis = 1, fill=-1.0)
                    cand = np.rot90(cand, -o)
                    match = (1-np.fabs(cand-self.map_trans))*np.array(cand>=0.0,dtype=float)
                    if np.sum(np.array(cand>=0.0,dtype=float),dtype=float) == 0:
                        prob = 0
                    else:
                        prob=np.sum(match,dtype=float)/np.sum(np.array(cand>=0.0,dtype=float),dtype=float)
                    self.gt_likelihood[o,i,j]=prob

        #self.gt_likelihood = softmax(self.gt_likelihood)

    def get_scan_2d(self):

        data = self.scan_data
        if self.map_rows == None :
            return
        if self.map_cols == None:
            return

        N=self.map_rows
        M=self.map_cols
        self.scan_2d = np.zeros(shape=(N,M))

        x_max = self.xlim[1] # map height/2 in meters
        x_min = self.xlim[0]
        y_max = self.ylim[1]# map width/2 in meters
        y_min = self.ylim[0]

        resol0=min((x_max-x_min)/N,(y_max-y_min)/M)

        angle = data.angle_min
        for i,dist in enumerate(data.ranges):
            resol=resol0
            if ~np.isinf(dist):
                over = 0
                while True:
                    x = (dist+over)*np.cos(angle)
                    y = (dist+over)*np.sin(angle)
                    n = to_index(x, N, self.xlim)
                    m = to_index(y, M, self.ylim)
                    if not (n>=0 and n<N and m>0 and m<M): break
                    self.scan_2d[n,m] = 1.0
                    over += resol
            angle += data.angle_increment

        self.scan_2d_low = np.zeros((self.grid_rows,self.grid_cols),dtype=int)
        row_ticks = np.linspace(start=0,stop=self.map_rows,num=self.grid_rows+1,dtype=int)
        col_ticks = np.linspace(start=0,stop=self.map_cols,num=self.grid_cols+1,dtype=int)
        for i in range(self.grid_rows):
            for j in range(self.grid_cols):
                patch = self.scan_2d[row_ticks[i]:row_ticks[i+1],col_ticks[j]:col_ticks[j+1]]
                self.scan_2d_low[i,j] = 1 if np.mean(patch) > 0.5 else 0

    def get_a_scan(self, x_real, y_real, offset=0, scan_step=1):
        row_hd = to_index(x_real, self.map_rows, self.xlim)  # from real to hd
        col_hd = to_index(y_real, self.map_cols, self.ylim)  # from real to hd
        scan = np.zeros(360)
        for i_ray in range(0,360, scan_step):
            theta = math.radians(i_ray)+offset
            dist = self.min_scan_range
            while True:
                if dist >= self.max_scan_range:
                    dist = np.inf
                    break
                x_probe = x_real + dist * np.cos(theta)
                y_probe = y_real + dist * np.sin(theta)
                # see if there's something
                i_hd_prb = to_index(x_probe, self.map_rows, self.xlim)
                j_hd_prb = to_index(y_probe, self.map_cols, self.ylim)
                if i_hd_prb < 0 or i_hd_prb >= self.map_rows:
                    dist = np.inf
                    break
                if j_hd_prb < 0 or j_hd_prb >= self.map_cols:
                    dist = np.inf
                    break
                if self.map_2d[i_hd_prb, j_hd_prb] >= 0.5:
                    break
                dist += 0.01+0.01*(np.random.rand())
            scan[i_ray]=dist
        return scan

    def get_synth_scan(self):

        n_places = self.map_rows * self.map_cols
        for i_place in range(n_places):
            row_ld = i_place // self.map_rows
            col_ld = i_place % self.map_cols
            x_real = to_real(row_ld, self.xlim, self.map_rows ) # from low-dim location to real
            y_real = to_real(col_ld, self.ylim, self.map_cols ) # from low-dim location to real
            scan = self.get_a_scan(x_real, y_real,scan_step=self.args.pm_scan_step)
            self.scans_over_map_high[row_ld, col_ld,:] = np.clip(scan, 1e-10, self.max_scan_range)
            if i_place%10==0: print (i_place)

    def get_scan_2d_n_headings(self):

        data = self.scan_data
        if self.map_rows == None :
            return
        if self.map_cols == None:
            return

        O=self.grid_dirs
        N=self.map_rows
        M=self.map_cols
        self.scan_2d = np.zeros(shape=(O,N,M))
        # self.scan_2d_rotate = np.zeros(shape=(O,N,M))
        angles = np.linspace(data.angle_min, data.angle_max, data.ranges.size, endpoint=False)

        for i,dist in enumerate(data.ranges):
            for rotate in range(O):

                offset = 2*np.pi/O*rotate
                angle = offset + angles[i]
                #print("stuck_here? ", angle)
                if angle > math.radians(self.args.fov[0]) and angle < math.radians(self.args.fov[1]):
                    continue
                if ~np.isinf(dist):
                    x = (dist)*np.cos(angle)
                    y = (dist)*np.sin(angle)
                    n = to_index(x, N, self.xlim)
                    m = to_index(y, M, self.ylim)
                    if n>=0 and n<N and m>0 and m<M:
                        self.scan_2d[rotate,n,m] = 1.0

        return

    def mask_likelihood(self):
        the_mask = torch.tensor(np.ones([self.grid_dirs, self.grid_rows, self.grid_cols])).float().to(self.device)
        for i in range(self.grid_rows):
            for j in range(self.grid_cols):
                if (i*self.grid_cols+j==self.taken).any():
                    the_mask[:,i,j]=0.0
        self.likelihood = self.likelihood * the_mask
        #self.likelihood = torch.clamp(self.likelihood, 1e-9, 1.0)
        self.likelihood = self.likelihood/self.likelihood.sum()

    def get_lidar(self):
        ranges = self.get_a_scan(self.current_pose.x, self.current_pose.y, offset=self.current_pose.theta)
        bearing_deg = np.arange(360.0)
        mindeg=0
        maxdeg=359
        incrementdeg=1

        params = {'ranges': ranges,
                  'angle_min': math.radians(mindeg),
                  'angle_max': math.radians(maxdeg),
                  'range_min': self.min_scan_range,
                  'range_max': self.max_scan_range}

        self.scan_data = Lidar(**params)

        ## scan_data @ unperturbed pose
        x = to_real(self.true_grid.row, self.xlim, self.map_rows)
        y = to_real(self.true_grid.col, self.ylim, self.map_cols)
        print("x, y = ", x, y)
        offset = self.heading_resol*self.true_grid.head
        ranges = self.get_a_scan(x, y, offset=offset)
        params = {'ranges': ranges,
                  'angle_min': math.radians(mindeg),
                  'angle_max': math.radians(maxdeg),
                  'range_min': self.min_scan_range,
                  'range_max': self.max_scan_range}

        self.scan_data_at_unperturbed = Lidar(**params)

    def do_train(self, input_batch0, target_batch0, target_batch1, i):
        self.likeli_model_l0.train()
        self.likeli_model_l1.train()
        self.optimizer0.zero_grad()
        self.optimizer1.zero_grad()

        input_batch0 = Variable(torch.FloatTensor(input_batch0))
        input_batch0 = input_batch0.to(self.device)
        target_batch0 = Variable(torch.FloatTensor(target_batch0))
        target_batch0 = target_batch0.to(self.device)
        target_batch1 = Variable(torch.FloatTensor(target_batch1))
        target_batch1 = target_batch1.to(self.device)

        output0 = self.likeli_model_l0(input_batch0)

        bs, a,b,c = output0.shape
        u = torch.reshape(output0, (-1, a*b*c))
        _, idx = torch.topk(output0.view(output0.shape[0], -1), dim=-1, k=self.cells)
        x = idx/(b*c)
        y = (idx%(b*c))/b
        z = (idx%(b*c))%c

        output1 = torch.zeros((bs, 4, 224, 224))
        # output1 = output1/torch.sum(output1)
        for btc in range(self.cells):
            scan_cut = torch.ones((bs, 4, 160, 160))
            map_cut = torch.ones((bs, 160, 160))
            for eth in range(bs):
                dire, row, col = x[eth,btc], y[eth,btc], z[eth,btc]
                # print("dire, row, col = ", dire, row, col)
                if row*20 - 80 >= 0:
                    row_min = row*20 - 80
                else:
                    row_min = 0
                if row*20 + 80 <= 224:
                    row_max = row*20 + 80
                else:
                    row_max = 224

                if col*20 - 80 >= 0:
                    col_min = col*20 - 80
                else:
                    col_min = 0
                if col*20 + 80 <= 224:
                    col_max = col*20 + 80
                else:
                    col_max = 224

                scan_cut[eth, :, 0:row_max-row_min, 0:col_max-col_min] = input_batch0[eth, 1:5, row_min:row_max, col_min:col_max]
                map_cut[eth, 0:row_max-row_min, 0:col_max-col_min] = input_batch0[eth, 0, row_min:row_max, col_min:col_max]

            input_batch1 = torch.zeros((bs, 5, 160, 160))
            input_batch1[:,0,:,:] = map_cut
            input_batch1[:,1:5,:,:] = scan_cut
            output_cut = self.likeli_model_l1(input_batch1)
            weight = output0[:,dire,row,col].unsqueeze(-1).unsqueeze(-1).unsqueeze(-1)
            output1[:, :, row*20:(row+1)*20, col*20:(col+1)*20] = weight *output_cut

        loss0 = self.criterion(output0, target_batch0)
        if self.criti == 'kld':
            loss0 = abs(loss0)
        loss0.backward(retain_graph=True)
        self.optimizer0.step()

        loss1 = self.criterion(output1, target_batch1)
        if self.criti == 'kld':
            loss1 = abs(loss1)
        loss1.backward()
        self.optimizer1.step()
        self.writer.add_scalar('loss0', loss0, i)
        self.writer.add_scalar('loss1', loss1, i)
        print(loss0, loss1)

        str_date_time = datetime.now().strftime('%Y%m%d-%H%M%S')
        self.logfile = 'anl_output-%s.txt'%str_date_time
        self.pm_filepath0='/home/sai/hierar/hierarchical/scripts/montreal_hierar/' + self.modelfile+'_0.model'
        self.pm_filepath1='/home/sai/hierar/hierarchical/scripts/montreal_hierar/' + self.modelfile+'_1.model'
        torch.save(self.likeli_model_l0, self.pm_filepath0)
        torch.save(self.likeli_model_l1, self.pm_filepath1)

        print("backprop done")

lol = LocalizationNode()
lol.loop()


import json
import numpy as np
import pandas as pd

from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.text import Tokenizer, text_to_word_sequence
from tensorflow.keras.utils import to_categorical

# import our chat-bot intents file
with open('intent.json') as json_data:
    intents = json.load(json_data)

# Crear el vocabulario a partir de todas las palabras del intents.json
train_text=""
p=[]
t=[]
for n in intents['intents']:
	p = p + n['patterns']
	t = t + [n['tag'] for x in range(len(n['patterns']))]
	train_text = train_text + " ".join(n['patterns']) + " ".join(n['responses'])

#Creacion del vocabulario
corpus= set(text_to_word_sequence(train_text))
corpus = list(sorted(corpus))
df = pd.DataFrame({'words': corpus})
df.to_csv('corpus.csv')
size = len(corpus)+1

# Obtenemos los datos de entrada para entrenamiento
tok = Tokenizer()
tok.fit_on_texts(corpus)
tokens= tok.texts_to_sequences(p)

x_train = [np.add.reduce(to_categorical(X, size)) for X in tokens]
x_train = np.array(x_train)

# Obtenemos los datos de salida para el entrenamiento
clases = list(sorted(set(t)))
size_s = len(clases)+1

tok2 = Tokenizer()
tok2.fit_on_texts(clases)
tokens_s = tok2.texts_to_sequences(t)

y_train= [np.add.reduce(to_categorical(Y, size_s)) for Y in tokens_s]
y_train = np.array(y_train)

model = keras.Sequential()
model.add(keras.Input(shape=x_train[0].shape))
model.add(layers.Dense(30))
model.add(layers.Dense(60, activation='relu'))
model.add(layers.Dense(60, activation='relu'))
model.add(layers.Dense(len(y_train[0])))

# Compilamos el modelo, definiendo la función de coste y el optimizador.
model.compile(loss='mse', optimizer=keras.optimizers.SGD(lr=9), metrics=['acc'])

# Y entrenamos al modelo. Los callbacks
model.fit(x_train, y_train, epochs=8000)

pred=model.predict(np.array([x_train[2]]))

# Guardar el Modelo
model.save('model.h5')


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from sklearn.metrics import mean_squared_error
from fastcore.all import *
import argparse

class NodeDetectionEvaluator:
    def __init__(self, ground_truth, participant, tolerance):
        self.ground_truth = ground_truth.copy()
        self.participant = participant.copy()
        self.tolerance = tolerance

    def evaluate(self, object_id):
        gt_object = self.ground_truth[(self.ground_truth['ObjectID'] == object_id) & \
                          (self.ground_truth['Direction'] != 'ES')].copy()
        p_object = self.participant[(self.participant['ObjectID'] == object_id) & \
                                    (self.participant['Direction'] != 'ES')].copy()
        p_object['matched'] = False
        p_object['classification'] = None
        p_object['distance'] = None
        gt_object['classification'] = None
        gt_object['distance'] = None
        tp = 0
        fp = 0
        fn = 0

        for gt_idx, gt_row in gt_object.iterrows():
            matching_participant_events = p_object[
                (p_object['TimeIndex'] >= gt_row['TimeIndex'] - self.tolerance) &
                (p_object['TimeIndex'] <= gt_row['TimeIndex'] + self.tolerance) &
                (p_object['Direction'] == gt_row['Direction'])
            ]

            if len(matching_participant_events) > 0:
                p_idx = matching_participant_events.index[0]
                p_row = matching_participant_events.iloc[0]
                distance = p_row['TimeIndex'] - gt_row['TimeIndex']
                if p_row['Node'] == gt_row['Node'] and p_row['Type'] == gt_row['Type']:
                    tp += 1
                    gt_object.loc[gt_idx, 'classification'] = 'TP'
                    gt_object.loc[gt_idx, 'distance'] = distance
                    p_object.loc[p_idx, 'classification'] = 'TP'
                    p_object.loc[p_idx, 'distance'] = distance
                else:
                    fp += 1
                    gt_object.loc[gt_idx, 'classification'] = 'FP'
                    gt_object.loc[gt_idx, 'distance'] = distance
                    p_object.loc[p_idx, 'classification'] = 'FP'
                    p_object.loc[p_idx, 'distance'] = distance
                p_object.loc[matching_participant_events.index[0], 'matched'] = True
            else:
                fn += 1
                gt_object.loc[gt_idx, 'classification'] = 'FN'

        additional_fp = p_object[~p_object['matched']].copy()
        fp += len(additional_fp)
        p_object.loc[additional_fp.index, 'classification'] = 'FP'

        return tp, fp, fn, gt_object, p_object

    def score(self):
        total_tp = 0
        total_fp = 0
        total_fn = 0
        total_distances = []

        for object_id in self.ground_truth['ObjectID'].unique():
            _, _, _, gt_object, p_object = self.evaluate(object_id)

            total_tp += len(p_object[p_object['classification'] == 'TP'])
            total_fp += len(p_object[p_object['classification'] == 'FP'])
            total_fn += len(gt_object[gt_object['classification'] == 'FN'])
            total_distances.extend(
                p_object[p_object['classification'] == 'TP']['distance'].tolist()
            )

        precision = total_tp / (total_tp + total_fp) \
            if (total_tp + total_fp) != 0 else 0
        recall = total_tp / (total_tp + total_fn) \
            if (total_tp + total_fn) != 0 else 0
        f2 = (5 * total_tp) / (5 * total_tp + 4 * total_fn + total_fp) \
            if (5 * total_tp + 4 * total_fn + total_fp) != 0 else 0
        rmse = np.sqrt((sum(d ** 2 for d in total_distances) / len(total_distances))) if total_distances else 0

        return precision, recall, f2, rmse

    def plot(self, object_id):
        tp, fp, fn, gt_object, p_object = self.evaluate(object_id)
        tp_distances = p_object[p_object['classification'] == 'TP']['distance']
        mse = np.sqrt(mean_squared_error([0] * len(tp_distances), tp_distances)) if tp_distances.size else 0
        fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), sharex=True)
        ground_truth_EW = gt_object[gt_object['Direction'] == 'EW']
        ground_truth_NS = gt_object[gt_object['Direction'] == 'NS']
        participant_EW = p_object[p_object['Direction'] == 'EW']
        participant_NS = p_object[p_object['Direction'] == 'NS']
        self._plot_type_timeline(ground_truth_EW, participant_EW, ax1, 'EW')
        self._plot_type_timeline(ground_truth_NS, participant_NS, ax2, 'NS')
        plt.xlabel('TimeIndex')
        title_info = f"Object {object_id}: TPs={tp}, FPs={fp}, FNs={fn}"
        fig.suptitle(title_info, fontsize=10)
        plt.tight_layout(rect=[0, 0.08, 1, 0.96])
        legend_elements = [
            plt.Line2D([0], [0], color='green', linestyle='dashed', label='True Positive (TP)'),
            plt.Line2D([0], [0], color='blue', linestyle='dashed', label='False Positive (FP)'),
            plt.Line2D([0], [0], color='red', linestyle='dashed', label='False Negative (FN)'),
            patches.Patch(color='grey', alpha=0.2, label='Tolerance Interval')
        ]
        plt.legend(handles=legend_elements, loc='lower center', bbox_to_anchor=(0.5, -0.5), ncol=4)
        plt.show()

    def _plot_type_timeline(self, ground_truth_type, participant_type, ax,
                            type_label):
        for _, row in ground_truth_type.iterrows():
            label = row['Node'] + '-' + row['Type']
            ax.scatter(row['TimeIndex'], 2, color='black')
            ax.text(row['TimeIndex'] + 3, 2.05, label, rotation=45)
            ax.fill_betweenx([1, 2], row['TimeIndex'] - self.tolerance,
                             row['TimeIndex'] + self.tolerance, color='grey',
                             alpha=0.2)
            if row['classification'] == 'TP':
                ax.text(row['TimeIndex'] + self.tolerance + .5, 1.5,
                        str(row['distance']),
                        color='black')
                ax.plot([row['TimeIndex'],
                         row['TimeIndex'] + row['distance']], [2, 1],
                         color='green', linestyle='dashed')
            elif row['classification'] == 'FP':
                ax.plot([row['TimeIndex'],
                         row['TimeIndex'] + row['distance']], [2, 1],
                         color='blue', linestyle='dashed')
            elif row['classification'] == 'FN':
                ax.plot([row['TimeIndex'],
                         row['TimeIndex']], [2, 2.2], color='red',
                         linestyle='dashed')

        for _, row in participant_type.iterrows():
            label = row['Node'] + '-' + row['Type']
            ax.scatter(row['TimeIndex'], 1, color='black')
            ax.text(row['TimeIndex'] + 3, 1.05, label, rotation=45)
            if row['classification'] == 'FP' and row['matched'] == False:
                ax.plot([row['TimeIndex'], row['TimeIndex']], [1, 0.8],
                        color='blue', linestyle='dashed')

        ax.spines['left'].set_color('none')
        ax.spines['right'].set_color('none')
        ax.spines['top'].set_color('none')
        ax.yaxis.grid(True)
        ax.set_yticks([1, 2])
        ax.set_yticklabels(['Participant', 'Ground truth'])
        ax.set_title(type_label)

def merge_label_files(label_folder):
    """
    Merges all label files in a given folder into a single pandas DataFrame.
    The filenames must be in the format <ObjectID>.csv, and the object id will
    be extracted from the filename and added as a column to the DataFrame.

    Args:
        label_folder (str): The path to the folder containing the label files.

    Returns:
        pandas.DataFrame: A DataFrame containing the merged label data.
    """
    label_data = []
    label_folder = Path(label_folder).expanduser()
    for file_path in label_folder.ls():
        df = pd.read_csv(file_path)
        oid_s = os.path.basename(file_path).split('.')[0]  # Extract ObjectID from filename
        df['ObjectID'] = int(oid_s)
        label_data.append(df)

    label_data = pd.concat(label_data)
    label_data = label_data[['ObjectID'] + list(label_data.columns[:-1])]
    return label_data

def run_evaluator(ground_truth_path=None, participant_path=None, plot_object=None):

    if participant_path is None:
        participant_df = pd.read_csv('participant_toy.csv')
    else:
        participant_path = Path(participant_path).expanduser()
        if participant_path.is_dir():
            participant_df = merge_label_files(participant_path)
        else:
            participant_df = pd.read_csv(participant_path)

    if ground_truth_path is None:
        ground_truth_df = pd.read_csv('ground_truth_toy.csv')
    else:
        ground_truth_path = Path(ground_truth_path).expanduser()
        if ground_truth_path.is_dir():
            ground_truth_df = merge_label_files(ground_truth_path)
        else:
            ground_truth_df = pd.read_csv(ground_truth_path)

    # Create a NodeDetectionEvaluator instance
    evaluator = NodeDetectionEvaluator(ground_truth_df, participant_df, tolerance=6)
    precision, recall, f2, rmse = evaluator.score()
    print(f'Precision: {precision:.2f}')
    print(f'Recall: {recall:.2f}')
    print(f'F2: {f2:.2f}')
    print(f'RMSE: {rmse:.2f}')

    # Plot the evaluation for the selected object (if any)
    if plot_object:
        evaluator.plot(object_id=plot_object)
    return precision, recall, f2, rmse

if __name__ == "__main__":
    if 'ipykernel' in sys.modules:
        run_evaluator(plot_object=True)
    else:
        # Parse the arguments
        parser = argparse.ArgumentParser()
        parser.add_argument('--participant', type=str, required=False,
                            help='Path to the participant file or folder. \
                                If a folder is provided, all the CSV files in the \
                                    folder will be used. If none, the toy example \
                                        will be used.')
        parser.add_argument('--ground_truth', type=str, required=False,
                            help='Path to the ground truth file. If none, the toy \
                                example will be used.')
        parser.add_argument('--plot_object', type=int, required=False,
                    help='Object ID to plot.')
        args = parser.parse_args()
        run_evaluator(args.ground_truth, args.participant, args.plot_object)