#!/usr/bin/env python2
import argparse
from motorctrl.MotorHatService import MotorHatService

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Run socket server for listening to moter hat events')
    parser.add_argument("--host", type=str, help="host name or ip to listen to, default is localhost")
    parser.add_argument("--port", type=int, help="port to listen to, default is 5005")
    parser.add_argument("--timeout", type=int, help="client connection timeout, default is 1 second")
    args = parser.parse_args()
    host = args.host
    if not host:
        host = "0.0.0.0"
    port = args.port
    if not port:
        port = 5005
    timeout = args.timeout
    if not timeout:
        timeout = 1
    server = MotorHatService(host, port, timeout)
    server.run()


from typing import List, Union
from project.vehicles.cargo_van import CargoVan
from project.vehicles.passenger_car import PassengerCar
from project.user import User
from project.route import Route

class ManagingApp:

    VALID_CAR_TYPES = {'PassengerCar': PassengerCar,
                       'CargoVan': CargoVan}

    def __init__(self):
        self.users: List[User] = []
        self.vehicles: List[Union[CargoVan, PassengerCar]] = []
        self.routes: List[Route] = []

    def register_user(self, first_name: str, last_name: str, driving_license_number: str):
        user = self._get_user_by_driving_license_number(driving_license_number)
        if user:
            return f'{driving_license_number} has already been registered to our platform.'
        reg_user = User(first_name, last_name, driving_license_number)
        self.users.append(reg_user)
        return f'{first_name} {last_name} was successfully registered under DLN-{driving_license_number}'

    def upload_vehicle(self, vehicle_type: str, brand: str, model: str, license_plate_number: str):
        if vehicle_type not in self.VALID_CAR_TYPES:
            return f'Vehicle type {vehicle_type} is inaccessible.'
        vehicle = self._get_vehicle_by_register_plate_number(license_plate_number)
        if vehicle:
            return f'{license_plate_number} belongs to another vehicle.'
        vehicle_to_reg = self.VALID_CAR_TYPES[vehicle_type](brand, model, license_plate_number)
        self.vehicles.append(vehicle_to_reg)
        return f'{brand} {model} was successfully uploaded with LPN-{license_plate_number}.'

    def allow_route(self, start_point: str, end_point: str, length: float):
        route_to_find = self._check_if_route_exists(start_point, end_point)
        if route_to_find:
            if route_to_find.length == length:
                return f'{start_point}/{end_point} - {length} km had already been added to our platform.'
            if route_to_find.length < length:
                return f'{start_point}/{end_point} shorter route had already been added to our platform.'
            if route_to_find.length > length:
                route_to_find.is_locked = True
        route_to_reg = Route(start_point, end_point, length, len(self.routes) + 1)
        self.routes.append(route_to_reg)
        return f'{start_point}/{end_point} - {length} km is unlocked and available to use.'

    def make_trip(self, driving_license_number: str, license_plate_number: str, route_id: int,  is_accident_happened: bool):
        user = self._get_user_by_driving_license_number(driving_license_number)
        if user.is_blocked:
            return f'User {driving_license_number} is blocked in the platform! This trip is not allowed.'

        vehicle = self._get_vehicle_by_register_plate_number(license_plate_number)
        if vehicle.is_damaged:
            return f'Vehicle {license_plate_number} is damaged! This trip is not allowed.'

        route = self._get_route_by_id(route_id)
        if route.is_locked:
            return f'Route {route_id} is locked! This trip is not allowed.'

        vehicle.drive(route.length)
        if is_accident_happened:
            vehicle.change_status()
            user.decrease_rating()
        else:
            user.increase_rating()
        return str(vehicle)

    def repair_vehicles(self, count: int):
        all_damaged_vehicles = [v for v in self.vehicles if v.is_damaged]
        sorted_vehicles = sorted(all_damaged_vehicles, key=lambda x: (x.brand, x.model))
        for vehicle in sorted_vehicles[:count]:
            vehicle.recharge()
            vehicle.change_status()
        return f'{len(sorted_vehicles[:count])} vehicles were successfully repaired!'

    def users_report(self):
        result = ['*** E-Drive-Rent ***']
        sorted_users = sorted(self.users, key=lambda x: -x.rating)
        for u in sorted_users:
            result.append(str(u))
        return '\n'.join(result)

    def _get_user_by_driving_license_number(self, driving_license_number):
        searched_user = next((u for u in self.users if u.driving_license_number == driving_license_number), None)
        return searched_user

    def _get_vehicle_by_register_plate_number(self, license_plate_number):
        searched_vehicle = next((v for v in self.vehicles if v.license_plate_number == license_plate_number), None)
        return searched_vehicle

    def _check_if_route_exists(self, start_point, end_point):
        is_route = next((r for r in self.routes if r.start_point == start_point and
                         r.end_point == end_point), None)
        return is_route

    def _get_route_by_id(self, route_id):
        route = next((r for r in self.routes if r.route_id == route_id), None)
        return route


class MedianFinder:

    def __init__(self):
        self.maxHeap = []
        self.minHeap = []

    def addNum(self, num: int) -> None:
        minHeap = self.minHeap
        maxHeap = self.maxHeap
        heappush(maxHeap, -num)
        if minHeap and maxHeap and -maxHeap[0] > minHeap[0]:
            val = -heappop(maxHeap)
            heappush(minHeap, val)

        if len(maxHeap) > len(minHeap) + 1:
            val = -heappop(maxHeap)
            heappush(minHeap, val)
        elif len(minHeap) > len(maxHeap) + 1:
            val = heappop(minHeap)
            heappush(maxHeap, -val)
        # print(maxHeap, minHeap)

    def findMedian(self) -> float:
        minHeap = self.minHeap
        maxHeap = self.maxHeap
        if len(maxHeap) > len(minHeap):
            return -maxHeap[0]
        if len(minHeap) > len(maxHeap):
            return minHeap[0]

        return (minHeap[0]-maxHeap[0])/2

# Your MedianFinder object will be instantiated and called as such:
# obj = MedianFinder()
# obj.addNum(num)
# param_2 = obj.findMedian()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Libvirt exporter
================

Libvirt node export for OpenStack deployments.

Exporter relies on specific OS metadata.

Dependency on packages:
* python3-libvirt

======= =========
Stats   Reference
======= =========
CPU:    :py:func:`node_exporters.libvirt.libvirt_only.get_cpu_stats`
Traffic :py:func:`node_exporters.libvirt.libvirt_only.get_net_stats`
Disk    :py:func:`node_exporters.libvirt.libvirt_only.get_disk_io_stats`
Memory  :py:func:`node_exporters.libvirt.libvirt_only.get_mem_stats`
======= =========

.. list-table:: Time Units
   :widths: 25 75
   :header-rows: 1

   * - Code
     - Unit
   * - time
     - seconds
   * - mtime
     - milliseconds
   * - utime
     - microseconds (export)
   * - ntime
     - nanoseconds (cgroup stats)

"""
import argparse
import sys

from prometheus_client import start_http_server
from prometheus_client.core import REGISTRY
from prometheus_client.core import GaugeMetricFamily

try:
    from libvirtmetadata import LibvirtMetadata
except Exception:
    libvirtmetadata = None
try:
    from scheduler import Scheduler
except Exception:
    scheduler = None

class CustomCollector(object):
    def __init__(self, helper, helper_name='unknown', libv_meta=None):
        self.ALL_STATS = []
        self.HELPER = helper
        self.HELPER_NAME = helper_name
        self.libv_meta = libv_meta

    def collect(self):
        items = {}

        for stat in self.ALL_STATS:
            if stat[0] not in items:
                items[stat[0]] = []
            items[stat[0]].append(stat[1:])

        for key, values in items.items():
            labels = values[0][0]
            g = GaugeMetricFamily(key, self.HELPER, labels=labels)
            for labels, metadata, value in values:
                g.add_metric(metadata, value)
            yield g

        try:
            if self.libv_meta:
                g = GaugeMetricFamily(
                    'libvirt_connection_status',
                    'Libvirt status none (-1), connected (0), or error (1)',
                    labels=['node_exporter']
                )
                g.add_metric([self.HELPER_NAME], self.libv_meta.status)
                yield g
        except Exception:
            pass

def get_cpu_stats(stats):
    """
    Get cpu stats.

    .. list-table:: CPU stats
       :widths: 25 75
       :header-rows: 1

       * - Measure
         - Description
       * - User time (cpu_user_utime)
         - Amount of time the processor worked on the specific program
       * - System time (cpu_system_utime)
         - Amount of time the processor worked on OS functions connected to that specific program
       * - Total cpu time (cpu_total_utime)
         - Provided by OS (surprisingly it is not just a sum of user and system)
       * - VCPU time (vcpu_utime)
         - CPU time measured for each vcpu separately as one metric only, but can
           provide info about balancing inside (whether they actually use all their VCPUs)
       * - VCPU max count (vcpu_max_count)
         - How many VCPUs can be used by VM (quota)
       * - VCPU use count (vcpu_use_count)
         - How many VCPUs are currently used by VM (allocated)

    Limitations:
      * Domain total cpu data require cgroup CPUACCT controller to be mounted,
        in case of issues with measurement this has to be checked.

    :param dict stats: statistics data retrieved from libvirt.

    :return dict: stats
    """
    recount_cpu_time = False
    items = {
        'cpu_total_utime': int(stats.get('cpu.time', 0) / 1000),  # CPUACCT
        'cpu_user_utime': int(stats.get('cpu.user', 0) / 1000),  # CPUACCT
        'cpu_system_utime': int(stats.get('cpu.system', 0) / 1000),  # CPUACCT
        'cpu_max_count': stats.get('vcpu.maximum', 0),
        'cpu_use_count': 0,
        'variable': {},
    }

    if items['cpu_total_utime'] == 0:
        # If cgroup fails - missing measures in total
        recount_cpu_time = True

    for i in range(items.get('cpu_max_count')):
        if recount_cpu_time:
            items['cpu_total_utime'] += int(
                stats.get('vcpu.{}.time'.format(i), 0) / 1000)
        vcpu_state = stats.get('vcpu.{}.state'.format(i), 0)
        items['cpu_use_count'] += 1 if vcpu_state == 1 else 0
        items['variable']['vcpu:{}'.format(i)] = {
            'vcpu_utime': int(stats.get('vcpu.{}.time'.format(i), 0) / 1000),
        }
    return items

def get_net_stats(stats):
    """
    Get network traffic stats.

    Covers all interfaces - it is a sum of internal and external traffic - not just ingress/egress

    .. list-table:: Traffic stats
       :widths: 25 75
       :header-rows: 1

       * - Measure
         - Description
       * - TX count (net_tx_count)
         - Amount of processed transmissions
       * - RX count (net_rx_count)
         - Amount of processed receives
       * - TX bytes (net_tx_bytes)
         - Total transmitted volume in bytes
       * - RX bytes (net_rx_bytes)
         - Total received volume in bytes

    To measure ingress/egress we don't use data from compute nodes.

    TODO:
      * Could also get drop and error counts if wanted.

    :param dict stats: statistics data retrieved from libvirt.

    :return dict: stats
    """
    items = {
        'net_tx_count': 0,
        'net_rx_count': 0,
        'net_tx_bytes': 0,
        'net_rx_bytes': 0,
        'net_use_count': stats.get('net.count', 0),
    }

    for i in range(items.get('net_use_count')):
        items['net_tx_count'] += stats.get('net.{}.tx.pkts'.format(i), 0)
        items['net_rx_count'] += stats.get('net.{}.rx.pkts'.format(i), 0)
        items['net_tx_bytes'] += stats.get('net.{}.tx.bytes'.format(i), 0)
        items['net_rx_bytes'] += stats.get('net.{}.rx.bytes'.format(i), 0)
    return items

def get_disk_io_stats(stats):
    """
    Get disk IO stats.

    IO stats are available both as total and per device.

    .. list-table:: IO stats
       :widths: 25 75
       :header-rows: 1

       * - Measure
         - Description
       * - Read count (disk_read_count)
         - The number of read input/output operations generated by a process,
           including file, network, and device I/Os. I/O Reads directed to CONSOLE
           (console input object) handles are not counted.
       * - Write count (disk_write_count)
         - The number of write input/output operations generated by a process,
           including file, network, and device I/Os. I/O Writes directed to
           CONSOLE (console input object) handles are not counted.
       * - Read bytes (disk_read_bytes)
         - The number of bytes read in input/output operations generated by
           a process, including file, network, and device I/Os. I/O Read Bytes
           directed to CONSOLE (console input object) handles are not counted.
       * - Write bytes (disk_write_bytes)
         - The number of bytes written in input/output operations generated by
           a process, including file, network, and device I/Os. I/O Write Bytes
           directed to CONSOLE (console input object) handles are not counted.
       * - Disk use count (disk_use_count)
         - Amount of used devices.

    Limitations:
      * CPU read/write (IO) provide different information than storage (e.g. ceph) stats would show,
        because for cpu IO operations are not just disk operations (includes file, network, and device I/Os).
      * https://superuser.com/questions/993966/what-does-i-o-reads-or-writes-and-i-o-read-bytes-or-write-bytes-mean

    TODO:
      * Could also get flush reqs count and times

    :param dict stats: statistics data retrieved from libvirt.

    :return dict: stats
    """
    items = {
        'disk_write_bytes': 0,
        'disk_read_bytes': 0,
        'disk_write_count': 0,
        'disk_read_count': 0,
        'disk_use_count': stats.get('block.count', 0),
        'variable': {},
    }

    for i in range(items.get('disk_use_count', 0)):
        items['disk_write_bytes'] += stats.get(
            'block.{}.wr.bytes'.format(i), 0)
        items['disk_read_bytes'] += stats.get('block.{}.rd.bytes'.format(i), 0)
        items['disk_write_count'] += stats.get(
            'block.{}.wr.times'.format(i), 0)
        items['disk_read_count'] += stats.get('block.{}.rd.times'.format(i), 0)
        disk_name = stats.get('block.{}.name'.format(i), None)
        if disk_name:
            items['variable']['device:{}'.format(disk_name)] = {
                'dev_total_bytes': stats.get('block.{}.physical'.format(i), 0),
                'dev_write_bytes': stats.get('block.{}.wr.bytes'.format(i), 0),
                'dev_read_bytes': stats.get('block.{}.rd.bytes'.format(i), 0),
                'dev_write_count': stats.get('block.{}.wr.times'.format(i), 0),
                'dev_read_count': stats.get('block.{}.rd.times'.format(i), 0),
            }
    return items

def get_mem_stats(domain, stats):
    """
    Get memory stats.

    .. list-table:: Memory stats
       :widths: 25 75
       :header-rows: 1

       * - Measure
         - Description
       * - Total (mem_max_bytes)
         - Amount of memory specified on domain creation of VM
       * - Used (mem_use_bytes)
         - Returns values close to total, because VM holds all the memory needed as
           appears from the outside and does not reflect internal state of OS here.
       * - Free (mem_free_bytes)
         - Amount of memory left unused by the system (opposite)
       * - Rss (mem_rss_bytes)
         - Resident Set Size of the process running the domain

    Limitations:
      * both used and free reflect the process, but not what is seen inside VM, so it may
        not be useful for user or billing. Will have to review with higher versions of
        Openstack when we move on.

    :param domain: libvirt domain object for extra stats.
    :param dict stats: statistics data retrieved from libvirt.

    :return dict: stats
    """
    items = {}
    try:
        mem = domain.memoryStats()
        items = {
            'mem_use_bytes': 1000 * mem.get('available', 0) if mem.get('available', 0) >= 0 else 0,
            'mem_rss_bytes': 1000 * mem.get('rss', 0) if mem.get('rss', 0) >= 0 else 0,
            'mem_free_bytes': 1000 * mem.get('unused', 0) if mem.get('unused', 0) >= 0 else 0,
            'mem_max_bytes': 1000 * mem.get('actual', 0) if mem.get('actual', 0) >= 0 else 0,
        }
    except Exception:
        items = {
            'mem_use_bytes': 1000 * stats.get('balloon.current', 0),
            'mem_max_bytes': 1000 * stats.get('balloon.maximum', 0),
        }
    return items

def prom_stats(libv_meta, cc):
    """Gather and export prometheus stats."""
    all_stats = []

    try:
        with libv_meta.libvirt_connection() as conn:
            # all_domain_stats = conn.getAllDomainStats(stats=libv_meta.STATS, flags=libv_meta.FLAGS)
            # for domain, stats in all_domain_stats:
            for dom in conn.listAllDomains(flags=libv_meta.LIST_DOMAINS_RUNNING):
                stat_list = []
                try:
                    state = int(dom.state()[0])
                except Exception:
                    state = 0
                try:
                    control_state = int(dom.controlInfo()[0])
                except Exception:
                    control_state = 4
                try:
                    control_time = int(dom.controlInfo()[-1] / 1000)
                except Exception:
                    control_time = -1
                try:
                    instance = dom.name()
                    metadata = libv_meta.get_instance_metadata(instance, dom)
                    try:
                        all_stats.extend(libv_meta.export({
                            'vm_control_time': control_time,
                            'vm_control_state': control_state,
                            'vm_state': state
                        }, instance, metadata=metadata))
                    except Exception:
                        pass
                    if state == libv_meta.DOMAIN_RUNNING and control_time < 300 and control_time >= 0:
                        # Ignore if domain not running or busy/locked for more than 5 min
                        stat_list = conn.domainListGetStats(
                            [dom], stats=libv_meta.STATS, flags=libv_meta.FLAGS)
                except Exception:
                    stat_list = []
                for domain, stats in stat_list:
                    try:
                        all_stats.extend(libv_meta.export(
                            get_cpu_stats(stats), instance, metadata=metadata))
                        all_stats.extend(libv_meta.export(
                            get_net_stats(stats), instance, metadata=metadata))
                        all_stats.extend(libv_meta.export(
                            get_disk_io_stats(stats), instance, metadata=metadata))
                        all_stats.extend(libv_meta.export(get_mem_stats(
                            domain, stats), instance, metadata=metadata))
                        all_stats.extend(libv_meta.export(libv_meta.get_cpu_meta(
                            domain), instance, metadata=metadata))
                    except Exception:
                        pass
                    try:
                        all_stats.extend(libv_meta.export(libv_meta.get_gpu_meta(
                            domain), instance, metadata=metadata, prefix='libv_'))
                    except Exception:
                        pass
            try:
                all_stats.extend(libv_meta.export(libv_meta.get_gpu_device_meta(), None, prefix='libv_'))
            except Exception as e:
                print(e)
    except Exception:
        libv_meta.status = 1  # error

    cc.ALL_STATS = all_stats

def shell(args):
    """Start iPython shell for direct management access."""
    from IPython import embed
    from datetime import datetime as dt  # noqa
    from datetime import timedelta as td  # noqa
    from datetime import time  # noqa
    import logging
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
    libv_meta = LibvirtMetadata()  # noqa
    embed(header="Welcome in iPython shell")

def main(args):
    scheduler = Scheduler()
    libv_meta = LibvirtMetadata()
    try:
        libv_meta.load_libvirt_metadata()
    except Exception:
        pass

    cc = CustomCollector('Libvirt instance stats',
                         helper_name='libvirt', libv_meta=libv_meta)
    REGISTRY.register(cc)
    start_http_server(args.port, addr=args.addr)
    scheduler.log(
        'Exposing metrics at: http://{}:{}/metrics'.format(args.addr, args.port))

    # Every 'wait_time' seconds
    scheduler.add_periodic_task(
        prom_stats, 'second', round=args.wait_time, args=(libv_meta, cc)
    )
    # Every 20 minutes
    scheduler.add_periodic_task(
        libv_meta.load_libvirt_metadata, 'minute', round=20)

    scheduler.run_concurrent(debug=args.debug)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Libvirt textfile exporter')
    parser.set_defaults(func=main)
    subparsers = parser.add_subparsers(
        dest='action', help='Choose an alternative action (optional)')

    parser.add_argument(
        '-p', '--port', dest='port', default=9121, type=int,
        help='Port to expose metrics'
    )
    parser.add_argument(
        '-i', '--ip', dest='addr', default='0.0.0.0',
        help='IP address to expose metrics'
    )
    parser.add_argument(
        '-t', '--wait-time', dest='wait_time', default=2, type=int,
        help='Time to sleep between measures [2-30]'
    )
    parser.add_argument('--debug', dest='debug',
                        action='store_true', help='Debug messages')
    subparsers.add_parser(
        'shell', help='Run iPython shell').set_defaults(func=shell)

    args = parser.parse_args()
    args.func(args)


import pickle
import uuid
import time
import os
import tempfile
import urllib2
import math
from Bio import Entrez, SeqIO
from talconfig import BASE_DIR, REDIS_SERVER_HOSTNAME, REDIS_SERVER_PORT
from talutil import TaskError

redis_found = True
try:
    import redis
except ImportError:
    redis_found = False

Entrez.email = "6e6a62393840636f726e656c6c2e656475".decode("hex")
Entrez.tool = "https://tale-nt.cac.cornell.edu"

def _ncbi_search_assemblies(cached_file, logger, assembly_id):

    ehandle = Entrez.esearch(db="assembly", term=assembly_id)
    erecord = Entrez.read(ehandle)
    ehandle.close()

    if int(erecord["Count"]) != 0:

        canonical_assembly_ids = [x for x in erecord["IdList"] if x != "-1"]

        if len(canonical_assembly_ids) > 0:

            cached_file.assembly_id = canonical_assembly_ids[0]

            if len(canonical_assembly_ids) > 1:
                logger("Warning: NCBI search for assembly ID returned more than 1 record, chose the first")

def _ncbi_links_for_id(cached_file, logger, db, dbfrom, linkname, assembly_id):

    ehandle = Entrez.elink(db=db, dbfrom=dbfrom, id=assembly_id, linkname=linkname)
    erecord = Entrez.read(ehandle)
    ehandle.close()

    if len(erecord[0]["LinkSetDb"]) != 0:
        cached_file.nuc_seq_ids = [link["Id"] for link in erecord[0]["LinkSetDb"][0]["Link"]]

def _ncbi_search_nuccore(cached_file, logger, db, term):

    ehandle = Entrez.esearch(db="nucleotide", term=term)
    erecord = Entrez.read(ehandle)
    ehandle.close()

    if int(erecord["Count"]) != 0:

        cached_file.assembly_id = "nucleotide_" + erecord["IdList"][0]
        cached_file.nuc_seq_ids = [erecord["IdList"][0]]

        if int(erecord["Count"]) > 1:
            logger("Warning: NCBI search for nucleotide sequence ID returned more than 1 record, chose the first")

# redis locking
# http://www.dr-josiah.com/2012/01/creating-lock-with-redis.html

class BaseCachedEntrezFile(object):

    def __init__(self, logger, assembly_id):

        self.assembly_id = None
        self.nuc_seq_ids = []

        try:

            _ncbi_search_assemblies(self, logger, assembly_id)

            if self.assembly_id is not None:

                logger("ID matched an NCBI assembly, checking for linked RefSeq sequences")

                _ncbi_links_for_id(self, logger, "nuccore", "assembly", "assembly_nuccore_refseq", self.assembly_id)

                if len(self.nuc_seq_ids) == 0:

                    logger("No RefSeq sequences available for NCBI assembly ID, checking for matching GenBank sequences.")

                    _ncbi_links_for_id(self, logger, "nuccore", "assembly", "assembly_nuccore_insdc", self.assembly_id)

                    if len(self.nuc_seq_ids) == 0:

                        logger("No GenBank sequences available for NCBI assembly ID, checking if ID matches nucleotide sequence")

                        raise TaskError("No linked RefSeq or GenBank sequences for found for the given assembly ID")

                logger("Sequences for assembly located, downloading now")

            else:

                logger("ID did not match an NCBI assembly, searching for nucleotide sequences")

                _ncbi_search_nuccore(self, logger, "nucleotide", assembly_id)

                if len(self.nuc_seq_ids) == 0:
                    raise TaskError("The given ID did not match any assemblies or nucleotide sequences")

                logger("Nucleotide sequence for ID located, downloading now")

        except (IOError, urllib2.HTTPError):
            raise TaskError("Invalid NCBI ID provided")

if redis_found:

    class CachedEntrezFile(BaseCachedEntrezFile):

        WRITE_LOCK_DURATION = 18000
        READ_LOCK_DURATION = 36000

        CACHED_FILE_DIR = BASE_DIR + "/cached_gb_files"
        CACHED_FILE_PATTERN = CACHED_FILE_DIR + "/%s.fasta"

        def __init__(self, logger, assembly_id):

            if assembly_id == "NA":
                return

            self.conn = redis.StrictRedis(host=REDIS_SERVER_HOSTNAME, port=REDIS_SERVER_PORT, db=1)

            super(CachedEntrezFile, self).__init__(logger, assembly_id)

            self.lock_name = "gb_cache:%s" % self.assembly_id
            self.uuid = str(uuid.uuid4())
            self.filepath = CachedEntrezFile.CACHED_FILE_PATTERN % self.assembly_id
            self.file = None

        def __enter__(self):

            pipe = self.conn.pipeline(True)

            while True:

                try:

                    pipe.watch(self.lock_name)

                    if not pipe.exists(self.lock_name):

                        print("No entry for key %s, creating" % self.lock_name)

                        timestamp = time.time()

                        pipe.multi()

                        pipe.hmset(self.lock_name, {
                            "last-accessed": timestamp,
                            "readers": pickle.dumps({}),
                            "writers": pickle.dumps({
                                self.uuid: timestamp + CachedEntrezFile.WRITE_LOCK_DURATION
                            })
                        })

                        pipe.execute()

                        print("Key %s created" % self.lock_name)
                        print("Downloading file for newly created key %s" % self.lock_name)

                        try:
                            os.remove(self.filepath)
                        except OSError:
                            pass

                        try:

                            with open(self.filepath, "w") as cached_file:

                                for i in range(int(math.ceil(float(len(self.nuc_seq_ids)) / 5000))):

                                    start = i * 5000
                                    remaining = len(self.nuc_seq_ids) - start
                                    end = start + remaining if remaining < 5000 else start + 5000

                                    print("start %d remaining %d end %d" % (start, remaining, end))

                                    fetch_handle = Entrez.efetch(db="nucleotide", id=self.nuc_seq_ids[start:end], rettype="fasta", retmode="text")

                                    for line in fetch_handle:
                                        cached_file.write(line)

                                    fetch_handle.close()

                        except IOError:
                            # I dunno
                            raise

                        finally:

                            print("File for key %s finished downloading, removing writer")

                            pipe.watch(self.lock_name)

                            lock_writers = pickle.loads(pipe.hget(self.lock_name, "writers"))

                            if self.uuid in lock_writers:
                                del lock_writers[self.uuid]

                            pipe.multi()
                            pipe.hset(self.lock_name, "writers", pickle.dumps(lock_writers))
                            pipe.execute()

                            print("Writer for key %s removed" % self.lock_name)

                    else:

                        print("Key %s exists, checking for writer" % self.lock_name)

                        timestamp = time.time()

                        lock_writers = pickle.loads(pipe.hget(self.lock_name, "writers"))

                        if len(lock_writers.keys()) > 0:

                            print("Writer for key %s exists, checking expiration" % self.lock_name)

                            writers_changed = False

                            for l_uuid, l_timestamp in lock_writers.copy().items():

                                print("Writer for key %s with UUID %s, timestamp %s, current time %s" % (self.lock_name, l_uuid, str(l_timestamp), str(timestamp)))

                                if l_uuid == self.uuid:

                                    print("Writer for key %s has our UUID, previous attempt to remove writer failed, retrying" % self.lock_name)
                                    del lock_writers[l_uuid]
                                    writers_changed = True

                                elif l_timestamp < timestamp:

                                    print("Writer for %s with UUID %s expired, removing" % (self.lock_name, l_uuid))
                                    del lock_writers[l_uuid]
                                    writers_changed = True

                            if writers_changed:

                                pipe.multi()
                                #pipe.hset(self.lock_name, "writers", pickle.dumps(lock_writers))
                                # since file will only be downloaded if key doesn't exist (because there's no way to check if local sequence
                                # file is corrupted), and there's only one writer at a time, removing the only writer means the local file
                                # is likely corrupted, so we remove the key so that redownload of file is attempted
                                pipe.delete(self.lock_name)
                                pipe.execute()

                                print("Expired writers for key %s removed" % self.lock_name)

                            time.sleep(5)

                        else:

                            print("No writers for key %s, adding reader" % self.lock_name)

                            timestamp = time.time()

                            lock_readers = pickle.loads(pipe.hget(self.lock_name, "readers"))

                            lock_readers[self.uuid] = timestamp

                            pipe.multi()
                            pipe.hset(self.lock_name, "last-accessed", timestamp)
                            pipe.hset(self.lock_name, "readers", pickle.dumps(lock_readers))
                            pipe.execute()

                            print("Reader for key %s acquired, returning file" % self.lock_name)

                            break

                except redis.exceptions.WatchError:
                    pass

            self.file = open(self.filepath, "r")

            return self

        def __exit__(self, exc_type, exc_value, traceback):

            if self.file is not None:
                self.file.close()

            print("Releasing reader for key %s" % self.lock_name)

            pipe = self.conn.pipeline(True)

            while True:

                try:

                    pipe.watch(self.lock_name)

                    if pipe.exists(self.lock_name):

                        lock_readers = pickle.loads(pipe.hget(self.lock_name, "readers"))

                        if self.uuid in lock_readers:
                            del lock_readers[self.uuid]

                        pipe.multi()
                        pipe.hset(self.lock_name, "readers", pickle.dumps(lock_readers))
                        pipe.execute()

                    else:

                        # read lock was broken by garbage collector

                        pipe.unwatch()

                    break

                except redis.exceptions.WatchError:
                    pass

            print("Reader for key %s released" % self.lock_name)

else:

    class CachedEntrezFile(BaseCachedEntrezFile):

        def __init__(self, logger, assembly_id):

            if assembly_id == "NA":
                return

            super(CachedEntrezFile, self).__init__(logger, assembly_id)

            self.file = None
            self.filepath = ""

        def __enter__(self):

            try:

                fetch_handle = Entrez.efetch(db="nucleotide", id=self.nuc_seq_ids, rettype="fasta", retmode="text")
                self.file = tempfile.NamedTemporaryFile()

                for i in range(int(math.ceil(float(len(self.nuc_seq_ids)) / 5000))):

                    start = i * 5000
                    remaining = len(self.nuc_seq_ids) - start
                    end = start + remaining if remaining < 5000 else start + 5000

                    fetch_handle = Entrez.efetch(db="nucleotide", id=self.nuc_seq_ids[start:end], rettype="fasta", retmode="text")

                    for line in fetch_handle:
                        self.file.write(line)

                    fetch_handle.close()

                self.file.seek(0)

            except IOError:
                raise TaskError("Could not download sequence from NCBI")

            self.filepath = self.file.name

            return self

        def __exit__(self, exc_type, exc_value, traceback):

            if self.file is not None:
                self.file.close()


import functools
from typing import Optional

from binary_tree_with_parent_prototype import BinaryTreeNode
from test_framework import generic_test
from test_framework.binary_tree_utils import must_find_node
from test_framework.test_failure import TestFailure
from test_framework.test_utils import enable_executor_hook

"""

Compute lowest common ancestor given nodes that have parent pointers

Without parents, can't go back up the tree.
Have to start at root, find both nodes, then compare the paths.

With parent, can go back up the tree.
Build ancestor paths to the root...O(log n) (O(n) if unbalanced)
Iterate through the path nodes to find last match...O(log n) (O(n) if unbalanced)
-> O(log n)

If both nodes are same distance from root, LCA is first corresponding node in path starting from each node.

Worst case is always going all the way to the root, which has to take O(log n) or O(n) unabalanced

"""

def path_to_root(node):
    p = []
    while node != None:
        p.append(node)
        node = node.parent
    return p

def lca(node0: BinaryTreeNode,
        node1: BinaryTreeNode) -> Optional[BinaryTreeNode]:
    p1 = path_to_root(node0)
    p2 = path_to_root(node1)

    # paths are from nodes to root, so traverse from ends
    i = -1
    while p1[i] == p2[i]:
        i -= 1
        if abs(i) > len(p1) or abs(i) > len(p2):
            break

    return p1[i+1]

@enable_executor_hook
def lca_wrapper(executor, tree, node0, node1):
    result = executor.run(
        functools.partial(lca, must_find_node(tree, node0),
                          must_find_node(tree, node1)))

    if result is None:
        raise TestFailure('Result can\'t be None')
    return result.data

if __name__ == '__main__':
    exit(
        generic_test.generic_test_main('lowest_common_ancestor_with_parent.py',
                                       'lowest_common_ancestor.tsv',
                                       lca_wrapper))


import pyautogui

import os
import time

from pynput import mouse

import pynput, time

# 鼠标右键坏了 将鼠标中间按键按下模拟鼠标右键
def on_move(x, y):
    print('Pointer moved to {0}'.format((x, y)))

def on_click(x, y, button, pressed):
    print(button)
    # Button.middle left right
    if button==pynput.mouse.Button.middle:
        pyautogui.rightClick()
        return True
    return True

def on_scroll(x, y, dx, dy):
    print('Scrolled {0} at {1}'.format(
        'down' if dy < 0 else 'up',
        (x, y)))

# Collect events until released
with pynput.mouse.Listener(
        # on_move=on_move,
        on_click=on_click,
        on_scroll=on_scroll) as listener:

    listener.join()

# pyautogui.rightClick()


class House:
    flat_count = 0
    room_count = 0

    def __str__(self):
        return 'house'

    def __init__(self, n):
        self.number = n[0]
        self.year = n[1]
        self._material = n[2]
        self._num_floor = n[3]
        self._price = n[4]
        House.flat_count += 1
        print(House.flat_count, self)

#house = [['house1', 2021, 'brick', 9, 100000], ['house2', 2015, 'wood', 3, 70000], ['house3', 2016, 'panel', 20, 50000]]
h = {'house1': [1, 2021, 'brick', 9, 100000], 'house2': [2, 2015, 'wood', 3, 70000], 'house3': [3, 2016, 'panel', 20, 50000]}
for key, val in h.items():
    globals()[key] = House(val)
a = House([3,2000,'shlack',2,30000])
print(house2._price)
print(House.__dict__)
print(house2.__dict__)
print(house1._price/a._num_floor)


# LeetCode problem 171. Excel Sheet Column Number (easy)
# Algorithm: Start with right hand digit moving left and add the value of the digit's place value in base 26

class Solution:
    def titleToNumber(self, s: str) -> int:
        place = result = 0
        for ch in s[::-1]:
            result = result + (ord(ch)-64) * 26**place
            place +=1
        return result

LeetCode/171. Excel Sheet Column Number.py


import streamlit as st
import pickle
import pandas as pd
import numpy as np

movies_list_ = pickle.load(open("pickle_obj/movie_list.pkl", "rb"))
model = pickle.load(open("pickle_obj/model.pkl", "rb"))
book_pivot = pickle.load(open("pickle_obj/book_pivot.pkl", "rb"))

def get_isbn(name):
    final_rating = pd.read_csv("data/final_data.csv")
    isbn = final_rating.loc[
        final_rating['title'] == name].iloc[
        0].ISBN
    return isbn

def fetch_cover(isbn):
    url = f"https://covers.openlibrary.org/b/isbn/{isbn}-L.jpg"
    return url

def get_recommendations(name, no_of_recommendations=5):
    num = np.where(book_pivot.index == name)[0]
    if len(num) == 0:
        print("No such book in list")
        return
    else:
        num = num[0]
    distances, suggestions = model.kneighbors(book_pivot.iloc[num, :].values.reshape(1, -1), n_neighbors=no_of_recommendations + 1)
    return list(book_pivot.iloc[suggestions[0][1:]].index)

def recommendations_posters(name):
    book_list = get_recommendations(name, 5)
    cover_list = []
    for book in book_list:
        isbn = get_isbn(book)
        url = fetch_cover(isbn)
        cover_list.append(url)
    return cover_list

st.set_page_config(
     page_title="Book-Recommender-System",
     page_icon="ðŸ“š",
     layout="wide",
     initial_sidebar_state="expanded"
 )

st.title("Book Recommender System")

option = st.selectbox(
    'Please Select a Book',
    movies_list_)

st.image(fetch_cover(get_isbn(option)))

if st.button("Recommend"):
    names, posters = get_recommendations(option, 5), recommendations_posters(option)
    col1, col2, col3, col4, col5 = st.columns(5)

    with col1:
        st.text(f'{names[0]}')
        st.image(f"{posters[0]}")

    with col2:
        st.text(f'{names[1]}')
        st.image(f"{posters[1]}")

    with col3:
        st.text(f'{names[2]}')
        st.image(f"{posters[2]}")

    with col4:
        st.text(f'{names[3]}')
        st.image(f"{posters[3]}")

    with col5:
        st.text(f'{names[4]}')
        st.image(f"{posters[4]}")

footer = """

Developed with â�¤ by Vishal Thakur

"""
st.markdown(footer, unsafe_allow_html=True)


import numpy as np
def Reader():
    y_max=0
    maze=[]
    with open('maze-for-u.txt') as a:
        for line in a:
            maze.append(line.strip('\n'))
        x_max=len(maze[0])
        y_max=len(maze)
    return x_max,y_max,maze
max_x,max_y,maze=Reader()
m=list(maze)
POSSIBLE_WAYS=('N', 'S', 'W', 'E')
coord_treasure = [0, 0]
def is_coord_in_maze(maze, coord):
    if coord[0]<0 or coord[0]>len(maze[0])-1:
        return False
    if coord[1]<0 or coord[1]>len(maze)-1:
        return False
    return True
def is_coord_exit(coord):
    if coord[1]>len(maze)-2:
        return True
    return False
def is_path_clean(maze, coord):
    if maze[coord[1]][coord[0]] == '#':
        return False
    return True
def step(coord, direction):
    if direction == 'N':
         return step_N(coord)
    elif direction == 'S':
         return step_S(coord)
    elif direction == 'E':
         return step_E(coord)
    elif direction == 'W':
         return step_W(coord)
def step_N(coord):
    return [coord[0], coord[1]-1]
def step_E(coord):
    return [coord[0]+1, coord[1]]
def step_S(coord):
    return [coord[0], coord[1]+1]
def step_W(coord):
    return [coord[0]-1, coord[1]]
def cut_way_back(direction):
    """
    Cut the opposite direction in possible ways to prevent stepping back
    """
    if direction == 'N':
        return ('N', 'E', 'W')
    if direction == 'S':
        return ('S', 'E', 'W')
    if direction == 'E':
        return ('N', 'E', 'S')
    if direction == 'W':
        return ('N', 'S', 'W')
def shift_the_symbol(m, coord, symbol):
    w= list(m[coord[1]])
    w[coord[0]] = symbol
    m[coord[1]] = ''.join(w)
def empty_symbol(maze, i):
    return [maze[i].find(" "), i]
def is_treasure(coord):
    global treasure_is_here
    if coord[1]==treasure_is_here[1] and\
        coord[0]==treasure_is_here[0]:
        return True
    return False
def start_path(m, coord, path_to_exit):
    for a in path_to_exit:
        shift_the_symbol(m,coord,'-')
        coord=step(coord,a)
def find_a_way(maze, coord, possible_ways):
    global path_to_exit, current_path
    if not is_coord_in_maze(maze, coord):
        return
    if is_coord_exit(coord):
        return
    if is_treasure(coord):
        path_to_exit = current_path.copy()
        return
    if len(current_path) > len(path_to_exit):
        return
    for direction in possible_ways:
        if is_path_clean(maze, step(coord, direction)):
            current_path.append(direction)
            find_a_way(maze, step(coord, direction), cut_way_back(direction))
            current_path.pop()
    return
def coordinates():
    p=False
    while p==False:
        coord_treasure[0] = int(input(f'Where is threasure? (x is between 1 and {max_x}) ')) - 1
        coord_treasure[1] = int(input(f'Where is threasure? (y is between 1 and {max_y}) ')) - 1
        if maze[coord_treasure[1]][coord_treasure[0]] == '#':
            print('Error! There can be no treasure here! There\'s a wall here!')
        else:
            treasure_is_here = (abs(coord_treasure[0]) if abs(coord_treasure[0]) < max_x-1 else max_x-1, abs(coord_treasure[1]) if abs(coord_treasure[1]) < max_y-1 else max_y-1)
            p=True
            return treasure_is_here
last=[[-1 for j in range(max_x)] for i in range(max_y)]
def exit(treasure_is_here,fin):
    it=list()
    it.append(treasure_is_here)
    last[treasure_is_here[1]][treasure_is_here[0]] = 0
    while it:
        one=it.pop(0)
        for a in [[-1, 0],[1, 0],[0, -1],[0, 1]]:
            x=one[0]+a[0]
            y=one[1]+a[1]
            if (x<0 or x>=max_x or y<0 or y>=max_y):
                continue
            if (maze[y][x] == " " and last[y][x] == -1):
                last[y][x] = [one[0],one[1]]
                it.append([x, y])
    x=fin[0]
    y=fin[1]
    while last[y][x] != 0:
        shift_the_symbol(m, [x, y], '+')
        x_n=last[y][x][0]
        y_n=last[y][x][1]
        x,y=x_n,y_n
path_to_exit = []
for i in range(len(maze)*len(maze[0])):
    path_to_exit.append(' ')
current_path = []
start_point = empty_symbol(maze, 0)
exit_point = empty_symbol(maze, max_y - 1)
treasure_is_here = []
treasure_is_here=coordinates()
shift_the_symbol(m, treasure_is_here, '*')
find_a_way(maze, start_point, POSSIBLE_WAYS)
start_path(m, start_point, path_to_exit)
exit(treasure_is_here, exit_point)
end= open('result.txt','w')
for i in range(len(maze)):
    end.write(m[i])
    end.write("\n")
end.close()
print('The way to the treasure',path_to_exit)
print("Open the file to see clearly!")


#!/usr/bin/env python3

from typing import Tuple
from dataclasses import dataclass
import numpy as np
import torch as th
import cv2
nn = th.nn
F = nn.functional
from functools import partial
from tqdm.auto import tqdm
from torchvision.transforms import (
    Compose, ToTensor, Normalize, Resize)

from model import SlotAttentionAE
from dataset import CLEVRDataset
from util import (get_new_dir, ensure_dir, load_ckpt, save_ckpt)
import einops

@dataclass
class Config:
    batch_size: int = 16
    img_size: Tuple[int, int] = (128, 128)
    num_slots: int = 8
    ckpt_path: str = '/tmp/slot-attention/run-009/last.pt'
    num_workers:int = 4

def main():
    cfg = Config()
    device: th.device = th.device('cuda')
    model = SlotAttentionAE(cfg.img_size, cfg.num_slots).to(device)
    load_ckpt(cfg.ckpt_path, model)

    transform = Compose([
        ToTensor(),
        Resize(cfg.img_size),
        Normalize(0.5, 0.5, True),
    ])
    val_dataset = CLEVRDataset(
        '/media/ssd/datasets/CLEVR/CLEVR_v1.0/', 'val',
        transform=transform)
    val_data_loader = th.utils.data.DataLoader(val_dataset,
                                               batch_size=cfg.batch_size,
                                               num_workers=cfg.num_workers,
                                               shuffle=False)
    model.eval()
    for images in tqdm(val_data_loader):
        images = images.to(device)
        with th.no_grad():
            pred_imgs, recs, msks, _ = model(images)
            msks = msks[...,None,:,:]
            slot_imgs = recs * msks + (1 - msks)  # BxSxCXHXW
            slot_vis = slot_imgs * 0.5 + 0.5
            vis = einops.rearrange(slot_vis,
                    'b s c h w -> (b h) (s w) c')
        vis_np = vis.detach().cpu().numpy()
        cv2.imwrite('/tmp/vis.png', (vis_np * 255).astype(np.uint8) )
        break

if __name__ == '__main__':
    main()


import pygame
import colors as col
import pickle
from Arena import *
from snake import *
import time
import argparse
from input import *

if __name__ == "__main__":
    # command line argument parser
    ap = argparse.ArgumentParser()
    ap.add_argument('-i', '--input', required=True, help='relative path of the saved pickle file')
    ap.add_argument('-s', '--start', type=int, help='relative start of the saved snakes')
    args = vars(ap.parse_args())
    # loading the saved snakes
    file = open(args['input'], 'rb')
    snakes = pickle.load(file)
    generation = 0
    if args['start'] is not None:
        start = args['start']
        snakes = snakes[start:]
        generation += start
    file.close()
    # pygame initialization
    pygame.init()
    pygame.font.init()
    myfont = pygame.font.SysFont('Bitstream Vera Serif', 20)
    screen = pygame.display.set_mode((width, height))
    pygame.display.set_caption('Generation : 0\t\tScore : 0')
    # seed generated so that each snake sees same set of foods for performance comparison
    seed = random.random()
    arena = Arena(width, height, block_length)

    for saved_snake in snakes:
        t_snake = snake(width, height, brainLayer, block_length,
                        random_weights=False, random_bases=False)
        t_snake.Brain.weights = saved_snake.Brain.weights
        t_snake.Brain.bases = saved_snake.Brain.bases
        random.seed(seed)
        t_snake.Brain.setNextFood(arena.newFood(t_snake.list))
        screen = arena.setup(screen, col.bg, col.gray)
        screen = arena.drawFood(screen, col.pink)
        screen = t_snake.draw(screen, col.blue)
        pygame.display.update()
        checkloop = False
        while t_snake.isAlive():
            # checking for key presses and close button presses and pause-continue funcionality
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
                    pressed = True
                    while pressed:
                        for event in pygame.event.get():
                            if event.type == pygame.KEYDOWN and event.key == pygame.K_c:
                                pressed = False
                if event.type == pygame.KEYDOWN and event.key == pygame.K_q:
                    t_snake.crash_wall = True
                    t_snake.crash_body = True
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
            # getting result from the neural network
            result = t_snake.Brain.decision_from_nn(
                t_snake.head_x, t_snake.head_y, t_snake.list, t_snake.direction)
            # moving the snake
            alive = t_snake.move(result)
            # checking for loops made by snake
            if t_snake.steps_taken > (len(t_snake.list)/5*100):
                if not checkloop:
                    checkloop = True
                    any_point = (t_snake.head_x, t_snake.head_y)
                    times = 0
                if (t_snake.head_x, t_snake.head_y) == any_point:
                    times += 1
                if times > 4:
                    t_snake.crash_wall = True
                    t_snake.crash_body = True
                    alive = False
            else:
                checkloop = False
            if not alive:
                text = 'Generation : ' + str(generation+1) + '\t\t' + \
                    'Score : ' + str(len(t_snake.list)-1)+'\t[Dead]'
                if t_snake.crash_wall and t_snake.crash_body:
                    print('killed,', 'generation : ', generation+1, 'score : ', len(t_snake.list)-1)
                elif t_snake.crash_wall and not t_snake.crash_body:
                    print('crashed on wall,', 'generation : ',
                          generation+1, 'score : ', len(t_snake.list)-1)
                else:
                    print('crashed on body,', 'generation : ',
                          generation+1, 'score : ', len(t_snake.list)-1)
                pygame.display.set_caption(text)
                time.sleep(2)
                break
            if (t_snake.head_x, t_snake.head_y) == arena.food:
                t_snake.steps_taken = 0
                next_position = t_snake.Brain.decision_from_nn(
                    t_snake.head_x, t_snake.head_y, t_snake.list, t_snake.direction)
                if not t_snake.increaseSize(next_position):
                    t_snake.crash_wall = True
                t_snake.Brain.setNextFood(arena.newFood(t_snake.list))
            screen = arena.setup(screen, col.bg, col.gray)
            screen = arena.drawFood(screen, col.pink)
            screen = t_snake.draw(screen, col.blue)
            pygame.display.update()
            text = 'Generation : ' + str(generation+1) + '\t\t' + \
                'Score : ' + str(len(t_snake.list)-1)+'\t[Press q to kill]'
            pygame.display.set_caption(text)
            pygame.display.update()
            time.sleep(0.03)
        generation += 1
    pygame.quit()
    quit()


import numpy as np
import os as os
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pickle as pickle
from matplotlib import gridspec
import matplotlib.colors as colors
from deepres.simulator.periodic_field_functions import PeriodicPerturbations
proj_folder = os.path.dirname(os.path.realpath(__file__))
# path to save the training data file
save_folder = os.path.join(proj_folder, 'temp')
save_path = os.path.join(save_folder, 'data.npz')
grid_path = os.path.join(proj_folder, 'sample_scripts', 'script_files', '100_100_periodic.pkl')

#data = np.load(save_path)
#X = data['X']
#Y = data['Y']
#datFile =np.load('train_pressure.npz')

datFile =np.load('best_pred_pressure.npz')

X = datFile['perm']
pressure_actual = datFile['pressure']
p_pred = datFile['best_pred']

print(p_pred.shape)
with open(grid_path, 'rb') as input:
    grid = pickle.load(input)
dx, dy = grid.dx, grid.dy
nx = grid.m
gridx = grid.pores.x
gridy = grid.pores.y
x_mat = np.reshape(gridx, (nx,nx), order='F')
y_mat = np.reshape(gridy, (nx,nx), order='F')
# plot permeability

PI = PeriodicPerturbations(grid, None, None)
for i in range(10):

	fig = plt.figure(figsize=(9,4))

	gs = gridspec.GridSpec(1, 2)
	gs.update(left=0.1, right=0.86, hspace=0.1)
	gs1 = gridspec.GridSpec(1, 1)
	gs1.update(left=0.89, right=0.92)
	ax = plt.subplot(gs[0])
	ax2 = plt.subplot(gs[1])
	ax_cmap = plt.subplot(gs1[0])

	cmap = plt.cm.afmhot_r

	p = ax.pcolormesh(x_mat, y_mat, p_pred[i,:,:,0], cmap=plt.cm.coolwarm,vmin = -0.75,vmax =0.75 )

	ax.set_aspect('equal', 'box')

	p2 = ax2.pcolormesh(x_mat, y_mat, pressure_actual[i,:,:,0], cmap=plt.cm.coolwarm ,vmin = -0.75, vmax = 0.75)
	cbar = fig.colorbar(p2, ax_cmap, orientation='vertical')

	ax.set_aspect('equal', 'box')
	fig.savefig(os.path.join(save_folder, 'pressure_both{:}.png'.format(i)), format='png')

	# def compare_trans_mat_vtheta(trans_matrix_1, trans_matrix_2, figure_save_folder, prefix, refsize = 16):

	# fontsize = refsize * 0.8
	# fmt = 'pdf'
	# fig = plt.figure(figsize=(9,4))

	# gs = gridspec.GridSpec(1, 2)
	# gs.update(left=0.1, right=0.86, hspace=0.1)
	# gs1 = gridspec.GridSpec(1, 1)
	# gs1.update(left=0.89, right=0.92)
	# ax = plt.subplot(gs[0])
	# ax2 = plt.subplot(gs[1])
	# ax_cmap = plt.subplot(gs1[0])
	# cmap = plt.cm.afmhot_r
	# max_prob = 1.0
	# # print max_prob
	# p = ax.pcolor(np.sqrt(trans_matrix_1), norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,vmin=0, vmax=max_prob),
	# 	cmap=cmap, linewidth=0, rasterized=True)
	# p2 = ax2.pcolor(np.sqrt(trans_matrix_2), norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,vmin=0, vmax=max_prob),
	# 	cmap=cmap, linewidth=0, rasterized=True)

	# cbar = fig.colorbar(p, ax_cmap, orientation='vertical')
	# tick_array = [0.0, 0.1, 0.2, 0.3, 0.5, 0.7, 1.0]
	# cbar.set_ticks(tick_array)
	# # cbar.set_ticklabels()
	# lp  = 1
	# ax.set_xlabel('previous class ' + r'($v_n$)', labelpad=lp)
	# ax.set_ylabel('next class '+ r'($v_{n+1}$)', labelpad=lp)
	# ax2.set_xlabel('previous class '+ r'($\theta_n$)', labelpad=lp)
	# ax2.set_ylabel('next class '+ r'($\theta_{n+1}$)', labelpad=lp)
	# mat_size = trans_matrix_1.shape[1]
	# ax_bound = [0, mat_size]
	# ax.set_xbound(ax_bound)
	# ax.set_ybound(ax_bound)
	# mat_size = trans_matrix_2.shape[1]
	# ax_bound = [0, mat_size]
	# ax2.set_xbound(ax_bound)
	# ax2.set_ybound(ax_bound)
	# fig_name = prefix +'.'+fmt
	# file_name = os.path.join(figure_save_folder, fig_name)
	# fig.savefig(file_name, format=fmt)
	# plt.close(fig)


from django.shortcuts import get_object_or_404
from products.models import Product
from shipping.models import Shipping
from decimal import Decimal

def cart_contents(request):
    """
    Ensures that the cart contents are available when rendering
    every page
    """
    cart = request.session.get('cart', {})

    cart_items = []
    sub_total = Decimal(0)
    product_count = 0

    for id, quantity in cart.items():
        product = get_object_or_404(Product, pk=id)
        item_total = quantity * product.price
        sub_total += item_total
        product_count += quantity
        cart_items.append({'id': id, 'quantity': quantity, 'product': product, 'total': item_total})

    regions = Shipping.objects.all()
    try:
        default_region = regions[0].name
    except IndexError:
        default_region = ""
    selected_region = request.session.get('selected_region', default_region)
    region_price = Decimal(0)
    for region in regions:
        if region.name == selected_region:
            region_price = region.price
            break

    total = sub_total + region_price

    return {
        'product_count': product_count,
        'cart_items': cart_items,
        'sub_total': sub_total,
        'total': total,
        'regions': regions,
        'selected_region': selected_region,
        'region_price': region_price
    }


# for windows
import pyttsx3

# for chromium
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from time import sleep

def SpeakWindows(query):
    engine = pyttsx3.init("sapi5")
    voices = engine.getProperty("voices")
    engine.setProperty('voices', voices[0].id)
    engine.setProperty('rate', 170)

    print("")
    print(f"You: {query}. ")
    print("")

    engine.say(query)
    engine.runAndWait()

chrome_options = Options()
chrome_options.add_argument("--log-level=3")
chrome_options.headless = True

# chrome driver path
Path = "src\\driver\\chromedriver.exe"

# linking to chrome
driver = webdriver.Chrome(Path, options=chrome_options)
driver.maximize_window()

FreeTTS_Engine_URL = r"https://ttsmp3.com/text-to-speech/British%20English/"
driver.get(FreeTTS_Engine_URL)
ButtonSelection = Select(driver.find_element(by=By.XPATH, value="/html/body/div[4]/div[2]/form/select"))
ButtonSelection.select_by_visible_text("British English / Brian")

def SpeakChromium(query):
    length_of_query = len(str(query))

    if length_of_query == 0:
        pass

    else:
        print("")
        print(f"Ultron: {query}. ")
        print("")

        Data = str(query)
        xpathofsec = '/html/body/div[4]/div[2]/form/textarea'
        driver.find_element(By.XPATH, value=xpathofsec).send_keys(Data)
        driver.find_element(By.XPATH, value='//*[@id="vorlesenbutton"]').click()
        driver.find_element(By.XPATH, value="/html/body/div[4]/div[2]/form/textarea").clear()

        if length_of_query >= 30:
            sleep(4)

        elif length_of_query >= 40:
            sleep(6)

        elif length_of_query >= 55:
            sleep(8)

        elif length_of_query >= 70:
            sleep(10)

        elif length_of_query >= 100:
            sleep(12)

        elif length_of_query >= 120:
            sleep(14)

        else:
            sleep(2)

# SpeakChromium("hello ultron, this is rintron glade")


from math import sqrt
class Solution:
    # @param A : integer
    # @return an integer
    def isPower(self, n):
        if n > 2**32: return 0
        elif n == 1: return 1
        numbers = []

        # add all square numbers from 1 <= a <= sqrt(n)
        # but only if n is multiple of a
        for a in range(2, int(sqrt(n)) + 1):
            if (n % a == 0):
                numbers.append((a, a * a))

        # check list of candidates
        while numbers:
            # pop last tuple, see if we have n or whether n can be made
            (a, x) = numbers.pop()
            e = 2
            # try to compose n with a^e with e := integer greater than 1
            while x < n:
                e += 1
                x *= a
            if x == n:
                return 1
        # no solution was found looking at the candidates
        return 0


from ProductClass import *

# to Store class
# add_product(self, new_product) - takes a product and adds it to the store
# sell_product(self, id) - remove the product from the store's list of products

# given the id (assume id is the index of the product in the list) and print its info.

# inflation(self, percent_increase) - increases the price of each product
# by the percent_increase given (use the method you wrote in the Product class!)

# get_clearance(self, category, percent_discount) - updates all the products
# matching the given category by reducing the price by the percent_discount given
# (use the method you wrote in the Product class!)

import uuid
import time

class Store:
    def __init__(self, name = None, prod_list=[]):
        self.name = name
        self.prod_list = prod_list

    def add_product(self,new_product_name, price, category):
        id = "{}-{}".format(uuid.uuid4(), time.time())
        newprod = Product(id,new_product_name, price, category)
        self.prod_list.append(newprod)

    def sell_product(self, prod_id):
        self.prod_list.pop(prod_id)

    def print_prod_info(self, prod_id=None):
        if prod_id == None:
            print("All products in the store:")
            for item in self.prod_list:
                print(item)
        else:
            print("\nInfo for product with id:", prod_id)
            print(self.prod_list[prod_id], end ="")

    def inflation(self, id, percent_increase):
        prod = Product()
        upd_prod=prod.update_price(percent_increase, self.prod_list[id],is_increased=True)
        self.prod_list[id] = upd_prod

    def get_clearance(self, category_id, percent_discount):
        prod = Product()
        i = 0
        for prod in self.prod_list:
            if prod.category == category_id:
                print("found a catid match!", prod.category, category_id)
                upd_prod=prod.update_price(percent_discount, self.prod_list[i],is_increased=False)
                self.prod_list[i] = upd_prod
            i = i+1

    # def __str__(self):
    #     # Override to print a readable string presentation of your object
    #     # below is a dynamic way of doing this without explicity constructing the string manually
    #     return ', '.join(['{key}={value}'.format(key=key, value=self.__dict__.get(key)) for key in self.__dict__])

mystore= Store()
mystore.add_product("Buble", 20, 11)
mystore.add_product("Chair", 250, 8)
mystore.add_product("Table", 25, 3)
mystore.add_product("T", 5, 3)
mystore.add_product("B", 15, 3)
mystore.add_product("D", 3, 3)
mystore.add_product("Plate", 20, 11)

mystore.print_prod_info()
mystore.print_prod_info(1)

print("\nAfter inflation:")
mystore.inflation(0,2)

mystore.print_prod_info()
print('After clearence')
mystore.get_clearance(3,2)
mystore.print_prod_info()

mystore.sell_product(2)
print("\nSold product with id = 2")
mystore.print_prod_info()

#print(mystore)


from openpyxl.workbook import Workbook
from openpyxl import load_workbook

workbook = Workbook()
worksheet = workbook.active

ws1 = workbook.create_sheet('New Shiiit')
ws2 = workbook.create_sheet('Another sheet', 0)

worksheet.title = 'mySheet'

workbook2 = load_workbook('data/regions.xlsx')
new_sheet = workbook2.create_sheet('yet another sheet')
active_sheet = workbook2.active
cell = active_sheet['A1']

active_sheet['A1'] = f'helllllo'
workbook2.save('output/modified.xlsx')


import porespy as ps
import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage as spim
import scipy.io as sio
import pickle
from matplotlib import cm

### Load pore structure and LB simulation data

velocityNormData = np.loadtxt('weibullCubeVelocityNorm_300.dat')
simSize = 300
velocityNormData = np.reshape(velocityNormData,(simSize,simSize,simSize))

data = np.loadtxt("weibull300_cube.txt",delimiter=',')
beadPack = np.reshape(data,(simSize,simSize,simSize))

beadPack = np.transpose(beadPack,(1,2,0))

plt.figure(2)
plt.imshow(velocityNormData[:,:,100], cmap=plt.cm.nipy_spectral)

plt.imshow(beadPack[:,:,100],cmap=plt.cm.nipy_spectral)

plt.imshow((beadPack*velocityNormData)[:,:,100],cmap=plt.cm.nipy_spectral)

### Compute pore network information

dt = spim.distance_transform_edt(input=beadPack)
dt = spim.gaussian_filter(input=dt, sigma=0.4)
peaks = ps.network_extraction.find_peaks(dt=dt, r=4)

peaks = ps.network_extraction.trim_saddle_points(peaks=peaks, dt=dt)
peaks = ps.network_extraction.trim_nearby_peaks(peaks=peaks, dt=dt)

regions = ps.network_extraction.partition_pore_space(im=dt, peaks=peaks)

plt.figure(1)
plt.imshow((regions*beadPack)[:, :, 50], cmap=plt.cm.nipy_spectral)
plt.axis('off')

im = regions*beadPack
im = im.astype(np.int64)
net = ps.network_extraction.extract_pore_network(im=im, dt=dt)

cubeSize = len(beadPack)

velocities = {}

regionMap = regions*beadPack

for a in range(0, cubeSize):
    for b in range(0, cubeSize):
        for c in range(0, cubeSize):

            #print(beadPack[a,b,c])

            key = str(regionMap[a,b,c])
            if key != '0.0':
                if key in velocities:
                    velocities[key].append(velocityNormData[a,b,c])
                else:
                    velocities.setdefault(key,[])
                    velocities[key].append(velocityNormData[a,b,c])

numPores = len(net['pore.label'])
avgVelocity = []
for a in range(0, numPores):
    key = "%0.1f" % net['pore.label'][a]

    avgVelocity.append(sum(velocities[key])/len(velocities[key]))

net['avgVelocity'] = avgVelocity

#props = ps.metrics.regionprops_3D(im)

#plt.figure(5)
#plt.scatter(net['pore.diameter'],net['avgVelocity'])
#plt.show

# Save output data via pickle
outFile = 'weibullCubeNetworkInfo_300.pkl'

output = open(outFile,'wb')
pickle.dump(net, output)
pickle.dump(velocities, output)

#pickle.dump(props, output)

output.close()


"""
In this file, I have created the connection to my aws S3 bucket
Then i have uploaded my csv file to s3 bucket
"""

import boto
import boto3
import pandas as pd
from io import StringIO
import boto.s3.connection
from Perform_logging import log

class Bucket:
    """
    A class representing a bucket in Amazon S3.

    Attributes:
    -----------
    file_name : str
        The name of the CSV file to be uploaded to S3 bucket.
    access_key : str
        The AWS access key.
    secret_key : str
        The AWS secret access key.

    Methods:
    --------
    create_connection_bucket() -> None:
        Creates a connection to an S3 bucket using the given access and secret keys.
    upload_file_to_s3bucket() -> None:
        Uploads the CSV file to the S3 bucket.
    run() -> None:
        Runs the complete process of creating the connection to the S3 bucket and uploading the CSV file to the S3 bucket.
    """

    def __init__(self, file_name: str, access_key: str, secret_key: str) -> None:
        """
        Constructs a Bucket object.

        Parameters:
        -----------
        file_name : str
            The name of the CSV file to be uploaded to S3 bucket.
        access_key : str
            The AWS access key.
        secret_key : str
            The AWS secret access key.
        """

        self.CsvFileName = file_name
        self.__access_key = access_key
        self.__secret_key = secret_key

    def create_connection_bucket(self) -> None:
        """
        Creates a connection to an S3 bucket using the given access and secret keys.
        """
        log.info('Creating connection to S3 bucket...')
        conn = boto.connect_s3(
            aws_access_key_id=self.__access_key,
            aws_secret_access_key=self.__secret_key)

        buck1 = conn.create_bucket('my_data')
        log.info('Connection created successfully!')

    def upload_file_to_s3bucket(self) -> None:
        """
        Uploads the CSV file to the S3 bucket.
        """
        log.info('Uploading file to S3 bucket...')
        my_file = pd.read_csv(self.CsvFileName)

        s3 = boto3.client('s3',
                          aws_access_key_id=self.__access_key,
                          aws_secret_access_key=self.__secret_key)
        csv_buff = StringIO()
        my_file.to_csv(csv_buff, header=True, index=False)
        csv_buff.seek(0)
        s3.put_object(Bucket='Fininstrm_data',
                      Body=csv_buff.getvalue(), key='fininstrm_data')
        log.info('File uploaded successfully!')

    def run(self) -> None:
        """
        Runs the complete process of creating the connection to the S3 bucket and uploading the CSV file to the S3 bucket.
        """

        log.info(
            'Starting process to create connection to S3 bucket and upload file...')
        self.create_connection_bucket()
        self.upload_file_to_s3bucket()
        log.info('Process completed successfully!')


# -*- coding: utf-8 -*-

import scrapy
from parqueInmobiliario.items import InmuebleItem
from urllib.parse import urlparse

class FotocasaSpider(scrapy.Spider):
    name = 'fotocasa'
    def __init__(self, *args, **kwargs):

        super(FotocasaSpider, self).__init__(*args, **kwargs)
        self.start_urls = [
            "https://www.fotocasa.es/es/comprar/viviendas/"+ kwargs.get('ciudad') +"-provincia/todas-las-zonas/l/"
        ]

    def parse(self, response):

        for i in range(1,20):
            link = response.url + str(i)
            yield scrapy.Request(link, self.parse_pagina)

    def parse_pagina(self, response):
        links = response.xpath('//a[@class="re-CardImage-link"]/@href').extract()
        precios = response.xpath('//span[@class="re-Card-price"]/text()').extract()
        #habitaciones = response.xpath('//span[@class="re-Card-wrapperFeatures"]/span/text()')[0].extract()
        #superficies = response.xpath('//span[@class="re-Card-wrapperFeatures"]/span/text()')[1].extract()
        print(links)
        for i in range(0,len(links)):
            item = InmuebleItem()
            item['precio'] = precios[i]
            item ['link'] = 'https://www.fotocasa.es' + links[i]
            request = scrapy.Request(item['link'], callback=self.parse_vivienda, meta={'item': item})
            yield request

    def parse_vivienda(self, response):

        item = InmuebleItem()
        item['ciudad'] = response.xpath( '//a[@class = "re-Breadcrumb-link"]/text()' )[2].get()
        #item['codigoPostal'] = response.xpath( '//p[@class = "fc-DetailDescription"]/text()' ).re_first( r'[0-9]{5}' )
        item['comunidad'] = response.xpath( '//a[@class = "re-Breadcrumb-link"]/text()' )[0].get()
        item['habitaciones'] = response.xpath( '//li[@class = "re-DetailHeader-featuresItem"]/text()' )[0].re_first( r"([0-9]+) hab" )
        item['banos'] = response.xpath( '//li[@class = "re-DetailHeader-featuresItem"]/text()' )[1].re_first( r'([0-9]+) baño' )
        item['superficie'] = response.xpath( '//li[@class = "re-DetailHeader-featuresItem"]/text()' )[2].re_first( r'[0-9]+' )
        item['precio'] = response.xpath( '//span[@class = "re-DetailHeader-price"]/text()' ).re_first( r'[0-9]+\.[0-9]+' )
        item['referencia'] = response.xpath( '//span[@class = "re-DetailReference"]/text()' ).re_first( r'[0-9]+' )
        item['particular'] = 'Profesional' if response.xpath( '//div[@class = "re-ContactDetail-inmo"]' ) else 'Particular'
        item['web'] = 'Fotocasa'
        item['link'] = response.url

        yield item


import subprocess
import os
import abc
from . import base_transcoder, statistics

def animation2webm(source, out_file, crf=32):
    fname = ""
    if type(source) is str:
        fname = source
    elif isinstance(source, (bytes, bytearray)):
        fname = "transcode"
        file = open(fname, "bw")
        file.write(source)
        file.close()
    subprocess.call(
        [
            'ffmpeg',
            '-loglevel', 'error',
            '-i', fname,
            '-pix_fmt', 'yuva420p',
            '-c:v', 'libvpx-vp9',
            '-crf', str(crf),
            '-b:v', '0',
            '-profile:v', '0',
            '-f', 'webm',
            out_file
        ]
    )
    if isinstance(source, (bytes, bytearray)):
        os.remove(fname)

class WEBM_VideoOutputFormat(base_transcoder.BaseTranscoder):
    def animation_encode(self):
        self._quality = 85
        animation2webm(self._source, self._output_file + '.webm')
        self._output_size = os.path.getsize(self._output_file + '.webm')

    @abc.abstractmethod
    def _all_optimisations_failed(self):
        pass

    @abc.abstractmethod
    def get_converter_type(self):
        pass

    def gif_optimisations_failed(self):
        print("optimisations_failed")
        os.remove(self._output_file + '.webm')
        self._fext = 'webp'
        converter = self.get_converter_type()(self._source)
        out_data = converter.compress(lossless=True)
        self._output_size = len(out_data)
        if self._output_size >= self._size:
            self._all_optimisations_failed()
        else:
            out_data = converter.compress(lossless=True, fast=False)
            self._output_size = len(out_data)
            outfile = open(self._output_file + '.webp', 'wb')
            outfile.write(out_data.tobytes())
            outfile.close()
            print(('save {} kbyte ({}%) quality = {}').format(
                round((self._size - self._output_size) / 1024, 2),
                round((1 - self._output_size / self._size) * 100, 2),
                self._quality
            ))
            self._set_utime()
            self._remove_source()
            statistics.sumsize += self._size
            statistics.sumos += self._output_size
            statistics.avq += self._quality
            statistics.items += 1
        converter.close()


pi = 3.141592653589793
tol = 10**-8
iterMax = 2500
eps = 2.2204*(10**-16)

def is_number(x):
    if type(x) == int or type(x)==float:
        return True
    else:
        return False

def fact(x):
    """
    Toma un numero entero y retorna el factorial de ese numero

    :param n: numero entero
    :return: factorial del numero
    """
    if not is_number(x):
        return "err"
    x= int(x)
    fact = 1
    for i in range(1,x+1):
        fact = fact * i
    return fact

def div_t(x):
    """
    calcula la inversa de un numero, es decir 1/x o x^-1

    :param x: numero
    :return: inverso de x
    """
    if not is_number(x):
        return "err"
    if x==0:
        return "err"
    if x>0:
        return div_t_v(x)
    if x<0:
        return -1*div_t_v(abs(x))
def div_t_v(x):
    if fact(80)< x < fact(100):
        return div_t_aux(x, eps**15)
    if fact(60)< x <= fact(80):
        return div_t_aux(x, eps**11)
    if fact(40)< x <= fact(60):
        return div_t_aux(x, eps**8)
    if fact(20)< x <= fact(40):
        return div_t_aux(x, eps**4)
    if 0 < x <= fact(20):
        return div_t_aux(x, eps**2)
    if x >= fact(100):
        return 0
    return "err"
def div_t_aux(x, x0):
    xk = x0*(2-x*x0)
    for n in range (1,iterMax):
        xk1=xk*(2-(x*xk))
        if abs(xk1-xk)< tol*abs(xk1):
            return xk1
        xk=xk1
    return xk1

def exp_t(x):
    """
    calcula la funcion exponencial de un numero con base e

    :param x: numero
    :return: e elevado a x
    """
    if not is_number(x):
        return "err"
    xk= 1
    for n in range (1,iterMax):
        xk1=xk+power_t(x,n)*div_t(fact(n))
        error = abs(xk1-xk)
        if error<tol:
            return xk1
        xk=xk1

    return xk1

def ln_t(x):
    """
    calcula el logaritmo natural de un numero en radianes

    :param x: numero
    :return: logaritmo natural de x
    """
    if not is_number(x):
        return "err"
    if x<=0:
        return "err"
    xk=1
    const = (2*(x-1)) * div_t(x+1)
    for n in range (1,iterMax):
        xk1 = xk + ( div_t(2*n+1) * (power_t((x-1) * div_t(x+1), 2*n) ))
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1 * const
    print("break no err")
    return xk1 * const

def power_t(x,y):
    """
    calcula la potencia de un numero, es decir x^y

    :param x: numero
    :param y: exponente
    :return: numero elevado al exponente
    """
    if not is_number(x):
        return "err"
    if y == round(y):
        if y >=0:
            return x**y
        else:
            return div_t(x**abs(y))
    if x>=0 and y>=0:
        return exp_t(y*ln_t(x)) # no son enteros y son positivos
    if x<0 and y>=0:
        return -1* exp_t(y*ln_t(x))
    return x**y

def sin_t(x):
    """
    calcula el seno de un numero en radianes

    :param x: numero
    :return: seno de x
    """
    if not is_number(x):
        return "err"
    xk=x
    for n in range (1,iterMax):
        var = (2*n)+1
        xk1 = xk + ( power_t(-1,n) * (power_t(x,var) *div_t(fact(var))) )
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def sinh_t(x):
    """
    calcula el seno hiperbolico de un numero en radianes

    :param x: numero
    :return: seno hiperbolico de x
    """
    if not is_number(x):
        return "err"
    xk=x
    for n in range (1,iterMax):
        var = (2*n)+1
        xk1 = xk + (power_t(x,var) *div_t(fact(var)))
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def cosh_t(x):
    """
    calcula el coseno hiperbolico de un numero en radianes

    :param x: numero
    :return: coseno hiperbolico de x
    """
    if not is_number(x):
        return "err"
    xk=1
    for n in range (1,iterMax):
        var = 2*n
        xk1 = xk + (power_t(x,var) *div_t(fact(var)))
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def tanh_t(x):
    """
    calcula la tangente hiperbolica de un numero en radianes

    :param x: numero
    :return: tangente hiperbolica de x
    """
    if not is_number(x):
        return "err"
    return sinh_t(x)*div_t(cosh_t(x))

def root_t(x,y):
    """
    calcula la raiz de un numero

    :param x: numero
    :param y: indice
    :return: raiz de x segun el indice y
    """
    if not is_number(x):
        return "err"
    if (y%2==0 and x<0):
        return "err"
    if y == round(y) and y>2 :
        return root_t_aux(x,y)
    else:
        return power_t(x, div_t(y))
def root_t_aux(x,y):
    xk=x*div_t(2)
    for n in range (1,iterMax):
        xk1 = xk - (power_t(xk,y)-x)* div_t(y*power_t(xk, y-1))
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def atan_t(x):
    """
    calcula el arco tangente de un numero en radianes

    :param x: numero
    :return: arco tangente de x
    """
    if not is_number(x):
        return "err"
    if -1 <= x <= 1:
        return atan_t_aux(x)
    if x>1:
        return atan_t_aux2(x,pi*div_t(2))
    if x<1:
        return atan_t_aux2(x,-1*pi*div_t(2))
def atan_t_aux(x):
    xk=x
    for n in range (1,iterMax):
        var = (2*n)+1
        xk1 = xk + ( power_t(-1,n) * (power_t(x,var) *div_t(var)) )
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1
def atan_t_aux2(x, const):
    xk= div_t(x)
    for n in range (1,iterMax):
        xk1 = xk + ( power_t(-1,n) * div_t((2*n+1) * power_t(x, 2*n+1)) )
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return const-xk1
    print("break no err")
    return const-xk1

def cos_t(x):
    """
    calcula el coseno de un numero en radianes

    :param x: numero
    :return: coseno de x
    """
    if not is_number(x):
        return "err"
    xk=1
    for n in range (1,iterMax):
        var = 2*n
        xk1 = xk + ( power_t(-1,n) * (power_t(x,var) *div_t(fact(var))) )
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def sec_t(x):
    """
    calcula el secante de un numero en radianes

    :param x: numero
    :return: secante de x
    """
    if not is_number(x):
        return "err"
    if cos_t(x) == 0:
        return "err"
    return div_t(cos_t(x))

def tan_t(x):
    """
    calcula la tangente de un numero en radianes

    :param x: numero
    :return: tangente de x
    """
    if not is_number(x):
        return "err"
    if cos_t(x) == 0:
        return "err"
    return sin_t(x)* div_t(cos_t(x))

def log_t(x, y):
    """
    calcula el logaritmo de un numero

    :param x: argumento
    :param y: base
    :return: logaritmo base y de x
    """
    if not is_number(x):
        return "err"
    if x<=0 or y<=0:
        return "err"
    return ln_t(x)* div_t(ln_t(y))

def sqrt_t(x):
    """
    calcula la raiz cuadrada de un numero

    :param x: numero
    :return: raiz cuadrada de x
    """
    if not is_number(x):
        return "err"
    if x<0:
        return "err"

    return root_t(x,2)

def asin_t(x):
    """
    calcula el arco seno de un numero en radianes

    :param x: numero
    :return: arco seno de x
    """
    if not is_number(x):
        return "err"
    if -1 <= x <= 1:
        return asin_t_aux(x)
    return "err"
def asin_t_aux(x):
    xk=x
    for n in range (1,iterMax):
        xk1 = xk + ( fact(2*n) * div_t(power_t(4,n) * power_t(fact(n), 2) * (2*n+1)) * power_t(x,2*n+1))
        error = abs(xk1-xk)
        xk=xk1
        if error<tol:
            return xk1
    print("break no err")
    return xk1

def csc_t(x):
    """
    calcula el cosecante de un numero en radianes

    :param x: numero
    :return: cosecante de x
    """
    return div_t(sin_t(x))

def cot_t(x):
    """
    calcula el cotangente de un numero en radianes

    :param x: numero
    :return: cotangente de x
    """
    if not is_number(x):
        return "err"
    if sin_t(x) == 0:
        return "err"
    return div_t(tan_t(x))

def acos_t(x):
    """
    calcula el arco coseno de un numero en radianes

    :param x: numero
    :return: arco coseno de x
    """
    if not is_number(x):
        return "err"
    if not(-1 <= x <= 1):
        return "err"
    return pi*div_t(2) - asin_t(x)

"""print("start test")
print(div_t(0.15))
print(sin_t(5.2))
print(tan_t(0.9))
print(log_t(10,5))
print(sinh_t(5.2))
print(tanh_t(5))
print(root_t(5,7))#
print(atan_t(-0.9))
print(sec_t(-0.9))
print(exp_t(0))
print(cos_t(1))
print(ln_t(970))
print(power_t(5,-3))
print(cosh_t(1))
print(sqrt_t(51))
print(asin_t(0.56))
print(csc_t(-1))
print(cot_t(0.56))

print(acos_t(-0.56))"""


import unittest
from needleman_wunsh import make_alignment

MATCH = 2
MISMATCH = -1
GAP = -2

class TestNeedlemanWunsh(unittest.TestCase):
    @staticmethod
    def calculate_score(seq1: str, seq2: str, match: int, mismatch: int, gap: int) -> int:
        """Calculates score of alignment. Helper function used for results validation. """

        def s(a, b):
            """Score of pair"""
            if a == '-' or b == '-':
                return gap
            elif a == b:
                return match
            else:
                return mismatch

        return sum(s(x, y) for x, y in zip(seq1, seq2))

    def check_answer_correctness(self, aligned_seq1, aligned_seq2, score, seq1, seq2):
        dealigned_seq1 = aligned_seq1.replace('-', '')
        dealigned_seq2 = aligned_seq2.replace('-', '')

        self.assertEqual(len(aligned_seq1), len(aligned_seq2), f'aligned sequences must have the same lenghts')
        self.assertEqual(len(seq1), len(dealigned_seq1),
                              f'Length of seq1 does not match length of aligned_seq1: {len(seq1)} !=  {len(dealigned_seq1)}')
        self.assertEqual(len(seq2), len(dealigned_seq2),
                              f'Length of seq1 does not match length of aligned_seq1: {len(seq2)} !=  {len(dealigned_seq2)}')
        self.assertEqual(dealigned_seq1, seq1, f'Output seq1 is different than input seq1')
        self.assertEqual(dealigned_seq2, seq2, f'Output seq2 is different than input seq2')
        for i in range(len(aligned_seq1)):
            self.assertFalse((aligned_seq1[i] == '-' and aligned_seq2[i] == '-'),
                                  f'alignment can not have dash in both sequences at the same position: {i}')
        actual_score = self.calculate_score(aligned_seq1, aligned_seq2, MATCH, MISMATCH, GAP)
        self.assertEqual(actual_score, score, f'Reported score does not match actual score: {score} != {actual_score}')

    def test_empty(self):
        seq = ''
        al_1, al_2, s = make_alignment(seq, seq, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq, seq)
        self.assertEqual(seq, al_1)
        self.assertEqual(seq, al_2)
        self.assertEqual(0, s)

    def test_single_character_match(self):
        seq = 'A'
        al_1, al_2, s = make_alignment(seq, seq, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq, seq)
        self.assertEqual(seq, al_1)
        self.assertEqual(seq, al_2)
        self.assertEqual(MATCH, s)

    def test_single_character_mismatch(self):
        seq1 = 'A'
        seq2 = 'B'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual(seq1, al_1)
        self.assertEqual(seq2, al_2)
        self.assertEqual(MISMATCH, s)

    def test_match_gap(self):
        seq1 = 'A'
        seq2 = 'AG'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual('A-', al_1)
        self.assertEqual('AG', al_2)
        self.assertEqual(MATCH + GAP, s)

    def test_match_mismatch(self):
        seq1 = 'AT'
        seq2 = 'AG'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual(seq1, al_1)
        self.assertEqual(seq2, al_2)
        self.assertEqual(MATCH + MISMATCH, s)

    def test_mismatch_gap(self):
        seq1 = 'T'
        seq2 = 'AG'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual(MISMATCH + GAP, s)

    def test_border(self):
        seq1 = 'A'
        seq2 = 'TGGGTA'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual('-----A', al_1)
        self.assertEqual(seq2, al_2)
        self.assertEqual(MATCH + 5 * GAP, s)

    def test_border_flip(self):
        seq1 = 'TGGGTA'
        seq2 = 'A'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual(seq1, al_1)
        self.assertEqual('-----A', al_2)
        self.assertEqual(MATCH + 5 * GAP, s)

    def test_shifted(self):
        seq1 = 'ATG'
        seq2 = 'GAT'
        al_1, al_2, s = make_alignment(seq1, seq2, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, seq1, seq2)
        self.assertEqual('-ATG', al_1)
        self.assertEqual('GAT-', al_2)
        self.assertEqual(2 * MATCH + 2 * GAP, s)

    def test_complex_1(self):
        s_1WFN = 'GSSGSSGPQLVRTHEDVPGPVGHLSFSEILDTSLKVSWQEPGEKNGILTGYRISWEEYNRTNTRVTHYLPNVTLEYRVTGLTALTTYTIEVAAMTSKGQGQVSASTISSGVPPSGPSSG'
        s_1WFO = 'GSSGSSGRIGDGSPSHPPILERTLDDVPGPPMGILFPEVRTTSVRLIWQPPAAPNGIILAYQITHRLNTTTANTATVEVLAPSARQYTATGLKPESVYLFRITAQTRKGWGEAAEALVVTTEKRSGPSSG'
        al_1, al_2, s = make_alignment(s_1WFN, s_1WFO, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, s_1WFN, s_1WFO)
        self.assertEqual(6, s)

    def test_complex_2(self):
        s_1WFN = 'GSSGSSGPQLVRTHEDVPGPVGHLSFSEILDTSLKVSWQEPGEKNGILTGYRISWEEYNRTNTRVTHYLPNVTLEYRVTGLTALTTYTIEVAAMTSKGQGQVSASTISSGVPPSGPSSG'
        s_1WIS = 'GSSGSSGTISSGVPPELPGPPTNLGISNIGPRSVTLQFRPGYDGKTSISRWLVEAQVGVVGEGEEWLLIHQLSNEPDARSMEVPDLNPFTCYSFRMRQVNIVGTSPPSQPSRKIQTLQSGPSSG'
        al_1, al_2, s = make_alignment(s_1WFN, s_1WIS, MATCH, MISMATCH, GAP)
        self.check_answer_correctness(al_1, al_2, s, s_1WFN, s_1WIS)
        self.assertEqual(-27, s)

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


from oslo.config import cfg
import requests

from nova import context
from nova import db
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova.scheduler import filters

LOG = logging.getLogger(__name__)

trusted_opts = [
    cfg.StrOpt('attestation_server',
               help='Attestation server HTTP'),
    cfg.StrOpt('attestation_server_ca_file',
               help='Attestation server Cert file for Identity verification'),
    cfg.StrOpt('attestation_port',
               default='8443',
               help='Attestation server port'),
    cfg.StrOpt('attestation_api_url',
               default='/OpenAttestationWebServices/V1.0',
               help='Attestation web API URL'),
    cfg.StrOpt('attestation_auth_blob',
               help='Attestation authorization blob - must change'),
    cfg.IntOpt('attestation_auth_timeout',
               default=60,
               help='Attestation status cache valid period length'),
    cfg.BoolOpt('attestation_insecure_ssl',
                default=False,
                help='Disable SSL cert verification for Attestation service')
]

CONF = cfg.CONF
trust_group = cfg.OptGroup(name='trusted_computing', title='Trust parameters')
CONF.register_group(trust_group)
CONF.register_opts(trusted_opts, group=trust_group)

class AttestationService(object):
    # Provide access wrapper to attestation server to get integrity report.

    def __init__(self):
        self.api_url = CONF.trusted_computing.attestation_api_url
        self.host = CONF.trusted_computing.attestation_server
        self.port = CONF.trusted_computing.attestation_port
        self.auth_blob = CONF.trusted_computing.attestation_auth_blob
        self.key_file = None
        self.cert_file = None
        self.ca_file = CONF.trusted_computing.attestation_server_ca_file
        self.request_count = 100
        # If the CA file is not provided, let's check the cert if verification
        # asked
        self.verify = (not CONF.trusted_computing.attestation_insecure_ssl
                       and self.ca_file or True)
        self.cert = (self.cert_file, self.key_file)

    def _do_request(self, method, action_url, body, headers):
        # Connects to the server and issues a request.
        # :returns: result data
        # :raises: IOError if the request fails

        action_url = "https://%s:%d%s/%s" % (self.host, self.port,
                                             self.api_url, action_url)
        try:
            res = requests.request(method, action_url, data=body,
                                   headers=headers, cert=self.cert,
                                   verify=self.verify)
            status_code = res.status_code
            # pylint: disable=E1101
            if status_code in (requests.codes.OK,
                               requests.codes.CREATED,
                               requests.codes.ACCEPTED,
                               requests.codes.NO_CONTENT):
                try:
                    return requests.codes.OK, jsonutils.loads(res.text)
                except ValueError:
                    return requests.codes.OK, res.text
            return status_code, None

        except requests.exceptions.RequestException:
            return IOError, None

    def _request(self, cmd, subcmd, hosts):
        body = {}
        body['count'] = len(hosts)
        body['hosts'] = hosts
        cooked = jsonutils.dumps(body)
        headers = {}
        headers['content-type'] = 'application/json'
        headers['Accept'] = 'application/json'
        if self.auth_blob:
            headers['x-auth-blob'] = self.auth_blob
        status, res = self._do_request(cmd, subcmd, cooked, headers)
        return status, res

    def do_attestation(self, hosts):
        """Attests compute nodes through OAT service.

        :param hosts: hosts list to be attested
        :returns: dictionary for trust level and validate time
        """
        result = None

        status, data = self._request("POST", "PollHosts", hosts)
        if data is not None:
            result = data.get('hosts')

        return result

class ComputeAttestationCache(object):
    """Cache for compute node attestation

    Cache compute node's trust level for sometime,
    if the cache is out of date, poll OAT service to flush the
    cache.

    OAT service may have cache also. OAT service's cache valid time
    should be set shorter than trusted filter's cache valid time.
    """

    def __init__(self):
        self.attestservice = AttestationService()
        self.compute_nodes = {}
        admin = context.get_admin_context()

        # Fetch compute node list to initialize the compute_nodes,
        # so that we don't need poll OAT service one by one for each
        # host in the first round that scheduler invokes us.
        computes = db.compute_node_get_all(admin)
        for compute in computes:
            host = compute['hypervisor_hostname']
            self._init_cache_entry(host)

    def _cache_valid(self, host):
        cachevalid = False
        if host in self.compute_nodes:
            node_stats = self.compute_nodes.get(host)
            if not timeutils.is_older_than(
                             node_stats['vtime'],
                             CONF.trusted_computing.attestation_auth_timeout):
                cachevalid = True
        return cachevalid

    def _init_cache_entry(self, host):
        self.compute_nodes[host] = {
            'trust_lvl': 'unknown',
            'vtime': timeutils.normalize_time(
                        timeutils.parse_isotime("1970-01-01T00:00:00Z"))}

    def _invalidate_caches(self):
        for host in self.compute_nodes:
            self._init_cache_entry(host)

    def _update_cache_entry(self, state):
        entry = {}

        host = state['host_name']
        entry['trust_lvl'] = state['trust_lvl']

        try:
            # Normalize as naive object to interoperate with utcnow().
            entry['vtime'] = timeutils.normalize_time(
                            timeutils.parse_isotime(state['vtime']))
        except ValueError:
            try:
                # Mt. Wilson does not necessarily return an ISO8601 formatted
                # `vtime`, so we should try to parse it as a string formatted
                # datetime.
                vtime = timeutils.parse_strtime(state['vtime'], fmt="%c")
                entry['vtime'] = timeutils.normalize_time(vtime)
            except ValueError:
                # Mark the system as un-trusted if get invalid vtime.
                entry['trust_lvl'] = 'unknown'
                entry['vtime'] = timeutils.utcnow()

        self.compute_nodes[host] = entry

    def _update_cache(self):
        self._invalidate_caches()
        states = self.attestservice.do_attestation(self.compute_nodes.keys())
        if states is None:
            return
        for state in states:
            self._update_cache_entry(state)

    def get_host_attestation(self, host):
        """Check host's trust level."""
        if host not in self.compute_nodes:
            self._init_cache_entry(host)
        if not self._cache_valid(host):
            self._update_cache()
        level = self.compute_nodes.get(host).get('trust_lvl')
        return level

class ComputeAttestation(object):
    def __init__(self):
        self.caches = ComputeAttestationCache()

    def is_trusted(self, host, trust):
        level = self.caches.get_host_attestation(host)
        return trust == level

class TrustedFilter(filters.BaseHostFilter):
    """Trusted filter to support Trusted Compute Pools."""

    def __init__(self):
        self.compute_attestation = ComputeAttestation()

    def host_passes(self, host_state, filter_properties):
        instance_type = filter_properties.get('instance_type', {})
        extra = instance_type.get('extra_specs', {})
        trust = extra.get('trust:trusted_host')
        host = host_state.nodename
        if trust:
            return self.compute_attestation.is_trusted(host, trust)
        return True


import math
from collections import deque

text = open("input.txt").read()

blizards = set()
lines = text.split("\n")
for y, line in enumerate(lines):
    for x, c in enumerate(line):
        if c in '><^v':
            blizards.add((x,y,c))
W, H = len(lines[0]), len(lines)
PERIOD = math.lcm(W-2, H-2)

DIRS = {'<': (-1, 0), '>': (1,0), '^': (0, -1), 'v': (0, 1), 'x': (0,0)}
BLIZARDS = {}

def simulate(blizards):
    new = set()
    for x, y, dir in blizards:
        dx, dy = DIRS[dir]
        x2 = (x+dx-1)%(W-2)+1
        y2 = (y+dy-1)%(H-2)+1
        new.add((x2,y2,dir))
    return new

def BFS(blizards, target):
    queue = deque([(1, 0, 0, 0)])
    bests = {}
    bests[queue[-1]] = 0
    last_time = -1
    ile = 0
    while queue:
        ile += 1
        item = queue.popleft()
        x, y, time, count = item

        if time != last_time:
            last_time = time
            if time not in BLIZARDS:
                b =simulate(blizards)
                BLIZARDS[time] = (b, {(x,y) for x,y,_ in b})
            blizards, cells = BLIZARDS[time]

        if (x,y,count) == target:
            return bests[item]

        new_count = count
        if (count%2 == 0) and (x, y)== (W-2, H-1):
            new_count += 1
        elif (count % 2 == 1) and (x,y) == (1,0):
            new_count += 1

        for dx, dy in DIRS.values():
            p = x2, y2 = x+dx, y+dy

            if p==(1,0) or p == (W-2, H-1) or ((1 <= x2 < W-1) and (1 <= y2 < H-1)):
                item2 = (x2, y2, (time+1)%PERIOD, new_count)

                if (p not in cells) and (item2 not in bests):
                    queue.append(item2)
                    bests[item2] = bests[item]+1

print("a:", BFS(blizards, (W-2,H-1,0)))
print("b:", BFS(blizards, (W-2,H-1,2)))


somaidade = 0
maioridadehomem = 0
nomevelho = ''
totmulher20 = 0
for p in range (1,5):
    print ('{}ª PESSOA'.format(p))
    nome = str(input('NOME: '))
    idade =(int(input('IDADE: ')))
    sexo = (input('SEXO [M/F]: '))
    somaidade += idade
    if p == 1 and sexo in 'Mm':
        maioridadehomem = idade
    if sexo in 'Mm' and idade > maioridadehomem:
        maioridadehomem = idade
        nomevelho = nome
    if sexo in 'Ff'and idade < 20:
        totmulher20 += 1
media = somaidade / 4
print('A média da idade do grupo foi de: {:.1f} anos'.format(media))
print('O homem mais velho tem {} anos e se chama {}.'.format(maioridadehomem, nomevelho))
print('Ao todo tem {} mulheres com menos de 20 anos de idade'.format(totmulher20))