import gzip
from lxml import etree

def open_xournal(filename):
    with gzip.open(filename, 'rb') as f:
        ET = etree.parse(f)
    ET.getroot().remove(ET.xpath('//preview')[0])
    return ET

class XournalLayer:
    def __init__(self):
        self.items = []

    @classmethod
    def fromelem(cls, elem):
        self = cls()
        self.elem = elem
        for item in elem:
            # image, stroke, text
            self.items.append(etree.tostring(item, encoding='unicode').strip())
        return self

class XournalPage:
    def __init__(self):
        self.layers = []
        self.background = None
        self.attr = dict()

    @classmethod
    def fromelem(cls, elem):
        self = cls()
        self.elem = elem
        self.attr = dict(elem.attrib)
        for child in elem:
            if child.tag == 'layer':
                self.layers.append(XournalLayer.fromelem(child))
            elif child.tag == 'background':
                self.background = etree.tostring(child, encoding='unicode').strip()
            else:
                print(child)
                assert False
        return self

class XournalDocument:
    def __init__(self):
        self.filename = '?'
        self.title = '?'
        self.pages = []

    @classmethod
    def fromfile(cls, filename):
        self = cls()
        self.filename = filename
        tree = open_xournal(filename)
        self.title = tree.xpath('//title')[0].text
        pages = tree.xpath('//page')
        self.pages = [XournalPage.fromelem(page) for page in pages]
        return self

    def pprint(self):
        print('Document', self.filename)
        for i, page in enumerate(self.pages):
            print('||page', i, page.attr)
            print('|| - background', page.background)
            for j, layer in enumerate(page.layers):
                print('|| - layer', j)
                for item in layer.items:
                    print('||    -', item)
        print()

    def save(self, filename):
        tree = etree.Element('xournal')
        with gzip.open(filename, 'wb') as f:
            xournal = etree.SubElement(tree, 'xournal', attrib=dict(creator='xournal++ mergetool', fileversion='4'))
            title = etree.SubElement(xournal, 'title')
            title.text = self.title
            for page in self.pages:
                page_elem = etree.SubElement(xournal, 'page', attrib=page.attr)
                page_elem.append(etree.fromstring(page.background))
                for layer in page.layers:
                    layer_elem = etree.SubElement(page_elem, 'layer')
                    for item in layer.items:
                        layer_elem.append(etree.fromstring(item))
            f.write(etree.tostring(xournal, xml_declaration=True, encoding='utf-8', pretty_print=True))

    def __repr__(self):
        return f'Xournal({repr(self.filename)})'

def _merge3atom(root, a, b):
    if root != a:
        return a
    if root != b:
        return b
    return root

def _merge3dict(root, a, b):
    out = {}
    k = set(root.keys()) | set(a.keys()) | set(b.keys())
    for key in k:
        value = _merge3atom(root.get(key), a.get(key), b.get(key))
        if value is not None:
            out[key] = value
    return out

def _merge3list(root, a, b):
    root_lookup = set(root)
    a_lookup = set(a)
    b_lookup = set(b)
    removed = root_lookup - a_lookup - b_lookup
    added = (a_lookup - root_lookup) | (b_lookup - root_lookup)
    return list(root_lookup - removed) + list(added)

def merge_page(root, a, b):
    '''3-way automatic page merge

    root, a, b are XournalPage objects.
    in case of unresolved conflicts (mostly background), page a wins
    '''
    c = XournalPage()
    c.background = _merge3atom(root.background, a.background, b.background)
    c.attr = _merge3dict(root.attr, a.attr, b.attr)
    assert len(root.layers) == len(a.layers) == len(b.layers)
    for i in range(len(root.layers)):
        layer = XournalLayer()
        layer.items = _merge3list(root.layers[i].items, a.layers[i].items, b.layers[i].items)
        c.layers.append(layer)
    return c

def main():
    fn_root = 'root.xopp'
    fn_a = 'a.xopp'
    fn_b = 'b.xopp'
    fn_out = 'merged.xopp'

    import argparse
    parser = argparse.ArgumentParser(description='Merge xournal++ files')
    parser.add_argument('--root', default=fn_root, help='root file')
    parser.add_argument('--left', default=fn_a, help='file a')
    parser.add_argument('--right', default=fn_b, help='file b')
    parser.add_argument('--out', default=fn_out, help='output file')
    parser.add_argument('--verbose', default=False, action='store_true', help='verbose output')
    args = parser.parse_args()
    fn_root = args.root
    fn_a = args.left
    fn_b = args.right
    fn_out = args.out
    flag_verbose = args.verbose

    root = XournalDocument.fromfile(fn_root)
    a = XournalDocument.fromfile(fn_a)
    b = XournalDocument.fromfile(fn_b)

    if flag_verbose:
        root.pprint()
        a.pprint()
        b.pprint()

    c = XournalDocument()
    npages_common = min(len(root.pages), len(a.pages), len(b.pages))
    for i in range(npages_common):
        page = merge_page(root.pages[i], a.pages[i], b.pages[i])
        c.pages.append(page)
    c.pages.extend(a.pages[npages_common:])
    c.pages.extend(b.pages[npages_common:])

    if flag_verbose:
        c.pprint()
    c.title = _merge3atom(root.title, a.title, b.title)

    c.save(fn_out)

    if flag_verbose:
        with gzip.open(fn_out, 'rt') as f:
            print(f.read())

if __name__ == '__main__':
    main()


from django.core.urlresolvers import reverse
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

from signup.utils import send_email

from .models import WictUser

class WictUserAdmin(admin.ModelAdmin):
	def send_review_email(self, request, queryset):
		reviewers = queryset.filter(is_reviewer=True)
		for reviewer in reviewers:
			full_url = request.build_absolute_uri(reverse('website_reviews'))
			context = {
				"full_url": full_url
			}

			# this template is loaded from a different app... but it makes
			# so much more sense to place that template there
			send_email(
				'admin/review/articles_to_review_email.txt',
				context,
				reviewer.email
			)

		msg = u'Foram enviados emails para os seguintes revisores: (%i)'
		self.message_user(request, _(msg % len(reviewers)))
		for reviewer in reviewers:
			self.message_user(request, reviewer.get_full_name())

	def submitted_article(self, user):
		return user.article_set.count() != 0
	submitted_article.boolean = True
	submitted_article.short_description = _(u'Submeteu artigo')

	list_display = ('full_name', 'email', 'submitted_article', 'is_reviewer', 'is_active')
	list_filter = ('is_reviewer', 'is_admin', 'is_staff', 'is_active')
	actions = ['send_review_email']

admin.site.register(WictUser, WictUserAdmin)


import os, sys
from sklearn.svm import OneClassSVM
from analog.bin.machine_learning.TfidfVector import TfidfVector
from datetime import datetime
import re
import numpy as np
from urllib.parse import unquote
from sklearn.model_selection import ParameterGrid
import pickle

class Train:
    def __init__(self, path=None):
        self.root_path = path
        self.set_path = os.path.join(self.root_path, "analog/sample_set/")

        self.train_log_path = os.path.join(self.root_path, "analog/sample_set/train.txt")
        self.test_black_path = os.path.join(self.root_path, "analog/sample_set/test_black_log.txt")
        self.test_white_path = os.path.join(self.root_path, "analog/sample_set/test_white_log.txt")
        self.result_path = os.path.join(self.root_path, "analog/sample_set/result.txt")
        self.complete = False
        # self.test_log_path = os.path.join(self.root_path, "analog/sample_set/test.txt")

    def is_complete(self):
        return self.complete

    def set_complete(self, v: bool):
        self.complete = v

    def read_txt(self, path: str, l: list, encoding='utf-8'):
        log_Pattern = r'^(?P<remote_addr>.*?) - (?P<remote_user>.*) \[(?P<time_local>.*?) \+[0-9]+?\] "(?P<request>.*?)" ' \
                      '(?P<status>.*?) (?P<body_bytes_sent>.*?) "(?P<http_referer>.*?)" "(?P<http_user_agent>.*?)"$'
        log_regx = re.compile(log_Pattern)
        flag = False
        # 读取样本集(日志格式)
        with open(path, "r", encoding=encoding) as file:
            line = file.readline().strip("\r\n")
            while line:
                log_tuple = log_regx.search(line)
                line = file.readline().strip("\r\n")
                if log_tuple is None and len(l) == 0:
                    flag = True
                    break
                if log_tuple is not None:
                    l.append(TfidfVector.get_url(log_tuple.group('request')))
        if flag:
            # 读取样本集(纯路径格式)
            with open(path, "r", encoding=encoding) as file:
                line = file.readline().strip("\r\n")
                while line:
                    l.append(line)
                    line = file.readline().strip("\r\n")

    @staticmethod
    def get_url(request: str, unquote_url=False):
        """
        处理日志里面的request（如:GET /admin/login.php HTTP/1.0 )
        只保留路径部分
        """
        if request.startswith(("GET", "POST")):
            if unquote_url:
                res = unquote(request.strip("GETPOSTHTTP/1.10").strip())
            else:
                res = request.strip("GETPOSTHTTP/1.10").strip()
        else:
            if unquote_url:
                res = unquote(request.strip())
            else:
                res = request.strip()
        return res.ljust(2)

    def get_model(self, queue=None):
        log_Pattern = r'^(?P<remote_addr>.*?) - (?P<remote_user>.*) \[(?P<time_local>.*?) \+[0-9]+?\] "(?P<request>.*?)" ' \
                      '(?P<status>.*?) (?P<body_bytes_sent>.*?) "(?P<http_referer>.*?)" "(?P<http_user_agent>.*?)"$'
        log_regx = re.compile(log_Pattern)
        # 输出重定向
        __console__ = sys.stdout
        sys.stdout = open(os.path.join(self.root_path, "analog/log/train_log.txt"), 'w+')
        start = datetime.now()
        print("Start at {}".format(
                start.strftime("%Y/%m/%d %H:%M:%S")))

        train_example = []
        white_example = []
        black_example = []

        # 读取训练集
        self.read_txt(self.train_log_path, train_example)
        # with open(self.train_log_path, "r") as file:
        #     line = file.readline().strip("\r\n")
        #     while line:
        #         log_tuple = log_regx.search(line)
        #         line = file.readline().strip("\r\n")
        #         if log_tuple is not None:
        #             train_example.append(TfidfVector.get_url(log_tuple.group('request')))

        # 读取黑样本集
        self.read_txt(self.test_black_path, black_example)
        # with open(self.test_black_path, "r") as file:
        #     line = file.readline().strip("\r\n")
        #     while line:
        #         log_tuple = log_regx.search(line)
        #         line = file.readline().strip("\r\n")
        #         if log_tuple is not None:
        #             black_example.append(TfidfVector.get_url(log_tuple.group('request')))

        # 读取白样本集(日志格式)
        self.read_txt(self.test_white_path, white_example)
        # with open(test_white_path, "r") as file:
        #     line = file.readline().strip("\r\n")
        #     while line:
        #         log_tuple = log_regx.search(line)
        #         line = file.readline().strip("\r\n")
        #         if log_tuple is not None:
        #             white_example.append(TfidfVector.get_url(log_tuple.group('request')))

        # 读取白样本集(纯路径格式)
        # with open(self.test_white_path, "r") as file:
        #     line = file.readline().strip("\r\n")
        #     while line:
        #         white_example.append(line)
        #         line = file.readline().strip("\r\n")

        tf_idf_vector = TfidfVector()
        # 特征向量化训练样本
        train_vector = tf_idf_vector.fit_vector

        # 特征向量化黑白样本
        test_normal_vector = tf_idf_vector.transform(white_example)
        test_abnormal_vector = tf_idf_vector.transform(black_example)

        y = [1] * (len(train_example))

        # ============================================= 遍历调优参数nu与gamma ==========================================
        grid = {'gamma': np.logspace(-8, 1, 10),
                'nu': np.linspace(0.01, 0.20, 20)}

        # 核函数(rbf,linear,poly)
        kernel = 'rbf'

        # 最高准确度、召回率、F1值纪录
        max_F1 = 0
        max_Re = 0
        max_Pr = 0

        # 最高准确度、召回率、F1值时参数gamma的值
        gamma_r_F1 = 0.01
        gamma_r_Re = 0.01
        gamma_r_Pr = 0.01

        # 最高准确度、召回率、F1值时参数nu的值
        nu_r_F1 = 0
        nu_r_Re = 0
        nu_r_Pr = 0

        svdd = OneClassSVM(kernel=kernel)
        zero_count = 0
        re_gamma = 0

        total_loop = len(ParameterGrid(grid))
        process_count = 0
        for z in ParameterGrid(grid):
            process_count += 1

            queue.put_nowait("{:0.4f}".format(process_count / total_loop))
            if re_gamma == z.get('gamma'):
                if zero_count >= 4:
                    continue
            else:
                zero_count = 0
                # re_gamma = z.get('gamma')
                # zero_count = 0
            #     print("This parameter gamma({}) maybe too small. So pass it for saving time.".format(z.get('gamma')))
            #
            # if :
            #     continue
            svdd.set_params(**z)
            svdd.fit(train_vector, y)
            k = svdd.get_params()
            # 正常样本测试
            f = svdd.predict(test_normal_vector)

            TP = f.tolist().count(1)  # True positive
            FN = f.tolist().count(-1)  # False Negative

            # 异常样本测试
            f = svdd.predict(test_abnormal_vector)

            FP = f.tolist().count(1)  # False positive
            Precision = 0 if TP == 0 else (TP / (TP + FP))  # Precision
            Recall = 0 if TP == 0 else (TP / (TP + FN))  # Recall
            if Recall == 0 or Precision == 0:
                F1_score = 0
                zero_count += 1
                re_gamma = k.get('gamma')
            else:
                F1_score = 2 * Precision * Recall / (Precision + Recall)  # F1 value

            if F1_score > max_F1:
                max_F1 = F1_score
                nu_r_F1 = k.get('nu')
                gamma_r_F1 = k.get('gamma')

            if Recall > max_Re:
                max_Re = Recall
                nu_r_Re = k.get('nu')
                gamma_r_Re = k.get('gamma')

            if Precision > max_Pr:
                max_Pr = Precision
                nu_r_Pr = k.get('nu')
                gamma_r_Pr = k.get('gamma')

            print("========================== [{}] ===========================".format(
                    datetime.now().strftime("%Y/%m/%d %H:%M:%S")))
            print("nu: ", k.get('nu'), 'gamma', k.get('gamma'), )
            print("Precision: {}%".format(Precision * 100))
            print("Recall: {}%".format(Recall * 100))
            print("F1 score: {}".format(F1_score))
        print("========================== [{}] ===========================".format(
                datetime.now().strftime("%Y/%m/%d %H:%M:%S")))

        print("MAX Precision:  {:^20.6f}When Current nu: {:^20.6f} and gamma: {:0.8f}".format(max_Pr, nu_r_Pr,
                                                                                gamma_r_Pr))
        print("MAX Recall:     {:^20.6f}When Current nu: {:^20.6f} and gamma: {:0.8f}".format(max_Re, nu_r_Re,
                                                                                gamma_r_Re))
        print("MAX F1:         {:^20.6f}When Current nu: {:^20.6f} and gamma: {:0.8f}".format(max_F1, nu_r_F1,
                                                                                gamma_r_F1))
        total_second = datetime.now() - start
        print("Cost {}s.".format(total_second.total_seconds()))
        queue.put_nowait("1")
        with open(os.path.join(self.root_path, "analog/cache/model.pkl"), 'wb') as file:
            svdd.set_params(kernel=kernel, nu=nu_r_F1, gamma=gamma_r_F1)
            svdd.fit(train_vector, y)
            pickle.dump(svdd, file)
        self.complete = True


import json
import logging
from hashlib import sha1
from datetime import datetime
from typing import Union, Callable, Awaitable, Optional, List, Any, Tuple
from uuid import uuid4

from dotty_dict import dotty
from pydantic import PrivateAttr, validator, BaseModel, ValidationError

from tracardi.exceptions.exception_service import get_traceback
from tracardi.service.utils.getters import get_entity_id

from tracardi.config import tracardi
from ...service.profile_merger import ProfileMerger
from ..console import Console
from ..event import Event
from ..event_metadata import EventPayloadMetadata
from ..event_source import EventSource
from ..geo import Geo
from ..identification_point import IdentificationPoint
from ..marketing import UTM
from ..payload.event_payload import EventPayload
from ..session import Session, SessionMetadata, SessionTime
from ..time import Time
from ..entity import Entity
from ..profile import Profile
from ...exceptions.log_handler import log_handler
from user_agents import parse

from tracardi.service.storage.driver.elastic import identification as identification_db
from ...service.utils.languages import language_codes_dict, language_countries_dict
from ...service.utils.parser import parse_accept_language

logger = logging.getLogger(__name__)
logger.setLevel(tracardi.logging_level)
logger.addHandler(log_handler)

class ScheduledEventConfig:

    def __init__(self, flow_id: Optional[str], node_id: Optional[str]):
        self.node_id = node_id
        self.flow_id = flow_id

    def is_scheduled(self) -> bool:
        return self.node_id is not None and self.flow_id is not None

    def __repr__(self):
        return f"ScheduledEventConfig(node_id={self.node_id}, flow_id={self.flow_id})"

class TrackerPayload(BaseModel):

    _id: str = PrivateAttr(None)
    _make_static_profile_id: bool = PrivateAttr(False)
    _scheduled_flow_id: str = PrivateAttr(None)
    _scheduled_node_id: str = PrivateAttr(None)
    _tracardi_referer: dict = PrivateAttr({})

    source: Union[EventSource, Entity]  # When read from a API then it is Entity then is replaced by EventSource
    session: Optional[Entity] = None

    metadata: Optional[EventPayloadMetadata]
    profile: Optional[Entity] = None
    context: Optional[dict] = {}
    properties: Optional[dict] = {}
    request: Optional[dict] = {}
    events: List[EventPayload] = []
    options: Optional[dict] = {}
    profile_less: bool = False
    debug: Optional[bool] = False

    def __init__(self, **data: Any):
        data['metadata'] = EventPayloadMetadata(
            time=Time(
                insert=datetime.utcnow()
            ))
        super().__init__(**data)
        self._id = str(uuid4())
        self._tracardi_referer = self.get_tracardi_data_referer()
        if 'scheduledFlowId' in self.options and 'scheduledNodeId' in self.options:
            if isinstance(self.options['scheduledFlowId'], str) and isinstance(self.options['scheduledNodeId'], str):
                if len(self.events) > 1:
                    raise ValueError("Scheduled events may have only one event per tracker payload.")
                if self.source.id[0] != "@":
                    raise ValueError("Scheduled events must be send via internal scheduler event source.")
                self._scheduled_flow_id = self.options['scheduledFlowId']
                self._scheduled_node_id = self.options['scheduledNodeId']

    @property
    def tracardi_referer(self):
        return self._tracardi_referer

    @property
    def scheduled_event_config(self) -> ScheduledEventConfig:
        return ScheduledEventConfig(flow_id=self._scheduled_flow_id, node_id=self._scheduled_node_id)

    def _replace_profile(self, profile_id):
        self.profile = Entity(id=profile_id)
        self.profile_less = False
        self.options.update({"saveProfile": True})

    def _replace_session(self, session_id):
        self.session = Entity(id=session_id)
        self.profile_less = False
        self.options.update({"saveSession": True})

    def generate_profile_and_session_for_webhook(self, console_log: list) -> bool:

        """

        Returns True if profile or session generated

        :param console_log:
        :return:

        """
        if isinstance(self.source, EventSource):

            if 'webhook' in self.source.type:
                if self.source.config is not None:
                    if 'generate_profile' in self.source.config:
                        if self.source.config['generate_profile'] is True:

                            if 'replace_session_id' in self.source.config:
                                try:
                                    session_id_ref = self.source.config['replace_session_id'].strip()
                                    if bool(session_id_ref):
                                        # Webhooks have only one event, so it is save to get it from self.events[0]
                                        session_id = self.events[0].properties[session_id_ref]
                                        self._replace_session(session_id)
                                except KeyError as e:
                                    message = f"Could not generate set session for a webhook. " \
                                              f"Event stays session-less. " \
                                              f"Probable reason: Missing data: {str(e)}"
                                    logger.error(message)
                                    console_log.append(Console(
                                        flow_id=None,
                                        node_id=None,
                                        event_id=None,
                                        profile_id=get_entity_id(self.profile),
                                        origin='tracker',
                                        class_name=__name__,
                                        module=__name__,
                                        type='error',
                                        message=message,
                                        traceback=get_traceback(e)
                                    ))

                            if 'replace_profile_id' in self.source.config:
                                try:
                                    profile_id_ref = self.source.config['replace_profile_id'].strip()
                                    if bool(profile_id_ref):
                                        # Webhooks have only one event, so it is save to get it from self.events[0]
                                        profile_id = self.events[0].properties[profile_id_ref]
                                        self._replace_profile(profile_id)
                                except KeyError as e:
                                    message = f"Could not generate profile and session for a webhook. " \
                                              f"Event stays profile-less. " \
                                              f"Probable reason: Missing data: {str(e)}"
                                    logger.error(message)
                                    console_log.append(Console(
                                        flow_id=None,
                                        node_id=None,
                                        event_id=None,
                                        profile_id=get_entity_id(self.profile),
                                        origin='tracker',
                                        class_name=__name__,
                                        module=__name__,
                                        type='error',
                                        message=message,
                                        traceback=get_traceback(e)
                                    ))

                            if not self.profile:
                                self._replace_profile(str(uuid4()))

                            if not self.session:
                                self._replace_session(str(uuid4()))

                            return True
        else:
            logger.error("Can't generate profile. Method _generate_profile_and_session used before "
                         "EventSource was created.")

        return False

    def has_type(self, event_type):
        for event_payload in self.events:
            if event_payload.type == event_type:
                return True
        return False

    def get_event_properties(self, event_type) -> List[dict]:
        for event in self.events:
            if event.type == event_type:
                yield event.properties

    def force_static_profile_id(self, flag=True):
        self._make_static_profile_id = flag

    def has_static_profile_id(self) -> bool:
        return self._make_static_profile_id

    def get_events_dict(self) -> List[dict]:
        # Todo Cache in property - this is expensive
        for event_payload in self.events:
            # Todo PErformance
            yield event_payload.to_event_dict(
                self.source,
                self.session,
                self.profile,
                self.profile_less)
            # yield event_payload.to_event(self.metadata,
            #                              self.source,
            #                              self.session,
            #                              self.profile,
            #                              self.profile_less)
            # yield event_payload.to_event_data_class(self.metadata,
            #                                         self.source,
            #                                         self.session,
            #                                         self.profile,
            #                                         self.profile_less)

    def set_headers(self, headers: dict):
        if 'authorization' in headers:
            del headers['authorization']
        if 'cookie' in headers:
            del headers['cookie']
        self.request['headers'] = headers

    def get_id(self) -> str:
        return self._id

    def get_finger_print(self) -> str:
        jdump = json.dumps(self.dict(exclude={'events': ..., 'metadata': ...}), sort_keys=True, default=str)
        props_hash = sha1(jdump.encode())
        return props_hash.hexdigest()

    def has_events(self):
        return len(self.events) > 0

    def set_ephemeral(self, flag=True):
        self.options.update({
            "saveSession": not flag,
            "saveEvents": not flag
        })

    def force_session(self, session):
        # Get session
        if self.session is None or self.session.id is None:
            # Generate random
            self.session = session

    def is_on(self, key, default):
        if key not in self.options or not isinstance(self.options[key], bool):
            # default value
            return default

        return self.options[key]

    def is_debugging_on(self) -> bool:
        return tracardi.track_debug and self.is_on('debugger', default=False)

    async def get_static_profile_and_session(self,
                                             session: Session,
                                             profile_loader: Callable[['TrackerPayload', bool], Awaitable],
                                             profile_less: bool) -> Tuple[Optional[Profile], Session]:

        if profile_less:
            profile = None
        else:
            if not self.profile or not self.profile.id:
                raise ValueError("Can not use static profile id without profile.id.")

            profile = await profile_loader(self, True)  # is_static is set to true
            if not profile:
                profile = Profile(
                    id=self.profile.id
                )
                profile.operation.new = True

            if session is None:
                session = Session(
                    id=self.session.id,
                    metadata=SessionMetadata(
                        time=SessionTime(
                            insert=datetime.utcnow()
                        )
                    )
                )
                session.operation.new = True

                if isinstance(session.context, dict):
                    session.context.update(self.context)
                else:
                    session.context = self.context

                if isinstance(session.properties, dict):
                    session.properties.update(self.properties)
                else:
                    session.properties = self.properties

                # # Remove the session from cache we just created one.
                # # We repeat it when saving.
                # cache.session_cache().delete(self.session.id)

        return profile, session

    def get_tracardi_data_referer(self) -> dict:

        try:
            return self.context['tracardi']['pass']
        except KeyError:
            return {}

    def get_referer_data(self, type: str) -> Optional[str]:
        if self._tracardi_referer:
            if type in self._tracardi_referer:
                return self._tracardi_referer[type].strip()
        return None

    def has_referred_profile(self) -> bool:
        refer_profile_id = self.get_referer_data('profile')
        if refer_profile_id is None:
            return False
        if self.profile is None:
            return True
        return self.profile.id != refer_profile_id.strip()

    async def list_identification_points(self):
        return list(await self.get_identification_points())

    def get_profile_attributes_via_identification_data(self, valid_identification_points) -> Optional[List[Tuple[str, str]]]:
        try:
            # Get first event type and match identification point for it
            _identification = valid_identification_points[0]
            properties = dotty(next(self.get_event_properties(_identification.event_type.id)))
            find_profile_by_fields = []
            for field in _identification.fields:
                if field.event_property.ref and field.profile_trait.ref:
                    if field.event_property.value not in properties:
                        raise AssertionError(f"While creating new profile Tracardi was forced to load data by merging "
                                             f"key because identification must be performed on new profile. "
                                             f"We encountered missing data issue for property "
                                             f"[{field.event_property.value}] in the event property. "
                                             f"Identification point [{_identification.name}] has it defined as customer "
                                             f"merging key but the event has only the properties {properties}.")
                        # error
                    find_profile_by_fields.append((field.profile_trait.value, properties[field.event_property.value]))
            if find_profile_by_fields:
                # load profile
                return find_profile_by_fields
            return None
        except AssertionError as e:
            logger.error(f"Can not find property to load profile by identification data: {str(e)}")
            return None

    async def get_profile_and_session(self, session: Session,
                                      profile_loader: Callable[['TrackerPayload'], Awaitable],
                                      profile_less) -> Tuple[Optional[Profile], Session]:

        """
        Returns session. Creates profile if it does not exist.If it exists connects session with profile.
        """

        is_new_profile = False
        is_new_session = False
        profile = None

        if session is None:  # loaded session is empty

            session = Session(
                id=self.session.id,
                metadata=SessionMetadata(
                    time=SessionTime(
                        insert=datetime.utcnow()
                    )
                )
            )

            logger.debug("New session is to be created with id {}".format(session.id))

            is_new_session = True

            if profile_less is False:

                # Bind profile
                if self.profile is None:

                    # First, check if the tracker_payload does not have events that need merging because
                    # the identification point is defined. In such case we need to try to load profile with
                    # data defined in identification point.

                    # Rafael Bug fixed

                    valid_identification_points = await self.list_identification_points()

                    # Has identification points?
                    if valid_identification_points:
                        # We have new profile and identification point.
                        profile_fields = self.get_profile_attributes_via_identification_data(valid_identification_points)

                        # We have fields that identify profile according to identification point

                        if profile_fields:

                            profile = await ProfileMerger.invoke_merge_profile(
                                Profile.new(),
                                merge_by=profile_fields,
                                limit=1000)

                        # profiles = await profile_driver.load_profiles_to_merge(merge_key_values=profile_fields)
                        print("profiles", profile)
                        print(profile_fields)

                    # If there is still no profile that means that it could not be loaded. It can happen if
                    # event properties did not have all necessary data or the is no profile with defined
                    # attributes.

                    # Then create new profile.

                    if profile is None:

                        # Create empty default profile generate profile_id
                        profile = Profile.new()

                        # Create new profile
                        is_new_profile = True

                        logger.info(
                            "New profile created at UTC {} with id {}".format(profile.metadata.time.insert, profile.id))

                    # if True:  # has identification point
                    #     self.profile = profile
                    #     # load profile by identification data

                else:

                    # ID exists, load profile from storage
                    profile: Optional[Profile] = await profile_loader(self)

                    if profile is None:
                        # Profile id delivered but profile does not exist in storage.
                        # ID was forged

                        profile = Profile.new()

                        # Create new profile
                        is_new_profile = True

                        logger.info(
                            "No merged profile. New profile created at UTC {} with id {}".format(
                                profile.metadata.time.insert,
                                profile.id))

                    else:
                        logger.info(
                            "Merged profile loaded with date {} UTC and id {}".format(profile.metadata.time.insert,
                                                                                profile.id))

                # Now we have profile and we should assign it to session

                session.profile = Entity(id=profile.id)

        else:

            logger.info("Session exists with id {}".format(session.id))

            if profile_less is False:

                # There is session. Copy profile id form session to profile

                if session.profile is not None:
                    # Loaded session has profile

                    # Load profile on profile id saved in session
                    copy_of_tracker_payload = TrackerPayload(**self.dict())
                    copy_of_tracker_payload.profile = Entity(id=session.profile.id)

                    profile: Optional[Profile] = await profile_loader(copy_of_tracker_payload)

                    if isinstance(profile, Profile) and session.profile.id != profile.id:
                        # Profile in session id has been merged. Change profile in session.

                        session.profile.id = profile.id
                        session.metadata.time.timestamp = datetime.timestamp(datetime.utcnow())

                        is_new_session = True

                else:
                    # Corrupted session, or profile less session

                    profile = None

                # Although we tried to load profile it still does not exist.
                if profile is None:
                    # ID exists but profile not exist in storage.

                    profile = Profile.new()

                    # Create new profile
                    is_new_profile = True

                    # Update session as there is new profile. Previous session had no profile.id.
                    session.profile = Entity(id=profile.id)
                    is_new_session = True

        if isinstance(session.context, dict):
            session.context.update(self.context)
        else:
            session.context = self.context

        if isinstance(session.properties, dict):
            session.properties.update(self.properties)
        else:
            session.properties = self.properties

        session.operation.new = is_new_session

        if session.operation.new:

            # Add session created
            self.events.append(
                EventPayload(type='session-opened', properties={})
            )

            # Compute the User Agent data
            try:
                ua_string = session.context['browser']['local']['browser']['userAgent']
                user_agent = parse(ua_string)

                session.os.version = user_agent.os.version_string
                session.os.name = user_agent.os.family

                device_type = 'mobile' if user_agent.is_mobile else \
                    'pc' if user_agent.is_pc else \
                        'tablet' if user_agent.is_tablet else \
                            'email' if user_agent.is_email_client else None

                if 'device' in session.context:
                    session.device.name = session.context['device'].get('name', user_agent.device.family)
                    session.device.brand = session.context['device'].get('brand', user_agent.device.brand)
                    session.device.model = session.context['device'].get('model', user_agent.device.model)
                    session.device.touch = session.context['device'].get('model', user_agent.device.is_touch_capable)
                    session.device.type = session.context['device'].get('type', device_type)
                else:
                    session.device.name = user_agent.device.family
                    session.device.brand = user_agent.device.brand
                    session.device.model = user_agent.device.model
                    session.device.touch = user_agent.is_touch_capable
                    session.device.type = device_type

                if 'location' in self.context:
                    try:
                        session.device.geo = Geo(**self.context['location'])
                        del self.context['location']
                    except ValidationError:
                        pass

                # Get Language from request and geo

                spoken_languages = []
                language_codes = []
                if 'headers' in self.request and 'accept-language' in self.request['headers']:
                    languages = parse_accept_language(self.request['headers']['accept-language'])
                    if languages:
                        spoken_lang_codes = [language for (language, _) in languages if len(language) == 2]
                        for lang_code in spoken_lang_codes:
                            if lang_code in language_codes_dict:
                                spoken_languages += language_codes_dict[lang_code]
                                language_codes.append(lang_code)

                if session.device.geo.country.code:
                    lang_code = session.device.geo.country.code.lower()
                    if lang_code in language_codes_dict:
                        spoken_languages += language_codes_dict[lang_code]
                        language_codes.append(lang_code)

                if spoken_languages:
                    session.context['language'] = list(set(spoken_languages))
                    profile.data.pii.language.spoken = session.context['language']

                if 'geo' not in profile.aux:
                    profile.aux['geo'] = {}

                # Continent

                if 'time' in self.context:
                    tz = self.context['time'].get('tz', 'utc')

                    if tz.lower() != 'utc':
                        continent = tz.split('/')[0]
                    else:
                        continent = 'n/a'

                    profile.aux['geo']['continent'] = continent

                # Aux markets

                markets = []
                for lang_code in language_codes:
                    if lang_code in language_countries_dict:
                        markets += language_countries_dict[lang_code]

                if markets:
                    profile.aux['geo']['markets'] = markets

                # Screen

                try:
                    session.device.resolution = f"{self.context['screen']['local']['width']}x{self.context['screen']['local']['height']}"
                except KeyError:
                    pass

                try:
                    session.device.color_depth = int(self.context['screen']['local']['colorDepth'])
                except KeyError:
                    pass

                try:
                    session.device.orientation = self.context['screen']['local']['orientation']
                except KeyError:
                    pass

                session.app.bot = user_agent.is_bot
                session.app.name = user_agent.browser.family  # returns 'Mobile Safari'
                session.app.version = user_agent.browser.version_string
                session.app.type = "browser"

                if 'utm' in self.context:
                    try:
                        session.utm = UTM(**self.context['utm'])
                        del self.context['utm']
                    except ValidationError:
                        pass

                # session.app.resolution = session.context['screen']

            except Exception as e:
                pass

            try:
                session.device.ip = self.request['headers']['x-forwarded-for']
            except Exception:
                pass

            try:
                session.app.language = session.context['browser']['local']['browser']['language']
            except Exception:
                pass

        # Updates on EXISTING Session

        if 'location' in self.context:
            try:
                # If location is sent but not available in session - update session
                if session.device.geo.is_empty():
                    session.device.geo = Geo(**self.context['location'])
                    session.operation.update = True

                # Add last geo to profile
                profile.data.devices.last.geo = session.device.geo
                profile.operation.update = True
                del self.context['location']
            except ValidationError:
                pass

        # If UTM is sent but not available in session - update session
        if 'utm' in self.context and session.utm.is_empty():
            try:
                session.utm = UTM(**self.context['utm'])
                session.operation.update = True
                del self.context['utm']
            except ValidationError:
                pass

        if isinstance(self.source, EventSource):
            session.metadata.channel = self.source.channel

        if profile_less is False and profile is not None:
            profile.operation.new = is_new_profile

            if profile.operation.new:
                # Add session created
                self.events.append(
                    EventPayload(type='profile-created', properties={})
                )

        return profile, session

    @staticmethod
    async def _load_identification_points():
        identification_points = await identification_db.load_enabled(limit=200)
        return identification_points.to_domain_objects(IdentificationPoint)

    def _get_valid_identification_points(self,
                                         identification_points: List[IdentificationPoint]):
        for identification_point in identification_points:
            if identification_point.source.id != "" and identification_point.source.id != self.source.id:
                continue

            if not self.has_type(identification_point.event_type.id):
                continue

            yield identification_point

    async def get_identification_points(self):
        return self._get_valid_identification_points(await self._load_identification_points())


import asyncio

async def foo():
    print('----start foo')
    await asyncio.sleep(2)
    print('----end foo')

async def bar():
    print('****start bar')
    await asyncio.sleep(1)
    print('****end bar')

async def main():
    task1 = asyncio.create_task(foo())
    task2 = asyncio.create_task(bar())
    # task1 = foo()
    # task2 = bar()
    await task1
    await task2

if __name__ == '__main__':
    asyncio.run(main())
    asyncio.get_event_loop


import pytest
import unittest
import os
import sys
import subprocess
import fvid
import ffpb
import tqdm
import platform

from helper import SkippableTest
from shlex import split
from collections import namedtuple
from functools import reduce

proc_output = namedtuple('proc_output', 'stdout stderr')

def pipeline(starter_command, *commands):
    if not commands:
        try:
            starter_command, *commands = starter_command.split('|')
        except AttributeError:
            pass
    starter_command = _parse(starter_command)
    starter = subprocess.Popen(starter_command, stdout=subprocess.PIPE)
    last_proc = reduce(_create_pipe, map(_parse, commands), starter)
    return proc_output(*last_proc.communicate())

def _create_pipe(previous, command):
    proc = subprocess.Popen(command, stdin=previous.stdout, stdout=subprocess.PIPE)
    previous.stdout.close()
    return proc

def _parse(cmd):
    try:
        ok = list(map(str, split(cmd)))
        print(ok)
        return ok
    except Exception:
        return cmd

class FvidTestCase(unittest.TestCase):
    def test_decode_from_yt(self):
        logging_info = ""
        encoded_yt_videos = [i for i in sorted(os.listdir('../tests/encoded/'), reverse=True) if i.lower().startswith('yt')]
        for video_name in encoded_yt_videos:
            cmd = "python3 -m" + video_name[2:-4] + " -i '../tests/encoded/" + video_name + "'"
            if platform.system().lower() in ("linux", "darwin"):
                cmd += ' -o /dev/null'
            elif platform.system().lower() in ("windows",):
                cmd += ' -o nul'
            resp = pipeline(cmd)[0].decode('utf-8')
            print(resp)
            logging_info += resp
        assert 'error' not in logging_info.lower()

    def test_encode_and_decode_files(self):
        logging_info = ""
        files = [i for i in sorted(os.listdir('../tests/decoded/'), reverse=True) if not i == 'README.txt']
        possible_encodings = ['-ey5', '-ey5 -f 3', '-eyz5', '-eyz']
        for file_name in files:
            for encoding in possible_encodings:
                cmd = "python3 -m fvid " + encoding + " -i ../tests/decoded/" + file_name + " -o '../tests/temp/yt_fvid_" + encoding + ".mp4'"
                resp = pipeline(cmd)[0].decode('utf-8')
                print(resp)
                logging_info += resp
                break # only doing one for now so we can test decoding
            break
        videos = [i for i in sorted(os.listdir('./temp/'), reverse=True)]
        possible_decodings = ['-dy5', '-dy5 -f 3', '-dyz5', '-dyz']
        for video_name in videos:
            for decoding in possible_decodings:
                cmd = "python3 -m" + video_name[2:-4].replace('_', ' ') + " -i ../tests/temp/" + video_name
                if platform.system().lower() in ("linux", "darwin"):
                    cmd += ' -o /dev/null'
                elif platform.system().lower() in ("windows",):
                    cmd += ' -o nul'
                resp = pipeline(cmd)[0].decode('utf-8')
                print(resp)
                logging_info += resp
                break
            break
        print(logging_info.lower())
        assert 'error' not in logging_info.lower()

if __name__ == '__main__':
#    try:
#        print(FvidTestCase().test_decode_from_yt())
#        print(FvidTestCase().test_encode_and_decode_files())
#    except KeyboardInterrupt:
#        pass
    pytest.main([__file__])


#!/usr/bin/env python3
# multi-processing
# Different processes live in different memory spaces, they don't share data
# Need special share memory objects to share data such as Value and Array
from multiprocessing import Pool

def cube(number):
    return number * number * number

# When script is being run directly __name__ = __main__ if it's being imported
#and run indirectly, the __name__ variable is set to the other script
# https://www.geeksforgeeks.org/what-does-the-if-__name__-__main__-do/
if __name__ == "__main__":

    numbers = range(10)
    pool = Pool()
    # important methods: map, apply, join, close
    # create multiple process that should execute a function
    # Will automatically allocate the maximum number of processes available
    # then will split iterable into equal size chunks and submit to function
    result = pool.map(cube, numbers)

    #pool.apply(cube, numbers[0])#executes with one argument

    pool.close()
    pool.join()

    print(result)


def counter(file):
    count = 0
    text = ""
    word = "ey"

    for i in file:
        text = i
        count = count + text.lower().count(word)

    return count

def openFile():
    file = open("msg.txt", "r")
    return file

f = openFile()
print(counter(f))


import torch
from torch.utils.data import Dataset
import os
import json
from random import randint
from torch import nn
from torch.nn import functional as F
import pandas as pd
import numpy as np

def make_dataset(directory, class_to_idx):
    instances = []
    directory = os.path.expanduser(directory)
    for target_class in sorted(class_to_idx.keys()):
        class_index = class_to_idx[target_class]
        target_dir = os.path.join(directory, target_class)
        if not os.path.isdir(target_dir):
            continue
        for root, _, fnames in sorted(os.walk(target_dir, followlinks=True)):
            for fname in sorted(fnames):
                path = os.path.join(root, fname)
                item = path, class_index
                instances.append(item)
    return instances

class CAER_LANDMARK(Dataset):
    def __init__(self, root, min_frames=25, test=False):
        super(CAER_LANDMARK, self).__init__()
        self.root = root
        classes, class_to_idx = self._find_classes(self.root)
        samples = make_dataset(self.root, class_to_idx)
        if len(samples) == 0:
            msg = "Found 0 files in subfolders of: {}\n".format(self.root)
            raise RuntimeError(msg)
        self.classes = classes
        self.class_to_idx = class_to_idx
        self.samples = samples
        self.min_frames = min_frames
        self.test = test

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

    def _find_classes(self, dir):
        """
        Finds the class folders in a dataset.

        Args:
            dir (string): Root directory path.

        Returns:
            tuple: (classes, class_to_idx) where classes are relative to (dir), and class_to_idx is a dictionary.

        Ensures:
            No class is a subdirectory of another.
        """
        classes = [d.name for d in os.scandir(dir) if d.is_dir()]
        classes.sort()
        class_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}
        return classes, class_to_idx

    def __getitem__(self, index: int):
        path, target  = self.samples[index][0], self.samples[index][1]

        with open(path) as json_file:
            data = json.load(json_file)
        ## for the time being just slice
        ld = np.array(data["landmark"])

        #pad if the are not enough frames
        kx = ld[:,:,0]
        ky = ld[:,:,1]
        kx = (kx - np.min(kx))/np.ptp(kx)
        ky = (ky - np.min(ky))/np.ptp(ky)
        norm_ld = np.array([kx,ky]).T
        ld = torch.Tensor(np.rollaxis(norm_ld,1,0))

        num_frames = ld.shape[0]
        if num_frames < self.min_frames:
            pad = self.min_frames - num_frames
            ld = torch.cat((ld,ld[ld.shape[0]-1].repeat(pad,1,1) ), 0)

        if num_frames > self.min_frames:
            start_frame =  randint(0, num_frames-self.min_frames)
        else:
            start_frame = 0

        if self.test:
            start_frame = ld.shape[0] - self.min_frames

        return target, ld[start_frame: start_frame+self.min_frames,17:,: ]


from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

# 重写 jwt 返回方法
def jwt_response_payload_handler(token, user=None, request=None):
    """
    自定义jwt认证成功返回数据
    """
    return {
        'token': token,
        'id': user.id,
        'username': user.username
    }

class PageNum(PageNumberPagination):
    """
        自定义的分页器
    """
    page_size_query_param = 'pagesize'
    max_page_size = 10

    # 由于当前分页器返回的结果不适用于前端，需要重写继承类的返回信息
    def get_paginated_response(self, data):
        return Response({
            'count': self.page.paginator.count,
            'lists': data,
            'page': self.page.number,
            'pages': self.page.paginator.num_pages,
            'pagesize': self.max_page_size
        })


from ta.volume import ChaikinMoneyFlowIndicator as CMF
from . import menu
import os

def calculate(stock,window) :
    # Initiate CMF Indicator Variable
    # Parameters
    # high (pandas.Series) – dataset ‘High’ column.
    # low (pandas.Series) – dataset ‘Low’ column.
    # close (pandas.Series) – dataset ‘Close’ column.
    # volume (pandas.Series) – dataset ‘Volume’ column.
    # window (int) – n period (Default : 20 Period).
    # fillna (bool) – if True, fill nan values.
    CMFIndicator = CMF(high = stock["High"], low = stock["Low"], close = stock["Close"], volume = stock["Volume"],window = window)

    # Add CMF Features to the data frame
    stock["CMF"] = CMFIndicator.chaikin_money_flow()

    stock.loc[stock['CMF'] > 0, 'CMF_Recommend'] = 'BUY'
    stock.loc[stock['CMF'] < 0, 'CMF_Recommend'] = 'SELL'

    print("The CMF Values and Signal Recommendation has been succesfully added!")
    print("Type anything to return to the menu")
    os.system("pause")

    # menu.techIndicatorsMenu(stock)
    return()


# Jayson Yin
# Nov. 27th 2022

# Create a program that will calculate the Return on Investment(ROI) for a rental property

    # Income
        # Rental income = $$$ per month
        # Storage income
        # ect.

        # Total income = All income combined

    # Expenses
        # (Are any of these included?) ask for input
        # Tax
        # Insurance
        # Utilities
        # HOA
        # Repairs
        # CapEx
        # Property Management
        # Mortgage

        # Gather all expenses

    # Cashflow
        # Income - Expenses

    # Cash-on-Cash ROI
        # Down Payment
        # Closing Costs
        # Repair Budget
        # Misc.

        # Total investment = All combined

        # Annual cashflow = monthly cashflow * 12
        # Cash-on-Cash ROI = Annual cashflow / Total investment (will end up as a percentage)

# Gives a list of possible income and expense sources so that they can be changed if needed at a later point
income_sources = ['rental', 'storage', 'misc.']
expense_sources = ['tax', 'insurance', 'utilities', 'HOA', 'repairs', 'property management', 'mortgage', 'misc.']
investment_sources = ['down payment', 'closing costs', 'repairs', 'misc.']

def gather_income():
    print("\nIncome:\n")
    income = 0
    for source in income_sources:
        amount = int(input(f'What will be your monthly income for "{source}" '))
        income += amount
    return income

def gather_expenses():
    print("\nExpenses:\n")
    expenses = 0
    for source in expense_sources:
        amount = int(input(f'What will be your monthly expense for "{source}" '))
        expenses += amount
    return expenses

def gather_investment():
    print("\nInitial Investment:\n")
    investment = 0
    for source in investment_sources:
        amount = int(input(f'How much did you spend on "{source}" '))
        investment += amount
    return investment

def gather_cashflow(income, expenses):
    return income - expenses

def run():
    income = gather_income()
    expenses = gather_expenses()
    cashflow = gather_cashflow(income, expenses)
    investment = gather_investment()
    house1 = ROI(income, expenses, cashflow, investment)
    print(house1.returnOnInvestment())
    house1.showInfo()

# Creating a class to gather and save the information
class ROI():

    def __init__(self, income, expenses, cashflow, investment):
        self.income = income
        self.expenses = expenses
        self.cashflow = cashflow
        self.investment = investment

    def returnOnInvestment(self):
        roi = ((self.cashflow * 12) / self.investment) * 100
        roi = round(roi, 2)
        return f"\nYour return on investment is {roi}%\n"

    def showInfo(self):
        print("\nThis is how we calculated it:")
        print(f"\tIncome: ${self.income}")
        print(f"\tExpenses: ${self.expenses}")
        print(f"\tCashflow ({self.income} - {self.expenses}): ${self.cashflow}")
        print("\nThen on to figuring out how good the investment is:")
        print(f"\tAnnual cashflow ({self.cashflow} * 12): ${self.cashflow * 12}")
        print(f"\t\nROI = ({self.cashflow * 12}/{self.investment})%")

run()


import boto3
import logging
from boto3.dynamodb.conditions import Key
from datetime import datetime
from utils.helper_wo_pandas import weekly_data_db, store_in_s3_bucket_wo_pandas, region, buckets

def handler(event, context) -> None:
    """
    Create the weekly query and store it in S3
    """
    ta_place_id = event.get("trip_advisor_place_id", None)
    if not ta_place_id:
        raise Exception("Trip advisor place ID is not in event")
    if event.get("custom_date", None) is not None:
        today = datetime.strptime(event["custom_date"], "%Y_%m_%d_%H_%M_%S")
    else:
        today = datetime.today()
    today_iso = today.isocalendar()

    # Query from dynamoDB
    dynamodb = boto3.resource('dynamodb', region_name=region)
    table = dynamodb.Table(weekly_data_db)
    response = table.query(
      KeyConditionExpression=Key('ta_place_id').eq(ta_place_id)
    )
    logging.info(response)

    weekly_data = []
    for restaurant in response.get("Items", []):
        if restaurant.get("gm_date", None) is None or restaurant.get("restaurant_name", None) is None:
            continue
        data = {
            "place_id": restaurant["ta_place_id"],
            "restaurant_id": restaurant["ta_restaurant_id"],
            "restaurant_name": restaurant["restaurant_name"],
            "dates": {
                "trip_advisor": restaurant["ta_date"],
                "google_maps": restaurant["gm_date"]
            },
            "scores": dict(),
            "symbol": dict(),
            "services": list(),
            "travellers_choice": restaurant["ta_travellers_choice"]
        }
        trip_advisor_score = float(restaurant["ta_score_overall"])
        google_maps_score = float(restaurant["gm_score_overall"])
        all_scores = [x for x in [trip_advisor_score, google_maps_score] if x >= 0]
        mean_score = round(sum(all_scores)/len(all_scores) if all_scores else -1, 2)
        data["scores"] = {
            "trip_advisor": trip_advisor_score,
            "google_maps": google_maps_score,
            "average": mean_score,
        }
        trip_advisor_symbol = float(restaurant["ta_symbol"])
        google_maps_symbol = float(restaurant["gm_symbol"])
        all_symbols = [x for x in [trip_advisor_symbol, google_maps_symbol] if x >= 0]
        mean_symbol = round(sum(all_symbols) / len(all_symbols) if all_symbols else -1)
        data["symbol"] = {
            "trip_advisor": trip_advisor_symbol,
            "google_maps": google_maps_symbol,
            "average": mean_symbol,
        }
        if restaurant.get("gm_deliver", False):
            data["services"].append("deliver")
        if restaurant.get("gm_dine_in", False):
            data["services"].append("dine in")
        if restaurant.get("gm_reservable", False):
            data["services"].append("reservable")
        if restaurant.get("gm_serves_beer", False):
            data["services"].append("serves beer")
        if restaurant.get("gm_serves_dinner", False) or restaurant.get("ta_serves_dinner", False):
            data["services"].append("serves dinner")
        if restaurant.get("gm_serves_lunch", False) or restaurant.get("ta_serves_lunch", False):
            data["services"].append("serves lunch")
        if restaurant.get("gm_serves_vegetarian_food", False):
            data["services"].append("serves vegetarian food")
        if restaurant.get("gm_serves_wine", False):
            data["services"].append("serves wine")
        if restaurant.get("gm_takeout", False):
            data["services"].append("takeout")
        if restaurant.get("gm_wheelchair_accessible_entrance", False):
            data["services"].append("wheelchair accessible entrance")
        if restaurant.get("ta_serves_breakfast", False):
            data["services"].append("serves breakfast")
        if restaurant.get("ta_serves_brunch", False):
            data["services"].append("serves brunch")

        weekly_data.append(data)

    # Store data in S3
    filename = f"{ta_place_id}_{today.strftime('%Y_%m_%d_%H_%M_%S')}"
    s3_path = f"weekly_query/{ta_place_id}/{today_iso.year}/{today_iso.week}"
    store_in_s3_bucket_wo_pandas(buckets["trip_advisor"], s3_path, weekly_data, filename)


from skimage import io
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage
from math import sqrt,pi

# Manual mean filter to show the working of convolution
# Takes in the size of the kernel and input image as parameters
def mean_filter_manual(size,img):
	correction = size//2
	kernel = np.divide(np.ones((size,size)),size*size)
	res = np.copy(img)

	for i in range(correction,len(img)-correction):
		for j in range(correction,len(img[0])-correction):
			sum = 0

			subImg = img[i-correction:i+correction+1,j-correction:j+correction+1]

			for x in range(size):
				for y in range(size):
					sum += kernel[x][y]*subImg[x][y]
			res[i-1][j-1] = int(sum)

	return res

# Mean filter using the convolution function from ndimage which is faster
# Takes in the size of the kernel and input image as parameters
def mean_filter_auto(size,img):
	kernel = np.divide(np.ones((size,size)),size*size)
	res = ndimage.convolve(img,kernel)
	return res

# Gaussian function
# Takes in the step, mean and standard deviation as parameters
def gaussian(x, mu, sig):
    return 1./(sqrt(2.*pi)*sig)*np.exp(-np.power((x - mu)/sig, 2.)/2)

# Function to create a gaussian kernel
# Size of the kernel is determined by the standard deviation value - Size = 5 * standard deviation
# Takes in the standard deviation as parameter
def gaussian_kernel(sigma):
	size = int(5 * sigma)
	size = size+1 if size%2 == 0 else size
	limit = size//2
	#The range we pick values from must be equal to 5 times sigma
	gaus_range = [x for x in range(-limit,limit+1)]
	kernel = [gaussian(x,0,sigma) for x in gaus_range]
	normalized_kernel = [x/kernel[limit] for x in kernel]
	print(normalized_kernel)
	total = sum(normalized_kernel)
	gauss_kernel = [x/total for x in normalized_kernel]
	print(gauss_kernel)
	return np.array(gauss_kernel).reshape(1,size)

# Applies a gaussian filter to an image and returns the filtered image
# Takes in standard deviation and input image as parameters
def gaussian_filter(sigma,img):
	kernel = gaussian_kernel(sigma)
	print(kernel)
	res = ndimage.convolve(img,kernel)
	kernel = np.transpose(kernel)
	res = ndimage.convolve(img,kernel)
	return res

# Applies a median filter with manual convolution and returns the filtered image
# Takes in the size of kernel and input image as parameters
def median_filter_manual(size,img):
	correction = size//2
	kernel = np.zeros((size,size))
	res = np.copy(img)
	for i in range(correction,len(img)-correction):
		for j in range(correction,len(img[0])-correction):
			kernel = img[i-correction:i+correction+1,j-correction:j+correction+1]
			res[i,j] = np.median(kernel)

	return res

# Applies a median filter using ndimage library which is much faster and returns the filtered image
# Takes in the size of the kernel and input image as parameters
def median_filter_auto(sz,img):
	res = ndimage.median_filter(img,size = sz)
	return res

# Function to display the results of filtering on 4x4 subplots
# Takes in 2 raw images, 2 filtered images, type of filter applied and messages for filtered images as parameters
def display_output(img1,img2,img3,img4,filter,msg):
	fig = plt.figure()
	first = fig.add_subplot(2,2,1)
	io.imshow(img1)
	first.set_title("Gaussian noise image")
	first.axis('off')
	second = fig.add_subplot(2,2,2)
	io.imshow(img2)
	second.set_title("Impulsive noise image")
	second.axis('off')
	a = fig.add_subplot(2,2,3)
	io.imshow(img3)
	a.set_title(filter + " filter with " + msg)
	a.axis('off')
	b = fig.add_subplot(2,2,4)
	io.imshow(img4)
	b.set_title(filter + " filter with " + msg)
	b.axis('off')
	plt.show()

#Test cases
if __name__ == "__main__":
	img1 = io.imread("NoisyImage1.jpg")
	img2 = io.imread('NoisyImage2.jpg')

	mean_res1 = mean_filter_auto(3,img1)
	mean_res2 = mean_filter_auto(3,img2)
	display_output(img1,img2,mean_res1,mean_res2,"Mean","size 3")

	mean_res1 = mean_filter_auto(5,img1)
	mean_res2 = mean_filter_auto(5,img2)
	display_output(img1,img2,mean_res1,mean_res2,"Mean","size 5")

	gaussian_res1 = gaussian_filter(1.4,img1)
	gaussian_res2 = gaussian_filter(1.4,img2)
	display_output(img1,img2,gaussian_res1,gaussian_res2,"Gaussian","sigma 1.4")

	gaussian_res1 = gaussian_filter(1.8,img1)
	gaussian_res2 = gaussian_filter(1.8,img2)
	display_output(img1,img2,gaussian_res1,gaussian_res2,"Gaussian","sigma 1.8")

	median_res1 = median_filter_auto(3,img1)
	median_res2 = median_filter_auto(3,img2)
	display_output(img1,img2,median_res1,median_res2,"Median","size 3")

	median_res1 = median_filter_auto(5,img1)
	median_res2 = median_filter_auto(5,img2)
	display_output(img1,img2,median_res1,median_res2,"Median","size 5")


# -*- coding: utf-8 -*-
"""
Created on Mon Feb 17 21:02:08 2014

@author: ventilator

Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.

A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.

For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both "halves", it is impossible to decrypt the message.

Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.

Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher.txt (right click and 'Save Link/Target As...'), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text.

ascii a = 97, ascii z = 122

"""

import profile

from numpy import loadtxt
from itertools import cycle, product

filename = "p059_cipher.txt"

key_alphabet = ''
for k_value in range(ord("a"),ord("z")+1):
    key_alphabet+= chr(k_value)
print(key_alphabet)

def solve_problem():
    encrypted_text = loadtxt(filename, delimiter=",", dtype = int)
    for key in product(key_alphabet, repeat = 3)     :
        decrypted_text = ''.join(chr(e^ord(k)) for e,k in zip(encrypted_text, cycle(key)))
        if (decrypted_text.find(" the ") > -1): # " the " is better than "the"
            print(decrypted_text)
            print(key)
            sum_ascii = 0
            for char in decrypted_text:
                sum_ascii += ord(char)
            print("Sum of characters")
            print(sum_ascii)
            break

    return 0

solve_problem()
# profile.run('solve_problem()')


# cp required h file to $pwd

import subprocess
import re
import shutil

file = "./Python.h"
#file = "./compile.h"
prepath = re.compile(r'^/usr/include/python2.7/')

def find_hfile(hfilename):
    #subp = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
    #command = ['sudo', 'find', '/', '-name', "'"+hfilename+"'"]    ERROR
    #command = ['find', '/', '-name', "'"+hfilename+"'"]            ERROR
    command = ['find', '/', '-name', hfilename]
    print(command)

    output = subprocess.check_output(command)
    lines = output.split('\n')
    print(lines)
    get_path(lines)

def get_path(path_list):
    for tpath in path_list:
        if prepath.search(tpath):
            print("get the path: " + tpath)
            cpto_pwd(tpath)

def cpto_pwd(abshfpath):
    shutil.copy(abshfpath, "./")
    print("copy...ok"  )

fd   = open(file, "r")
for tmp in fd.readlines():
    if ".h>" in tmp:
        tmp = tmp.split('<')
        tmp = tmp[1].split('>')
        print(tmp[0])
    elif ".h\"" in tmp:
        tmp = tmp.split('"')
        #print(tmp[1])
        find_hfile(tmp[1])
        #command = "sudo find / -name '" + tmp[1] + "'"
        #subprocess.call(command, shell=True)


'''
https://leetcode.com/problems/russian-doll-envelopes/
You have a number of envelopes with widths and heights given as a pair of integers (w, h).
One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope.
What is the maximum number of envelopes can you Russian doll? (put one inside other)

Note:
Rotation is not allowed.

Example:
Input: [[5,4],[6,4],[6,7],[2,3]]
Output: 3
Explanation: The maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
'''
'''
Time:O(nlgn)
Space:O(n)
'''
class Solution:
    def maxEnvelopes(self, envelopes: List[List[int]]) -> int:
        if not envelopes:   return 0
        envelopes.sort(key = lambda x:(x[0],-x[1]))

        def lis(nums):
            dp = []
            for i in range(len(nums)):
                #idx = bisect.bisect_left(dp, nums[i])
                idx = binary(dp,nums[i])
                if idx == len(dp):
                    dp.append(nums[i])
                else:
                    dp[idx] = nums[i]
            return len(dp)

        def binary(dp, num):
            i, j = 0, len(dp)-1
            while i<=j:
                mid = (i+j)//2
                if dp[mid]<num:
                    i = mid+1
                elif dp[mid]>num:
                    j = mid-1
                else:
                    return mid
            return i

        return lis([i[1] for i in envelopes])


from typing import List

def path_to_coordinates(
    path: List[str], coordinates: dict = None, previous_position=(0, 0), previous_step=1
) -> dict:
    coordinates = coordinates if coordinates else dict()

    if not path:
        return coordinates

    x, y = previous_position
    direction, distance = path[0][0], int(path[0][1:])

    for step in range(previous_step, previous_step + distance):
        if direction == "R":
            x += 1
        elif direction == "L":
            x -= 1
        elif direction == "U":
            y += 1
        elif direction == "D":
            y -= 1
        else:
            raise ValueError("Bad direction")

        if (x, y) not in coordinates:
            coordinates[(x, y)] = step

    return path_to_coordinates(path[1:], coordinates, (x, y), previous_step + distance)

def manhattan(coord):
    x, y = coord
    return abs(x) + abs(y)

def intersections(path1: List[str], path2: List[str]) -> set:
    path1_coords = path_to_coordinates(path1)
    path2_coords = path_to_coordinates(path2)

    return set(path1_coords.keys()) & set(path2_coords.keys())

def nearest_intersection(path1, path2):
    return min(intersections(path1, path2), key=lambda coord: manhattan(coord))

def intersections_with_path_length(path1, path2) -> dict:
    path1_coords = path_to_coordinates(path1)
    path2_coords = path_to_coordinates(path2)

    intersections = set(path1_coords.keys()) & set(path2_coords.keys())
    return {coord: path1_coords[coord] + path2_coords[coord] for coord in intersections}

def shortest_intersection_path_length(path1, path2):
    return min(intersections_with_path_length(path1, path2).values())

def parse_path(path_spec):
    return path_spec.split(",")

if __name__ == "__main__":
    with open("input") as fp:
        path_spec1, path_spec2 = fp.readlines()

        path1 = parse_path(path_spec1)
        path2 = parse_path(path_spec2)

        assert path1[5] == "U457"
        assert path2[6] == "L878"

        print(manhattan(nearest_intersection(path1, path2)))
        print(shortest_intersection_path_length(path1, path2))


no_of_pairs=int(input("how many pairs you want to give?"))
L=[]
while len(L)<no_of_pairs:             #it takes input repeatedly till no of given iterations
    pair=input("Give me the pair:").split(',')        #it splits two numbers of input in coma(,) and make a list out of that elements
    L.append(pair)               #it makes list of lists
print(L)
j=[]
for i in L:                #loop for each list inside of the big list L
    j+=i                #concatinating lists inside L
lst=list(set(j))        #removing duplicates by making it a set from list then again make it list.this finally gives us list of unique elements
lst.sort()            #'sort' function arranges elements in accesnding order
print(lst)           #printing a list(lst) of unique numbers which are in accesnding order from list of lists L,these are the key values of dictionary i.e. nodes of graph
V=[]           #initializing a empty list
d={}        #initializing a empty dictionary
for e in lst:         #loop for each element in lst
    v=[]
    for k in L:       #loop for each list inside of the big list L
        if e in k:               #the motive behind this condition is that if a node is present in any list it will remove the node and append the other value to a empty list.This doing for all nodes will give us different nodes connected with a node
            k_copy=k.copy()             #Here I am creating a copy of list so that after removing a particular element, the main list remain intact
            k_copy.remove(e)           #removing the node for which the outermost loop is running
            v.append(int(k_copy[0]))        #appending the other element into empty list v

    d[int(e)]=v         #entering key values for each key e in empty diictionary d
print(d)                      #Here we are printing the dictionary of lists that will show us the nodes(represented as key) and its adjacency nodes(key values)


import argparse
import os
from importlib import resources
import re
import contextlib
import sys

import polycotylus

class CompletionAction(argparse.Action):
    files = {
        "fish": "polycotylus.fish",
    }

    def __call__(self, parser, namespace, shell, option_string=None):
        with contextlib.suppress(Exception):
            if sys.stdout.isatty():  # pragma: no cover
                print("# Pipe the output of this command into source or ~/.config/fish/completions/polycotylus.fish\n",
                      file=sys.stderr, flush=True)
        with resources.open_text("polycotylus._completions", self.files[shell]) as f:
            print(f.read(), end="")
        parser.exit()

class ListLocalizationAction(argparse.Action):
    def __call__(self, parser, namespace, key, option_string=None):
        from polycotylus._yaml_schema import localizations
        with contextlib.suppress(BrokenPipeError):
            print(key.title(), "Tag  Description")
            print("-" * (len(key) + 4), " -----------")
            for (tag, description) in localizations[key].items():
                print(f"{tag}{' ' * (4 + len(key) - len(tag))}  {description}")
        parser.exit()

class ConfigureAction(argparse.Action):
    def __call__(self, parser, namespace, key, option_string=None):
        if not key:
            for option in polycotylus._configuration.options:
                print(f"{option}={polycotylus._configuration.read(option) or ''}")
        else:
            for argument in key:
                match = re.fullmatch(r"([a-z]+)=(.*)", argument)
                if match:
                    if match[2]:
                        polycotylus._configuration.write(*match.groups())
                    else:
                        polycotylus._configuration.clear(match[1])
                else:
                    print(polycotylus._configuration.read(argument) or "")
        parser.exit()

class PresubmitCheckAction(argparse.Action):
    def __call__(self, parser, namespace, key, option_string=None):
        self = polycotylus.Project.from_root(".")
        parser.exit(self.presubmit())

parser = argparse.ArgumentParser(
    "polycotylus",
    description="Convert Python packages to Linux ones.",
    formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("distribution", choices=sorted(polycotylus.distributions))
parser.add_argument("--quiet", "-q", action="count", default=-2)
parser.add_argument("--completion", action=CompletionAction,
                    choices=sorted(CompletionAction.files))
parser.add_argument("--configure", nargs="*", action=ConfigureAction,
                    help="Manipulate global settings. This is an overloaded syntax:\n"
                    "  * List all settings:  polycotylus --configure\n"
                    "  * Read a setting:     polycotylus --configure docker\n"
                    "  * Write a setting:    polycotylus --configure docker=podman\n"
                    "  * Clear a setting:    polycotylus --configure docker=")
parser.add_argument("--list-localizations", action=ListLocalizationAction,
                    choices=["language", "region", "modifier"])
parser.add_argument("--architecture")
parser.add_argument("--gpg-signing-id")
parser.add_argument("--void-signing-certificate")
parser.add_argument("--post-mortem", action="store_true",
                    help="Enter an in-container interactive shell whenever an "
                    "error occurs in a docker container")
parser.add_argument("--presubmit-check", action=PresubmitCheckAction, nargs=0,
                    help="Run checks specific to submitting a package to official repositories")

def cli(argv=None):
    try:
        assert isinstance(argv, list) or argv is None
        options = parser.parse_args(argv)
        os.environ["POLYCOTYLUS_VERBOSITY"] = str(max(-options.quiet, 0))
        polycotylus._docker.post_mortem = options.post_mortem

        cls = polycotylus.distributions[options.distribution]
        signing_id = None
        if issubclass(cls, polycotylus._base.GPGBased):
            signing_id = options.gpg_signing_id
        elif issubclass(cls, polycotylus.Void):  # pragma: no branch
            signing_id = options.void_signing_certificate
        self = cls(polycotylus.Project.from_root("."), options.architecture,
                   signing_id)
        self.generate()
        artifacts = self.build()
        self.test(artifacts["main"])
        self.update_artifacts_json(artifacts)
    except polycotylus.PolycotylusUsageError as ex:
        raise SystemExit("Error: " + str(ex))
    print(f"Built {len({i.path for i in artifacts.values()})} artifact{'s' if len(artifacts) != 1 else ''}:")
    for (variant, package) in artifacts.items():
        print(f"{variant}: {package.path}")
    return artifacts

def _console_script():  # pragma: no cover
    cli()

if __name__ == "__main__":
    cli()


""" Greet tests on the CLI """
from click.testing import CliRunner

from example.greet import greet

def test_greet_cli():
    """Case with only time zone"""
    runner = CliRunner()
    result = runner.invoke(greet, ["Europe/Istanbul"])
    assert result.exit_code == 0
    assert "Hello, Istanbul!" in result.output


from os import path, getcwd, environ

from ..runners import EnvironmentContext
from ..aws import DEFAULT_REGION

def env():
    environment=environ.copy()  # Inherits cicdctl's environment by default

    # Set default aws region
    environment['AWS_DEFAULT_REGION'] = DEFAULT_REGION

    _PS1='\\u:\\w\\$ '  # Default prompt string
    with open(path.join(getcwd(), 'tool-vars.mk'), 'r') as f:
        for line in f:
            if line.startswith('_PS1='):
                # Strip assingment, quotes, make dollar escapes
                _PS1=line.replace("_PS1=", '').rstrip().replace("'", '').replace("$$", '$')
                break

    environment['PS1'] = _PS1

    logged_keys = ['AWS_DEFAULT_REGION']
    return EnvironmentContext(environment, logged_keys)


import asyncio
import shlex
import sys
import yaml

@asyncio.coroutine
def build(versions_file, *, loop):

    with open(versions_file) as f:
        config = yaml.load(f.read())

    procs = []

    for version_map in config['versions']:
        args = shlex.split('make docker-build '
                           'IMAGE_NAME={image_name} '
                           'KAFKA_VERSION={kafka} '
                           'SCALA_VERSION={scala}'.format(
                                image_name=config['image_name'],
                                **version_map))
        proc = yield from asyncio.create_subprocess_exec(*args, loop=loop)
        procs.append(proc.wait())

    return (yield from asyncio.gather(*procs, loop=loop))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    statuses = loop.run_until_complete(build('config.yml', loop=loop))
    loop.close()
    sys.exit(max(statuses))


from Products.statusmessages.interfaces import IStatusMessage
from zope import component
from zope import event

from collective.rcse.action import ajax
from collective.rcse.content.group import GroupSchema
from collective.rcse.content.proxygroup import ProxyGroupSchema
from collective.rcse.event import UserRolesModifiedOnObjectEvent
from collective.rcse.i18n import _

class Join(ajax.AjaxAction):
    """Request Writer local role access using collective.request.access
    or if the current group is open, just give him the role"""
    kind = GroupSchema

    def get_group(self):
        return self.context

    def action(self):
        #precondition
        if not self.kind.providedBy(self.context):
            raise ValueError("can t join something that is not a group")
        group = self.get_group()
        portal_state = component.getMultiAdapter(
            (self.context, self.request),
            name=u'plone_portal_state'
        )
        member = portal_state.member()
        if member is None:
            raise ValueError("you must be authenticated")

        group_state = component.getMultiAdapter(
            (group, self.request),
            name=u'plone_context_state'
        )
        state = group_state.workflow_state()
        role = "Contributor"
        if state == "open":
            #just add the localrole
            group.manage_setLocalRoles(member.getId(), [role])
            group.reindexObject()
            event.notify(UserRolesModifiedOnObjectEvent(member.getUserName(),
                                                        group))
            msg = _(u"You have joined this group")
        elif state == "moderated" or state == "private":
            #You are supposed to already have view context to be here
            manager = group.restrictedTraverse("@@request_manager")
            request = manager.create()
            request.role = role
            manager.add(request)
            msg = _(u"You have request access to this group. "
                    u"Please wait for an administrator to validate it")

        self.request.response.redirect(self.context.absolute_url())
        status = IStatusMessage(self.request)
        status.add(msg)

class Quit(ajax.AjaxAction):
    """Quit this group"""
    kind = GroupSchema

    def get_group(self):
        return self.context

    def action(self):
        if not self.kind.providedBy(self.context):
            raise ValueError("can t join something that is not a group")
        group = self.get_group()
        portal_state = component.getMultiAdapter(
            (self.context, self.request),
            name=u'plone_portal_state'
        )
        member = portal_state.member()
        if member is None:
            raise ValueError("you must be authenticated")
        group.manage_delLocalRoles([member.getId()])
        group.reindexObject()
        event.notify(UserRolesModifiedOnObjectEvent(member.getUserName(),
                                                    group))
        msg = _(u"You have quit this group")
        url = group.aq_parent.absolute_url()
        self.request.response.redirect(url)
        status = IStatusMessage(self.request)
        status.add(msg)

class ProxyJoin(Join):
    kind = ProxyGroupSchema

    def get_group(self):
        return self.context

class ProxyQuit(Quit):
    kind = ProxyGroupSchema

    def get_group(self):
        return self.context


import random
import os
#Constants
DIMENSION = 10
SHIP_SIZE = 4

#initializing board
board = []

#variables to count number of guesses and number of hits
guesses = 0
hits = 0

#creating the board
for r in range(DIMENSION):
		row_list= []
		for c in range(DIMENSION):
			row_list.append(" ")

		board.append(row_list)

#RANDOMLY PLACING SHIP
#generating random initial location of ship
valid = False
while valid == False:
	initial_location_row = random.randint(0,DIMENSION - 1)
	initial_location_column = chr(random.randint(65, (64 + DIMENSION)))
	asciicode = ord(initial_location_column)
	#generating random orientation of ship
	ship_row = []
	ship_orientation = random.randint(0,1)
	orientation = ["v", "h"]
	if orientation[ship_orientation] == "v":
		ship_column = [initial_location_column]
		if initial_location_row <DIMENSION - SHIP_SIZE + 1:
			#ship can fits facing down.
			show_row = [initial_location_row]
			for i in range(SHIP_SIZE):
				ship_row.append(initial_location_row + i)
			valid = True

	else:
		ship_row = [initial_location_row]
		if initial_location_column < chr(64 + DIMENSION - SHIP_SIZE):
			#ship can fit going right
			ship_column = [initial_location_column]
			for z in range(SHIP_SIZE):
				ship_column.append(chr(asciicode+z))
			valid = True

#DETECTING END OF GAME. Keep running game until hits are 4 and the grid is printed.
while hits <SHIP_SIZE + 1:

	#Printing name of game
	os.system("clear")
	print("B", "A", "T", "T","L","E","S","H","I","P", sep = "     ")
	print("\n" * 2)
	#printing current score
	print("             guesses", guesses , "        hits:", hits)
	print("\n")

	#printing the board.
	for cols in range(65, 65 + DIMENSION):
		print('   ' + chr(cols), end="")
	print("\n +" + "---+" * DIMENSION)

	for row in range(DIMENSION):
		print(str(row) + "|", end = "  ")
		for col in range(DIMENSION):
			print(board[row][col] + "|", end = "  ")
		print("\n +" + "---+" * DIMENSION)

	#asking user for input and checking it. Keeps asking user until correct input is given or until end of game.
	while hits<SHIP_SIZE:
		coordinate = input("Enter a coordinate. Cooridnate must be a CAPITAL letter between A and J followed by a number between 0 and 9: ")
		coordinate_list = list(coordinate)

		#CHECKING FOR INVALID INPUT
		#checking if two items are input
		if len(coordinate_list) ==2:
			#checking if first item is alphabet fitting inside column.
			if coordinate_list[0].isalpha() and chr(65)<=coordinate_list[0]<=chr(64 + DIMENSION):
				#checking if second item is a number fitting inside rows.
				if coordinate_list[1].isdigit() and -1<int(coordinate_list[1])<DIMENSION:
					alphabet = coordinate_list[0]
					number = int(coordinate_list[1])

					#checking if coordinate has already been guessed
					if board[number][ord(alphabet) - 65] == " ":
						guesses += 1
						break
						#end loop because input is correct

		#Printing error values for each type of possible error.
					else:
						print("You have already guessed this coordinate. Try again.\n")
				else:
					print("A letter must be followed by a number between 0 and " + str(DIMENSION - 1) +". Try again.\n")
			else:
				print("Input must be a CAPITAL letter between A and " + chr(64+DIMENSION) + " followed by a number. Try again.\n")
		else:
			print("Incorrect input. Your coordinate should consist of two things. Try again.\n")

	#UPDATING BOARD CELLS.
	if alphabet in ship_column and number in ship_row:
		hits = hits + 1
		#writing X if hit
		board[number][ord(alphabet) - 65] = "X"
	else:
		#writing # if miss
		board[number][ord(alphabet) - 65] = "#"

print("\n" * 2)
#printing the final score to user.
print("Game over. You guessed :", guesses, "times.")


# Code adapté de :
# https://github.com/itechnofrance/micropython/blob/master/librairies/paj7620/use_paj7620.py
# Utilisation de librairie du capteur de gestes PAJ7620
from machine import Pin, SoftI2C
import time
import paj7620

#brochage I2C0
i2c = SoftI2C(scl=Pin(5), sda=Pin(4), freq=400000)

#instanciation capoteur de gestee
g= paj7620.PAJ7620(i2c)

# Liste des gestes
gestures = [ "Aucun geste", "Avant", "Arrière", "Droite", "Gauche", "Haut", "Bas", "Sens horaire", "Sens anti-horaire", "Vague"]

while True:
    # Lecture du geste
    geste = g.gesture()  #geste = numéro  du geste

    # Extrait le geste de la liste pour affichage dans shell
    if geste > 0 and geste < 10:
        print(gestures[geste])

    # Temporisation de 10 millisecondes
    time.sleep(0.1)


from tkinter import *

def printtext():
        string = entry.get()
        st='you have '+string
        searchbutton.place_forget()
        lable.place_forget()
        lable2.place_forget()
        entry.place_forget()
        scrollbar = Scrollbar(main_window)
        scrollbar.pack(side=RIGHT, fill=Y)
       # mylist = Listbox(root, yscrollcommand = scrollbar.set )
       # for line in range(100):
        #   mylist.insert(END, w.cget("text") + str(line))

        area = Text(main_window, yscrollcommand = scrollbar.set, font = ('Courier New', 11))
        area.pack(expand=True, fill='both')

        scrollbar.config(command=area.yview)

        l3=Label(area,text=st,font='times 50')
        for line in range(1000):
           area.insert(END, l3.cget("text") + str(line))

        l3.place(x=50,y=250)

main_window=Tk()
main_window.geometry('1100x650+50+100')
main_window.title('D-Checker')

entry=Entry(main_window,bd=2,relief='raised', width=60)
entry.place(x=340,y=250)
lable=Label(main_window,text='This is a medical search engine.',font='times 30')
lable.place(x=320,y=300)
lable2=Label(main_window,text='D-Checker',fg='green',font='times 110')
lable2.place(x=280,y=80)

searchbutton=Button(main_window,text='search',width=12,height=1,bd=3,relief='raised',command=printtext)
searchbutton.place(x=760,y=246)

main_window.mainloop()


'''
Author: Vegard Gjeldvik Jervell
Purpose: Wrapper for the PseudoHardSphere class.
'''

from pykingas import cpp_PseudoHardSphere, KineticGas
import numpy as np

def HS_pressure(rho, T, x, sigma, chi):
    p = rho * kB * T
    for i in range(len(x)):
        for j in range(len(x)):
            p += 2 * pi * rho**2 * x[i] * x[j] * kB * T * sigma[i][j]**3 * chi[i][j]
    return p

def Z_func(rho, x, sigma):
    n = rho * x
    Z = np.array([sum(n * np.diag(sigma)**i) for i in range(1, 5)]) * pi / 6
    Z[-1] = 1 - Z[-2]
    return Z

def mu_func(rho, T, x, sigma, chi):
    Z1, Z2, Z3, Z = Z_func(rho, x, sigma)
    n = rho * x
    p = HS_pressure(rho, T, x, sigma, chi)

    if Z3 >= (1 - 1e-6):
        return np.full_like(x, np.nan)
    mu = np.empty_like(x)
    for i in range(len(x)):
        mu[i] = kB * T * (np.log(n[i]) - np.log(1 - Z3)
                            + (pi * sigma[i][i]**3 * p / (6 * kB * T)) \
                            + (3 * (Z2 * sigma[i][i] + Z1 * sigma[i][i]**2) / Z)
                            + ((9 / 2) * (Z2 * sigma[i][i] / Z)**2) \
                            + 3 * (Z2 * sigma[i][i] / Z3)**2 * (np.log(Z) + (Z3 / Z) - (Z3**2 / (2 * Z**2))) \
                            - (Z2 * sigma[i][i] / Z3)**3 * (2 * np.log(Z) + Z3 * (2 - Z3) / Z))
    return mu

class PseudoHardSphere(KineticGas):

    def __init__(self, comps, mole_weights=None, sigma=None, N=3, is_idealgas=False,
                    parameter_ref='default'):

        super().__init__(comps, mole_weights=mole_weights, N=N, is_idealgas=is_idealgas)
        self.fluids = [self.fluids[i]['HardSphere'][parameter_ref] for i in range(self.ncomps)]
        if sigma == None:
            sigma = np.array([self.fluids[i]['sigma'] for i in range(self.ncomps)])
        else:
            sigma = np.array(sigma)

        self.sigma_ij =  0.5 * (np.vstack((sigma, sigma)) + np.vstack((sigma, sigma)).transpose())
        self.cpp_kingas = cpp_PseudoHardSphere(self.mole_weights, self.sigma_ij, is_idealgas)

    def get_Eij(self, Vm, T, x):
        x = np.array(x)
        rho = Avogadro / Vm
        n = rho * x

        E = np.empty((self.ncomps, self.ncomps))
        for j in range(self.ncomps):
            dn = np.zeros(self.ncomps)
            dn[j] = 1e-2 * n[j]
            drho = dn[j]
            x_1 = (n - dn / 2) / sum(n - dn / 2)
            x1 = (n + dn / 2) / sum(n + dn / 2)
            chi_1 = self.cpp_kingas.get_rdf(rho - drho / 2, T, x_1)
            chi1 = self.cpp_kingas.get_rdf(rho + drho / 2, T, x1)
            mu_1 = mu_func(rho - drho / 2, T, x_1, self.sigma, chi_1)
            mu1 = mu_func(rho + drho / 2, T, x1, self.sigma, chi1)

            for i in range(self.ncomps):
                E[i][j] = (n[i] / (kB * T)) * (mu1[i] - mu_1[i]) / dn[j]

        return E