#!/usr/bin/env python3

import requests
import socket
from utils import logger

moviePage_url = 'https://trailers.apple.com/'
movieSearch_url = 'https://trailers.apple.com/trailers/home/scripts/quickfind.php'
log = logger.get_log(__name__)

class Apple():
    def __init__(self, min_resolution, max_resolution):
        self.min_resolution = int(min_resolution)
        self.max_resolution = int(max_resolution)

    def _getMoivePage(self, title, year):
        movies = self._getJson(movieSearch_url, params={'q': title})

        if not movies:
            return False

        if movies.get('error', True) == True:
            log.debug('Apple could not find the movie "{}" url: {}'.format(title, movies['url']))
            return False

        if not 'results' in movies or len(movies.get('results')) < 1:
            log.debug('Apple returned no results for "{}" url: {}'.format(title, movies['url']))
            return False

        # find matching movie in results
        location = None
        for movie in movies.get('results'):
            if title.lower() == movie.get('title', '').lower() and str(year) in movie.get('releasedate', ''):
                    location = movie.get('location', None)
                    break

        # check if we found the right movie
        if not location:
            return False

        # build and get data for movie
        url = requests.compat.urljoin(moviePage_url, location + '/data/page.json')
        log.debug('Getting movie data from url: {}'.format(url))
        movieData = self._getJson(url)

        if not movieData:
            return False

        return movieData

    def _getJson(self, url, params=None):
        try:
            with requests.get(url, params=params, timeout=5) as r:
                r.raise_for_status()
                result = r.json()
                result['url'] = r.url
                return result
        except ValueError:
            log.debug('Failed to parse data returned from Apple. url: {} response:{}'.format(r.url, r.text))
            return None
        except requests.exceptions.Timeout:
            log.warning('Timed out while connecting to {}'.format(url))
            return None
        except requests.exceptions.ConnectionError as e:
            log.warning('Failed to connect to {} Error: {}'.format(url, e))
            return None
        except requests.exceptions.HTTPError as e:
            log.warning('Apple search failed for {} Error: {}'.format(url, e))
            return None
        except requests.exceptions.RequestException as e:
            log.warning('Unknown error: {}'.format(e))
            return None

    def getLinks(self, title, year):
        links =[]

        # Get movie page data
        movieData = self._getMoivePage(title, year)

        # return empty list if no movie page was found
        if not movieData:
            return links

        # Collect all trailer links
        for clip in movieData['clips']:
            if 'trailer' in clip['title'].lower():
                for item in clip['versions']['enus']['sizes']:
                    height = int(clip['versions']['enus']['sizes'][item]['height'])
                    try:
                        stdSize = int(item.replace('hd', ''))
                    except ValueError:
                        stdSize = 480

                    if '720p' in clip['versions']['enus']['sizes'][item]['srcAlt']:
                        altSize = 720
                    elif '1080p' in clip['versions']['enus']['sizes'][item]['srcAlt']:
                        altSize = 1080
                    else:
                        altSize = 480

                    # Filter based on clip height
                    if height >= self.min_resolution and height <= self.max_resolution:

                        # Parse clip into links
                        links.append({
                            'url': clip['versions']['enus']['sizes'][item]['src'],
                            'height': stdSize,
                            'source': 'apple'
                            })
                        links.append({
                            'url': clip['versions']['enus']['sizes'][item]['srcAlt'],
                            'height': altSize,
                            'source': 'apple'
                            })
        return links


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Created on Sun Oct  4 05:08:15 2020."""

import threading
import os , sys
import CSVTest
import ThinkSpeakTest
from PiPerformance import performance

#threadLock = threading.Lock()
# temp , pres , hum , pm , CH4 , CO , O3 , NH4 , CO2 = perf.data()
# csvlist = []
# thinkspeaklist = []
# csvlist.extend([pm[0],pm[1],temp,pres,hum,O3,NH4,CO,CH4,CO2])
# thinkspeaklist.extend(pm[0],pm[1],temp , pres , O3, NH4, CO, CH4)

class ThreadCSV (threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.running = True

    def run(self):
        while self.running:
            # Get lock to synchronize threads
            threadLock.acquire()
            print("Starting " + self.name)
            CSV_write()
            #Free lock to release next thread
            threadLock.release()

    def stop(self):
        self.running = False

class ThreadTS (threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.running = True

    def run(self):
        while self.running:
            # Get lock to synchronize threads
            threadLock.acquire()
            print("Starting " + self.name)
            TS_send()
            # Free lock to release next thread
            threadLock.release()

    def stop(self):
        self.running = False

def CSV_write():
    #while True:
    #if exitFlag:
    #    threadName.exit()
    temp , pres , hum , pm , CH4 , CO , O3 , NH4 , CO2 = perf.data()
    CSVTest.saveToCsv(pm[0],pm[1],temp,pres,hum,O3,NH4,CO,CH4,CO2)

def TS_send():
    #while True:
    #if exitFlag:
    #    threadName.exit()
    temp , pres , hum , pm , CH4 , CO , O3 , NH4 , CO2 = perf.data()
    ThinkSpeakTest.thingspeakconn(pm[0],pm[1],temp , pres , O3, NH4, CO, CH4)

def main():

    #threadLock = threading.Lock()
    threads = []
    # Create new threads
    thread1 = ThreadCSV(1, "Thread-CSV")
    thread2 = ThreadTS(2, "Thread-Think Speak")

    thread1.daemon = True #set this thread as a Daemon Thread
    thread2.daemon = True
    # Start new Threads
    thread1.start()
    thread2.start()

    # Add threads to thread list
    threads.append(thread1)
    threads.append(thread2)

    # Wait for all threads to complete
    for t in threads:
        t.join()
    #print("Exiting Main Thread")

if (__name__ == "__main__"):
    try:
        #exitFlag = 0
        perf = performance()
        threadLock = threading.Lock()
        main()
    except KeyboardInterrupt:
        ThreadCSV.stop()
        ThreadTS.stop()
        print('Finished')
        try:
            sys.exit(0)
        except SystemExit:
            os._exit(0)


# -*- coding: utf-8 -*-
"""Implementation of the Airfield class."""

import logging
import random
import math

import pygame

from airportgame.runway import Runway
from airportgame.utilities import vec2tuple, distance_between

class Airfield():
    """
    Airfield that contains runways.
    """
    FIELD_HEIGHT = 200
    FIELD_WIDTH = 400

    MINIMUM_DISTANCE = 40
    TRANSPARENCY_COLORKEY = (1, 2, 3)

    EDGE_BUFFER = 15

    def __init__(self, offset=(0, 0)):
        self.logger = logging.getLogger(__name__ + "." + type(self).__name__)

        # TODO: airfield size based on difficulty
        self.max_runways = 10
        self.min_runways = 3

        self.offset = offset

        # Airfield is created here
        self.reset_airfield()

    def reset_airfield(self):
        """Reset current airfield and create a new one"""
        self.logger.debug("Resetting airfield")
        self.runway_list = []

        self.create_airfield()

        self.airfield_map = pygame.Surface(
            (self.FIELD_WIDTH, self.FIELD_HEIGHT))
        self.airfield_map.fill(self.TRANSPARENCY_COLORKEY)
        self.airfield_map.set_colorkey(self.TRANSPARENCY_COLORKEY)
        self.update_map()

    def create_airfield(self):
        """
        Randomly fills the airfield with runways
        """
        number_of_runways = random.randint(self.min_runways,
                                           self.max_runways)

        # Initialize the list of runways
        runways = [0] * number_of_runways

        length = 0
        for i in range(number_of_runways):

            # Make sure that there is at least one runway of each length
            if i <= 2:
                length += 1
            else:
                length = random.randint(1, 3)

            # Get the full length of the runway.
            runway_length = Runway.RUNWAY_LENGTH_ENUM[length]

            start_point_found = False

            while not start_point_found:
                s_x, s_y = self.get_random_point_inside_airfield()

                start_point_found = self.compare_points((s_x, s_y), i)

            start = (s_x, s_y)

            end_point_found = False

            # Counter to prevent infinite loops
            temp = 0

            while not end_point_found:

                temp += 1

                angle = random.random() * math.pi * 2.0
                e_x = math.cos(angle) * runway_length
                e_y = math.sin(angle) * runway_length

                # Make sure the endpoints are inside the airfield
                if s_x + e_x > self.FIELD_WIDTH or s_x + e_x < 0:
                    e_x = s_x - e_x
                else:
                    e_x = s_x + e_x
                if s_y + e_y > self.FIELD_HEIGHT or s_y + e_y < 0:
                    e_y = s_y - e_y
                else:
                    e_y = s_y + e_y

                e_x = int(e_x)
                e_y = int(e_y)

                end = (e_x, e_y)
                end_point_found = (self.compare_points(end, i) and
                                   self.point_inside_airfield(end))

                if temp == 1000:
                    # Just use this one if we actually end up here
                    self.logger.warning(
                        "Unoptimal runway end point for runway #%d !", (i + 1))
                    end_point_found = True

            # start point should be to the left of end:
            if e_x < s_x:
                start, end = end, start

            runways[i] = (start, end)

            if not self.point_inside_airfield(start):
                self.logger.warning("Runway %d start outside airfield!", i+1)
            if not self.point_inside_airfield(end):
                self.logger.warning("Runway %d end outside airfield!", i+1)

            new_runway = Runway(self.add_offset_to_tuple(start),
                                self.add_offset_to_tuple(end), i+1, length)
            self.runway_list.append(new_runway)

        return

    def get_runways(self):
        """Return a list of the runways on the airfield.

        Returns:
            list -- A list of runways.
        """

        return self.runway_list

    def compare_points(self, point, index):
        """
        Checks that the starting and ending points of all other runways are far enough
        of the one being tested.
        """
        if index == 0:
            return True

        for runway_i in range(index):
            runway = self.runway_list[runway_i]
            start, end = runway.get_start_and_end_pos()
            start = self.remove_offset_from_tuple(start)
            end = self.remove_offset_from_tuple(end)

            if (distance_between(point, start) < self.MINIMUM_DISTANCE or
                    distance_between(point, end) < self.MINIMUM_DISTANCE):
                return False
            if self.dist_to_segment(start, end, point) < (self.MINIMUM_DISTANCE):
                return False
        return True

    def update_map(self):
        """Draws and paints the runways on the airfield map."""

        for runway in self.runway_list:
            runway.draw(self.airfield_map, self.get_offset())

        for runway in self.runway_list:
            runway.paint(self.airfield_map, self.get_offset())

    def get_airfield_map(self):
        """Return the map of the airfield.

        Returns:
            Surface -- The map of the airfield.
        """

        return self.airfield_map

    def draw(self, screen):
        """Draws the airfield.

        Arguments:
            screen {Surface} -- Surface to draw on.
        """

        screen.blit(self.airfield_map, self.offset)

    def get_offset(self):
        """Return the offset of the airfield.

        Returns:
            Vector2 -- Offset
        """

        return pygame.math.Vector2(self.offset)

    def add_offset_to_tuple(self, point):
        """Adds elementwise the given point tuple to the offset.

        Arguments:
            point {tuple} -- A tuple of two numbers.

        Returns:
            x -- New x coordinate
            y -- New y coordinate
        """

        offset_x, offset_y = self.offset
        return (point[0] + offset_x, point[1] + offset_y)

    def remove_offset_from_tuple(self, point):
        """Subtract elementwise the offset from the given point tuple.

        Arguments:
            point {tuple} -- A tuple of two numbers.

        Returns:
            x -- New x coordinate
            y -- New y coordinate
        """
        offset_x, offset_y = self.offset
        return (point[0] - offset_x, point[1] - offset_y)

    def point_inside_airfield(self, point, use_buffer=True):
        """Returns true if the given point is inside the airfield.

        Arguments:
            point {tuple} -- Coordinates of a point.

        Keyword Arguments:
            use_buffer {bool} -- Whether EDGE_BUFFER should be used.
                (default: {True})

        Returns:
            bool -- True if point is inside the airfield.
        """

        buffer = self.EDGE_BUFFER if use_buffer else 0
        is_inside = (
            (buffer <= point[0] <= self.FIELD_WIDTH - buffer) and
            (buffer <= point[1] <= self.FIELD_HEIGHT - buffer)
        )
        return is_inside

    def get_random_point_inside_airfield(self):
        """Pick a random point inside the airfield.

        Returns:
            int -- x-coordinate
            int -- y-coordinate
        """

        x = random.randint(
            self.EDGE_BUFFER, self.FIELD_WIDTH - self.EDGE_BUFFER)
        y = random.randint(
            self.EDGE_BUFFER, self.FIELD_HEIGHT - self.EDGE_BUFFER)
        return x, y

    def dist_to_segment(self, start, end, point):
        """Return the shortest distance between given segment a point.

        Arguments:
            start {Vector2} -- Start point of segment
            end {Vector2} -- End point of segment
            point {Vector2} -- Point

        Returns:
            float -- Shortest distance between segment and point.
        """

        # https://stackoverflow.com/a/1501725
        segment_length = distance_between(start, end)
        if segment_length == 0:
            return distance_between(start, point)
        try:
            vec_a = point - start
            vec_b = end - start
        except TypeError:
            start = pygame.math.Vector2(start)
            vec_a = pygame.math.Vector2(point) - start
            vec_b = pygame.math.Vector2(end) - start
        projection = vec_a.dot(vec_b) / (segment_length ** 2)
        t = max(0, min(1, projection))
        projection_point = start + t * vec_b
        return distance_between(point, vec2tuple(projection_point))


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

"""
@File    : T3.py
@Author  : wenhao
@Time    : 2023/4/9 10:27
@LC      :
"""
import bisect
from typing import List
from collections import Counter
from bisect import bisect_left

# 最大化最小值 == 二分答案
# 二分 mx
# 尽量多的选下标对 使得选出来的对数 >= p
# 如果下标不影响答案 那么可以排序
# 贪心 如果前两个数可以选 那么必选
#

class Solution:
    def minimizeMax(self, nums: List[int], p: int) -> int:
        nums.sort()
        # 优化 check 函数
        # 贪心的思想 相邻的元素选或者不选
        def check(mx: int) -> bool:
            cnt = i = 0
            while i < len(nums) - 1:
                if nums[i + 1] - nums[i] <= mx:  # 可以选
                    cnt += 1
                    i += 2
                else:  # 没法选 跳过
                    i += 1
            return cnt >= p

        # 闭区间模板
        l, r = 0, nums[-1] - nums[0]
        while l <= r:
            m = l + (r - l) // 2
            if check(m):
                r = m - 1
            else:
                l = m + 1
        return l

        # 使用 库函数 版本
        # nums.sort()
        # def check(mx: int) -> int:
        #     cnt = i = 0
        #     while i < len(nums) - 1:
        #         if nums[i + 1] - nums[i] <= mx:  # 可以选
        #             cnt += 1
        #             i += 2
        #         else:  # 没法选 跳过
        #             i += 1
        #     return cnt
        #
        # return bisect_left(range(nums[-1] - nums[0]), p, key=check)


from collections import defaultdict
import pandas as pd
import datetime
from lode.utilities.util import parse_date
from itertools import izip

def create_date_limited_sql(master_table, dates=None,
                            begin_date=None, end_date=None,
                            date_col="trading_date", range_break="Year"):
    """
    This is the initialisation function which takes into account the separation
    of the tables on a year by year basis in the Database (due to memory
    considerations). It is called with either the dates keyword or both the
    begin_date and end_date keywords in order to change the behaviour apparent.
    These are ensured to exist by the check_required_range function which has
    been previously run. Will return a list of queries which may then be
    modified as needed to construct the full custom queries desired

    Parameters:
    -----------
    master_table: The master table to query
    dates: A string or iterable object of dates to return
    begin_date: The first date in a range of dates to return
    end_date: The last date in a range of dates to return
    date_col: What column the dates are contained in
    range_break: A modification for performance purposes, default set to Year
                 but setting to 'Month' may result in reduced memory usage.

    Returns:
    --------
    all_queries: A list of SQL queries contained as strings
    """

    all_queries = []
    # If passing a selection of date objects
    if dates:
        if hasattr(dates, '__iter__'):
            return list(singular_sql_dates(master_table, dates, date_col))

        else:
            dt = parse_date(dates)
            return ["""SELECT * FROM %s_%s WHERE %s='%s'""" % (
                master_table, dt.year, date_col, dt.strftime('%d-%m-%Y'))]

    # Work with Date Ranges
    else:
        if range_break == "Year":
            return list(yearly_sql_dates(begin_date, end_date, master_table,
                                         date_col))

        elif range_break == "Month":
            return list(monthly_sql_dates(begin_date, end_date, master_table,
                                          date_col))

        else:
            raise ValueError("""Range Breaks for %s have not been
                                implemented, try 'Year'""" % range_break)

    return all_queries

def singular_sql_dates(master_table, dates, date_col):
    """
    For a list of dates this will create a series of SQL queries with the
    basic format SELECT * FROM table where dates in date_col. It has a little
    bit of magic in it to handle the fact that tables are sharded into smaller
    tables, often on a year by year basis.

    It also handles parsing dates if needed (although datetime objects may be
    passed to the method).

    Parameters:
    -----------
    master_table: The root database table to construct the query for, e.g. for
                  nodal_prices_2012  this would just simply be nodal_prices
    dates: Either a singluar date string or object or a list of date strings
           and objects to construct the SQL queries for. These may be in any
           order for any number of dates
    date_col: The column name for the dates in the SQL database

    Returns:
    --------
    SQL: This is a generator expression where each iteration is a separate
         SQL query for each year with all of the dates from that year contained
         as a selection query

    """

    dts = [parse_date(x) for x in dates]

    # Map the specific dates to the specific years isomg a default dict
    years_dict = defaultdict(list)
    for dt in dts:
        years_dict[dt.year].append(dt)

    # Iterate through each of the years and add the trading dates belonging
    # to each query to a specific query, yield this SQL string as a generator
    for year in years_dict:
        # Set up a custom string and then place it inside brackets for
        # Use in the query
        strings = join_date_strings(years_dict[year])
        date_string = "('%s')" % strings

        # The base query string to use
        query_string = """ SELECT * FROM %s_%s WHERE %s in %s"""

        # Substitute the values into the string
        SQL = query_string % (master_table, year, date_col, date_string)

        yield SQL

def yearly_sql_dates(begin_date, end_date, mtable, date_col,
                     df="%d-%m-%Y"):
    """
    Create full year SQL dates which ar every useful if a range goes over
    the yearly amount. For example, if the requested date range is
    20/12/2014 to 20/02/2015 then this requires querying both the 2014 and
    the 2015 table. This function creates two separate queries for each of
    the tables which allows this to happen behind the scenes. Should only
    be called if the yearly overlap is different.

    Note that this is a kind of a hacky use of a generator to create the
    SQL queries desired but this is due to the desire to use smaller table
    sizes on RAM limited machines. For example, a year of data is often 1GB
    of data and as there are 10+ years this exceeds the RAM available on an
    8GB machine easily.

    Parameters:
    -----------
    begin_date: String or datetime object of the first date to consider
    end_date: String or datetime object of the last date to consider
    mtable: What table to query (master)
    date_col: The column containing the trading dates
    df: The date format to use if needed

    Returns:
    --------
    query_string: A string containing the appropriate date SQL query as a base

    """
    # Parse the dates as they're probably strings
    begin_date = parse_date(begin_date)
    end_date = parse_date(end_date)

    # Set up dummy strings
    jan1, dec31 = "01-01-%s", "31-01-%s"
    query_string = """SELECT * FROM %s_%s WHERE %s BETWEEN '%s' AND '%s'"""

    if begin_date.year == end_date.year:
        fd, ld = begin_date.strftime(df), end_date.strftime(df)
        yield query_string % (mtable, begin_date.year, date_col, fd, ld)

    else:

        # Return the first string
        # From the beginning date to the 31st of December
        fd, ld = begin_date.strftime(df), dec31 % begin_date.year
        yield query_string % (mtable, begin_date.year, date_col, fd, ld)

        # Yield the intermediate dates if any
        # For example, if we are "12/12/2013" and "02/04/2015" we would
        # still want  all of the dates in 2014 to be returned.
        years = range(begin_date.year + 1, end_date.year)
        if len(years) > 0:
            for year in years:
                fd, ld = jan1 % year, dec31 % year
                yield query_string % (mtable, year, date_col, fd, ld)

        # Yield the last date
        # This is from the 1st of January of that year to the ending date
        if end_date.year != begin_date.year:
            fd, ld = jan1 % end_date.year, end_date.strftime(df)
            yield query_string % (mtable, end_date.year, date_col, fd, ld)

def monthly_sql_dates(begin_date, end_date, mtable, date_col, df='%d-%m-%Y'):
    """
    Returns queries which have been isolated on a per month basis which can
    then be fed into a DataFrame.

    This is a modified version of the yearly SQL dates return function which
    has been implemented due to memory considerations. There is a cut off
    where the additional overhead from running more queries is less than the
    overhead of holding large datasets in memory and coercing these to Pandas
    DataFrames. By using a generator expressions we are able to overcome this
    and keep total RAM usage reduced as the garbage collection runs.

    Parameters:
    -----------
    begin_date: The first date as either a datetime object or string
    end_date: The last date as either a datetime object or string
    mtable: The master table to query from
    date_col: What column contains date information
    df: What date format to use

    Returns:
    --------
    query_string: The SQL query which we may then modify

    """
    query_string = """SELECT * FROM %s_%s WHERE %s BETWEEN '%s' AND '%s'"""

    # Parse the dates as they're probably strings
    begin_date = parse_date(begin_date)
    end_date = parse_date(end_date)

    # Add an additional day in order to get the next months
    month_range = list(pd.date_range(begin_date, end_date, freq="M"))
    month_range_p1 = [x + datetime.timedelta(days=1) for x in
                      month_range]

    if month_range[-1] == end_date:
        end_dates = month_range
    else:
        end_dates = month_range + [end_date]

    # Can I do this functionally? I don't want to mutate the data
    # structures, currently copying the list
    begin_dates = [begin_date] + month_range_p1

    for s, e in izip(begin_dates, end_dates):
        beg, end = s.strftime(df), e.strftime(df)

        yield query_string % (mtable, s.year, date_col, beg, end)

def join_date_strings(dates, separator="','", df="%d-%m-%Y"):
    """
    Join a list of dates together in a specific string time format separated
    by a custom string. In many cases this is used to get it into the SQL
    format string needed
    """
    return separator.join([x.strftime(df) for x in dates])

def add_equality_constraint(column, values):

    if not hasattr(values, '__iter__'):
        return add_single_selection_constraint(column, values)
    else:
        return add_multiple_selection_constraint(column, values)

def add_exclusion_constraint(column, values):

    if not hasattr(values, '__iter__'):
        return add_single_exclusion_constraint(column, values)
    else:
        return add_multiple_exclusion_constraint(column, values)

def add_minimum_constraint(column, value):
    return """ AND %s >= '%s'""" % (column, value)

def add_maximum_constraint(column, value):
    return """ AND %s <= '%s'""" % (column, value)

def add_range_constraint(column, begin, end):
    return """ AND %s BETWEEN '%s' AND '%s'""" % (column, begin, end)

def add_single_selection_constraint(column, value):
    return """ AND %s='%s'""" % (column, value)

def add_multiple_selection_constraint(column, values):
    joined = "','".join(values)
    jvalues = "('%s')" % joined
    return """ AND %s IN %s""" % (column, jvalues)

def add_single_exclusion_constraint(column, value):
    return """ AND %s!='%s'""" % (column, value)

def add_multiple_exclusion_constraint(column, values):
    joined = "','".join(values)
    jvalues = "('%s')" % joined
    return """ AND %s NOT IN %s""" % (column, jvalues)

if __name__ == '__main__':
    pass


# MS MARCO Document: Script for plotting leaderboard over time scatter plots

import datetime
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
plt.switch_backend('agg')

import pandas as pd

df = pd.read_csv('../leaderboard/leaderboard.csv', parse_dates=['date'])

# Plot all the runs
ax = df.plot(x='date',y='MRR@100 (Eval)',marker='o',linestyle='none',label='Submission')

# Overlay all SOTA runs, in red.
sota = df[df['Unnamed: 2'] == '🏆']
sota.plot(ax=ax, x='date',y='MRR@100 (Eval)',marker='o',color = 'red',linestyle='none',label='SOTA')

# Guide to formatting date ticks
# https://matplotlib.org/3.1.1/gallery/text_labels_and_annotations/date.html
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.set_xlim([datetime.date(2020, 8, 1), datetime.date(2021, 3, 1)])

plt.title('MS MARCO Document Leaderboard')
plt.xlabel('Date')
plt.ylabel('MRR@100')

plt.savefig('leaderboard.pdf', bbox_inches='tight', format='pdf')


'''

Problem 844 | Backspace String Compare
https://leetcode.com/problems/backspace-string-compare/

'''

class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        s_stack, t_stack = [], []

        for i in s:
            if i == '#':
                if len(s_stack):
                    s_stack.pop(-1)
            else:
                s_stack.append(i)
        s = "".join(s_stack)

        for i in t:
            if i == '#':
                if len(t_stack):
                    t_stack.pop(-1)
            else:
                t_stack.append(i)
        t = "".join(t_stack)

        if s == t:
            return True
        else:
            return False

Data Structures/Stack/Backspace String Compare.py


class Solution:
    def equalPairs(self, grid):
        element_map = {}
        result = 0
        for row in grid:
            row_element = ",".join(map(str, row))
            element_map[row_element] = element_map.get(row_element, 0) + 1
        # prepare col_element
        col_elements = []
        for c in range(len(grid[0])):  # loop through column first
            col_values = []
            for r in range(len(grid)):
                col_values.append(grid[r][c])
            col_element = ",".join(map(str, col_values))
            col_elements.append(col_element)
        # loop through col_elements
        for e in col_elements:
            if str(e) in element_map:
                result += element_map[str(e)]
        return result

2352. Equal Row and Column Pairs/main.py


import cv2
import os
import glob
import argparse
import time

parser = argparse.ArgumentParser()
parser.add_argument("--video_dir",    type=str,
                    help="Dataset directory", default='/home/park/0808_capture/video/trade_tower/')
parser.add_argument("--video_result_dir", type=str,
                    help="Test result save directory", default='/home/park/0808_capture/video/trade_tower/results/')

args = parser.parse_args()

if __name__ == '__main__':
    video_list = os.path.join(args.video_dir, '*.mp4')
    video_list = glob.glob(video_list)

    os.makedirs(args.video_result_dir, exist_ok=True)

    for video_idx, video_file in enumerate(video_list):
        video_idx += 1

        if os.path.isfile(video_file):
            cap = cv2.VideoCapture(video_file)
        else:
            raise('cannot find file : {0}'.format(video_file))

        # Get camera FPS
        fps = cap.get(cv2.CAP_PROP_FPS)
        fps = 30
        # Frame width size
        frameWidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        # Frame height size
        frameHeight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        frame_size = (frameWidth, frameHeight)
        print('frame_size={0}'.format(frame_size))

        frame_idx = 0
        while True:
            print(frame_idx)
            retval, frame = cap.read()

            frame_idx+=1

            if not(retval):
                break
            if frame_idx % 50 == 0:
                cv2.imwrite(args.video_result_dir + '_' + str(video_idx) + '_' + str(frame_idx) + '.jpg', frame)

        if cap.isOpened():
            cap.release()


import tkinter as tk
from tkinter import *

class Calculator(tk.Frame):
    def __init__(self, **kw):
        super().__init__(**kw)
        self.place()

        self.create_frame_and_listbox()
        self.create_button()

        self.expression = ''

    def choose(self, char):
        self.expression += str(char)
        self.display_calculation.delete(1.0, 'end')
        self.display_calculation.insert(1.0, self.expression)

    def compute(self):
        try:
            self.total = str(eval(self.expression))
            self.display_calculation.delete(1.0, 'end')
            self.display_calculation.insert(1.0, self.total)
        except:
            self.clear()
            self.display_calculation.insert(1.0, 'Error')

    def clear(self):
        self.expression = ''
        self.display_calculation.delete(1.0, 'end')
        self.display_calculation.insert(1.0, 0)

    def create_frame_and_listbox(self):
        self.calculation_frame = Frame(root, width=235, height=120, bg="Black", bd=10, relief=SUNKEN)
        self.calculation_frame.place(x=10, y=0)

        self.display_calculation = Text(self.calculation_frame, bg='Black', fg='White',
                                        font=('Courier', 15, 'bold'))
        self.display_calculation.place(x=0, y=0, width=215, height=100)
        self.display_calculation.insert(1.0, 0)

    def create_button(self):
        self.button_division = Button(root, text='÷', font=('Courier', 15, 'bold'), bg='orange3',
                                      fg="White", width=3, command=lambda: self.choose('/'))
        self.button_division.place(x=200, y=130)
        self.button_division.config(activebackground="orange4", relief=RAISED)

        self.button_multiplication = Button(root, text='x', font=('Courier', 15, 'bold'),
                                            bg='orange3', fg="White", width=3,
                                            command=lambda: self.choose('*'))
        self.button_multiplication.place(x=200, y=190)
        self.button_multiplication.config(activebackground="orange4", relief=RAISED)

        self.button_soustraction = Button(root, text='-', font=('Courier', 15, 'bold'), bg='orange3',
                                          fg="White", width=3,
                                          command=lambda: self.choose('-'))
        self.button_soustraction.place(x=200, y=250)
        self.button_soustraction.config(activebackground="orange4", relief=RAISED)

        self.button_addition = Button(root, text='+', font=('Courier', 15, 'bold'), bg='orange3',
                                      fg="White", width=3, command=lambda: self.choose('+'))
        self.button_addition.place(x=200, y=310)
        self.button_addition.config(activebackground="orange4", relief=RAISED)

        self.button_egal = Button(root, text='=', font=('Courier', 15, 'bold'), bg='orange3',
                                  fg="White", width=3, command=self.compute)
        self.button_egal.place(x=200, y=370)
        self.button_egal.config(activebackground="orange4", relief=RAISED)

        self.button_zero = Button(root, text='0', font=('Courier', 15, 'bold'), bg='gray15',
                                  fg="White", width=8,
                                  command=lambda: self.choose(0))
        self.button_zero.place(x=10, y=370)
        self.button_zero.config(activebackground="gray50", relief=RAISED)

        self.button_point = Button(root, text='.', font=('Courier', 15, 'bold'), bg='gray15',
                                   fg="White", width=3, command=lambda: self.choose('.'))
        self.button_point.place(x=130, y=370)
        self.button_point.config(activebackground="gray50", relief=RAISED)

        self.button_one = Button(root, text='1', font=('Courier', 15, 'bold'), bg='gray15',
                                 fg="White", width=3, command=lambda: self.choose(1))
        self.button_one.place(x=10, y=310)
        self.button_one.config(activebackground="gray50", relief=RAISED)

        self.button_two = Button(root, text='2', font=('Courier', 15, 'bold'), bg='gray15',
                                 fg="White", width=3, command=lambda: self.choose(2))
        self.button_two.place(x=70, y=310)
        self.button_two.config(activebackground="gray50", relief=RAISED)

        self.button_three = Button(root, text='3', font=('Courier', 15, 'bold'), bg='gray15',
                                   fg="White", width=3, command=lambda: self.choose(3))
        self.button_three.place(x=130, y=310)
        self.button_three.config(activebackground="gray50", relief=RAISED)

        self.button_four = Button(root, text='4', font=('Courier', 15, 'bold'), bg='gray15',
                                  fg="White", width=3, command=lambda: self.choose(4))
        self.button_four.place(x=10, y=250)
        self.button_four.config(activebackground="gray50", relief=RAISED)

        self.button_five = Button(root, text='5', font=('Courier', 15, 'bold'), bg='gray15',
                                  fg="White", width=3, command=lambda: self.choose(5))
        self.button_five.place(x=70, y=250)
        self.button_five.config(activebackground="gray50", relief=RAISED)

        self.button_six = Button(root, text='6', font=('Courier', 15, 'bold'), bg='gray15',
                                 fg="White", width=3, command=lambda: self.choose(6))
        self.button_six.place(x=130, y=250)
        self.button_six.config(activebackground="gray50", relief=RAISED)

        self.button_seven = Button(root, text='7', font=('Courier', 15, 'bold'), bg='gray15',
                                   fg="White", width=3, command=lambda: self.choose(7))
        self.button_seven.place(x=10, y=190)
        self.button_seven.config(activebackground="gray50", relief=RAISED)

        self.button_eight = Button(root, text='8', font=('Courier', 15, 'bold'), bg='gray15',
                                   fg="White", width=3, command=lambda: self.choose(8))
        self.button_eight.place(x=70, y=190)
        self.button_eight.config(activebackground="gray50", relief=RAISED)

        self.button_nine = Button(root, text='9', font=('Courier', 15, 'bold'), bg='gray15',
                                  fg="White", width=3, command=lambda: self.choose(9))
        self.button_nine.place(x=130, y=190)
        self.button_nine.config(activebackground="gray50", relief=RAISED)

        self.button_clear = Button(root, text='C', font=('Courier', 15, 'bold'), bg='gray60',
                                   fg="Black", width=3, command=self.clear)
        self.button_clear.place(x=10, y=130)
        self.button_clear.config(activebackground="gray75", relief=RAISED)

        self.button_plus_or_less = Button(root, text='+/-', font=('Courier', 15, 'bold'), bg='gray60',
                                          fg="Black", width=3, command=lambda: self.choose('-'))
        self.button_plus_or_less.place(x=70, y=130)
        self.button_plus_or_less.config(activebackground="gray75", relief=RAISED)

        self.button_modulo = Button(root, text='%', font=('Courier', 15, 'bold'), bg='gray60',
                                    fg="Black", width=3, command=lambda: self.choose('%'))
        self.button_modulo.place(x=130, y=130)
        self.button_modulo.config(activebackground="gray75", relief=RAISED)

root = Tk()
root.geometry("255x420+355+30")
root.resizable(False, False)
root.title('Simple Calculator')
root.iconbitmap('icon.ico')
root.config(background="black")

app = Calculator(master=root)
app.mainloop()


'''
Faça um programa que leia um vetor de 10 números. Leia um número x. Conte os múltiplos de um número inteiro x num
vetor e mostre-os na tela.
'''

vetor = []
multiplos = []
dicionario = {0:'primeiro', 1:'segundo', 2:'terceiro', 3:'quarto', 4:'quinto',
5:'sexto', 6:'sétimo', 7:'oitavo', 8:'nono', 9:'décimo'}

while len(vetor) < 10:
    num = int(input(f'Digite o {dicionario[len(vetor)]} número: '))
    vetor.append(num)

num_x = int(input('Digite um número x: '))

for elemento in vetor:
    if elemento%num_x == 0:
        multiplos.append(elemento)

if len(multiplos) == 0:
    print(f'Dentro do vetor {vetor}, não há múltiplos de {num_x}.')
else:
    print(f'Dentro do vetor {vetor}, os múltiplos de {num_x} são {multiplos}.')


class Solution(object):
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        #time complexity = 0(N+K) = O(N)
        #space complexity = O(K) = O(N)

        # O(k) space, k = unique numbers in list
        num_count = []
        majority_items = []

        # O(N) runtime
        for i in nums:
            if (i in num_count):
                num_count[i] += 1
            else:
                num_count[i] = 1

        at_least = len(nums) / 3

        result = []

        #O(k) runtime
        for k in num_count:
            if (num_count[k] > at_least):
                result.append(k)

        return result


def accept_one_row():
    input_str = input().strip()
    input_list = input_str.split()
    return input_list

def convert_list_mem_to_int(target_list):
    return list(map(int, target_list))

if __name__ == "__main__":
    score_list = accept_one_row()
    score_list = convert_list_mem_to_int(score_list)
    N, X = score_list
    circle_and_cross = input().strip()
    for s in circle_and_cross:
        if s == "o":
            X += 1
        elif s == "x" and X >= 1:
            X -= 1
    print(X)


"""Import the compiled Python for .Net module"""
import clr
import sys

print()
print ('clr version = {}'.format(str(clr.__version__)))

"""Import the Keysight automated test app remote library DLL"""
sys.path.append(r'C:\ProgramData\Keysight\DigitalTestApps\Remote Toolkit\Version 6.3\Tools')
clr.AddReference("Keysight.DigitalTestApps.Framework.Remote")
import Keysight.DigitalTestApps.Framework.Remote as KtRemote
"""Connect to the automated test application running on the scope
This will wait for the application to be fully launched and ready
before proceeding"""
scopeIpAddress = "127.0.0.1"
remoteObj = KtRemote.RemoteAteUtilities.GetRemoteAte(scopeIpAddress)
remoteApp = KtRemote.IRemoteAte(remoteObj)

print (remoteApp.ApplicationName)


import math

def get_divisors(n):
    ret = set()
    for d in range(1, int(math.ceil(math.sqrt(n)))):
            if n % d == 0:
                ret.add(d)
                ret.add(n//d)
    return ret

def check_slice(start, end):
    size = (end[0] - start[0] + 1) * (end[1] - start[1] + 1)
    if size > H:
        return False

    mush = 0
    tom = 0
    for r in range(start[0], end[0]+1):
        for c in range(start[1], end[1]+1):
            if pizza[r][c] == 0:
                mush += 1
            else:
                tom += 1
            if mush > L and tom > L:
                return True
    return False

def get_slices(r, c):
    ret = []
    return ret

P = input().split(' ')

R = int(P[0])
C = int(P[1])
L = int(P[2])
H = int(P[3])

pizza = []
for i in range(R):
    line = input()
    pizza.append(list(map(lambda c: 0 if c == 'M' else 1, line)))
#print(pizza)

divs = get_divisors(H)
print(divs)

for r in range(R):
    for c in range(C):
        slices = get_slices(r, c)


familia = {
    'pai': 'Fulano de Tal',
    'mae': 'Beltrana de Tal',
    'filho': 'Celtrano de Tal',
    'filha': 'Deltrana de Tal',
}

print(familia)

copia_familia = familia.copy()

print(f"Compia da Familia: {copia_familia}")

itens = familia.items()

print(f"Itens: {itens}")

for item in itens:
    print(item)

chaves = familia.keys

print(f"Chaves: {chaves}")

for chave in chaves:
    print(chave)

valores = familia.values

print(f"Chaves: {valores}")

for valor in valores:
    print(valor)


'''

Problem 844 | Backspace String Compare
https://leetcode.com/problems/backspace-string-compare/

'''

class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        def function(seq):
            skip = 0
            for i in reversed(seq):
                if i == '#':
                    skip += 1
                elif skip:
                    skip -= 1
                else:
                    yield i
        return all(x == y for x, y in itertools.zip_longest(function(s), function(t)))

Algorithms/Two Pointers/Backspace String Compare.py


#!/usr/bin/python3
from brownie import CallMeChallenge
from scripts.deploy import deploy
from scripts.helpful_scripts import get_account
from colorama import Fore

# * colours
green = Fore.GREEN
red = Fore.RED
blue = Fore.BLUE
magenta = Fore.MAGENTA
reset = Fore.RESET

def print_colour(target, solved=False):
    if solved:
        print(f"{blue}Is complete: {green}{target.isComplete()}{reset}")
    else:
        print(f"{blue}Is complete: {red}{target.isComplete()}{reset}")

def hack(contract_address=None, attacker=None):
    if not contract_address:
        target, _ = deploy()
        _, attacker = get_account()
    else:
        target = CallMeChallenge.at(contract_address)

    # print(target.address)
    print_colour(target, target.isComplete())

    tx = target.callme({"from": attacker})
    tx.wait(1)

    # print(f"{blue}Is complete: {green}{target.isComplete()}{reset}")
    print_colour(target, target.isComplete())

    assert target.isComplete() == True

def main(contract_address=None):
    if contract_address:
        hack(contract_address, get_account())
    else:
        hack()

if __name__ == "__main__":
    main()


import json
from pprint import pprint
import requests
import logbook
from log_book import init_logger

logger = logbook.Logger(__file__)

def main():
    init_logger('movie-app.log')
    logbook.info("Starting the omdb search app...")

    logbook.debug("Getting user's input...")
    movie_name = get_user_input()

    logbook.debug("Loading '{0}' data...".format(movie_name))
    movie_data = load_movie_data(movie_name)

    logbook.debug("Displaying Awards...".format(movie_name))
    display_awards(movie_data, movie_name)

    logbook.debug("Displaying Ratings...".format(movie_name))
    displays_ratings(movie_data)

def get_user_input():
    user_input = input('Movie name: ')
    return user_input

def load_movie_data(movie_name):
    request = requests.get('http://www.omdbapi.com/?apikey=3e6f7dd7&t={}'.format(movie_name))
    json_result = json.loads(request.text)
    return json_result

def display_awards(movie_data, movie_name):
    print("{}'s Awards: {}".format(movie_name, movie_data['Awards']))

def displays_ratings(movie_data):
    for rating in movie_data['Ratings']:
        display_rating(rating)

def display_rating(rating):
    value = rating['Value']
    value = parse_value(value)
    print(f"{rating['Source']} - {value}")

def parse_value(value: str):
    logbook.debug("Parsing value '{0}'...".format(value))
    if value.endswith('%'):
        value = value.replace('%','')
        return '{}/10'.format(int(value) / 10)
    elif value.endswith('100'):
        (value, _) = value.split('/')
        return '{}/10'.format(int(value) / 10)
    else:
        (value, _) = value.split('/')
        return '{}/10'.format(float(value) * 1.0)

if __name__ == '__main__':
    main()


# Helper functions for stochastic raytracer

import numpy as np
import pickle
import matplotlib.pyplot as plt
from scipy import interpolate
from sklearn import preprocessing

# Create a linear interpolant in each of the x, y, z directions
def create_interpolant(xyz, g):
    fx = interpolate.RegularGridInterpolator(xyz, g[0])
    fy = interpolate.RegularGridInterpolator(xyz, g[1])
    fz = interpolate.RegularGridInterpolator(xyz, g[2])
    return (fx, fy, fz)

#
def get_sdf_components(dict_name, xyz, space_subdivs):
    with open(dict_name, 'rb') as dictionary_file:
        r = pickle.load(dictionary_file)

    # Compute interpolant of the sdf
    phi = interpolate.RegularGridInterpolator(xyz, r)

    # Compute gradient (2/space_subdivs corresponds to the step size since r is space_subdivs subdivisions over an interval of 2)
    g = np.gradient(r, 2/space_subdivs)

    # Interpolant of gradient in each of x,y,z directions
    fx, fy, fz  = create_interpolant(xyz, g)

    return (phi, fx, fy, fz)

# Closest point operator
def cp(points, phi, fx, fy, fz):
    """
    points - a point in R^3 as a 3 ndarray, or multiple points as a 3xN ndarray
    phi    - interpolant of the sdf given by the array
    fu     - interpolant of gradient in the direction of u for u in [x,y,z]

    Returns the closest point on the level set 0
    """
    phi_points  = phi(points).reshape(len(points), 1)       # reshaping to (N, 1) for broadcasting with points_grad
    px, py, pz  = fx(points), fy(points), fz(points)        # the gradient of the generated points in each direction
    points_grad = np.transpose(np.array([px, py, pz]))
    closest     = points - phi_points * points_grad
    return closest

# Find the points traced on the plane when tracing back to camera
def get_points_on_plane(cam, closest, k, n, D):
    """
    See report for justification as to why this works!

    cam     - location of camera
    closest - array of the closest points
    k       - vector normal to plane
    n       - normalized vector normal to plane
    D       - scalar parameter of plane
    """
    b = preprocessing.normalize(cam - closest)    # Normalized vectors in direction of closest points to camera
    cos = b @ (-n)                                # Cosine of the angle between n (in other direction) and b, simply the dot product since they are unit vectors
    d_plane = (closest @ k + D)/np.linalg.norm(k) # Distance from point to plane that is the screen (using standard point to plane formula)
    scale   = (d_plane/cos).reshape(-1,1)         # Scale to find the vector from point to plane via vector to camera
    points_plane = closest + scale * b            # Points on the
    return points_plane, scale

# Rotate the screen such that the camera vector is along x, then remove the x dimension
def get_rotation_matrix(k, cam):
    """
    Note: This only works if the plane passes through the z-axis. It can be generalized be changing the value of u.

    k            - vector normal to plane
    cam          - position of camera

    Returns A_mat, the inverse of T_mat, and T_mat, which brings the camera to the x-axis.
    """
    d_cam = np.linalg.norm(cam)           # Distance from origin to camera
    D_alt = - k @ cam                     # Alternate D that create the plane Ax + By + Cz + D_alt = 0 and cam lies on the plane
    u     = np.array([0, 0, -D_alt/k[2]]) # A point on this new plane (see notes above)
    v     = u - cam                       # A vector perpendicular to cam
    beta  = v*(d_cam/np.linalg.norm(v))   # Renormalize to have magnitude of cam
    gamma = np.cross(cam, beta)/d_cam     # Another vector parallel to both cam and beta with magnitude of cam

    A_mat    = np.transpose(np.array([cam, beta, gamma]))/d_cam # The matrix A which transform the standard coordinates with length d_cam to (cam, beta, gamma)
    T_mat    = np.linalg.inv(A_mat)                             # The transform T as a matrix
    return (A_mat, T_mat)

# Perform the rotation
def rotate_and_kill_x(T_mat, points_plane):
    """
    T_mat        - the transformation (rotation) matrix
    points_plane - the points on the plane
    """
    rotated  = np.transpose(T_mat @ np.transpose(points_plane)) # Apply rotation T to align screen to x-axis
    scrn     = rotated[:,1:]                                    # Kill off x dimension
    return scrn

# Get positions of unfilled pixels on the screen
def get_not_filled_positions(not_filled, n_x, n_y):
    count_not_filled     = np.sum(not_filled)
    not_filled_pos       = np.zeros((count_not_filled, 2))  # list of unfilled pixels by position

    not_filled_counter   = 0                                # counter for not filled
    for it_x in range(n_x):
        for it_y in range(n_y):
            if not_filled[it_x][it_y] == 1:
                not_filled_pos[not_filled_counter] = np.array([it_x, it_y])
                not_filled_counter += 1
    return not_filled_pos

# Get the direction in physical space of vectors from camera to missing pixels (this should be working)
def get_directional_vectors(not_filled_pos, n_x, n_y, a_x, a_y, b_x, b_y, A_mat, T_mat, cam):
    """
    not_filled - list of unfilled pixels
    All other parameters are standard as per its name

    Returns a list of unit vectors in physical space, which, when originating from cam, would pass through an unfilled pixel
    """
    not_filled_counter   = not_filled_pos.shape[0]            # number of not filled pixels

    cam_in_flat          = T_mat @ cam                        # location of camera in the rotated space
    not_filled_x_pos     = not_filled_pos[:, 0]               # x-coordinate in the screen (this corresponds to y-space)
    not_filled_y_pos     = not_filled_pos[:, 1]               # y-coordinate in the screen (this corresponds to z-space)

    # (approximate) real coordinates of pixels in rotated space
    unshifted_x          = not_filled_x_pos*(b_x - a_x)/n_x + a_x + (b_x - a_x)/(2*n_x) # this last term is to re-center
    unshifted_y          = not_filled_y_pos*(b_y - a_y)/n_y + a_y + (b_y - a_y)/(2*n_y)
    unshifted_coords     = np.array([np.zeros(not_filled_counter), unshifted_x, unshifted_y])

    cam_to_pixels_in_rot = unshifted_coords - np.repeat(cam_in_flat.reshape(3,1), not_filled_counter, axis=1) # vectors originating from camera to pixels
    ctp_in_rot_normal    = cam_to_pixels_in_rot/np.linalg.norm(cam_to_pixels_in_rot, axis=0)                  # normalize
    ctp_in_space         = A_mat @ ctp_in_rot_normal                                                          # return to physical space - these are the directions for sphere tracing
    return ctp_in_space

# Perform sphere tracing given a vector
def perform_sphere_tracing(cam, direction, phi, dist_threshold = 10e-5, t_max = 5):
    t = 0                                   # distance along the ray
    try:
        while(t < t_max):
            radius = phi(direction*t + cam)  # radius at current point
            if radius < dist_threshold:
                break
            t += radius
        if t < t_max:
            return t
        else:
            return np.inf
    except:
        return np.inf # this will happen if the evaluation of the interpolant phi is outside the interpolation range


# Python program to simulate a secret auction

# Able to import utilities module from helpers package since PYTHONPATH env var is set to "myPythonLearnings" folder
from helpers import utilities

def get_highest_bidder(bid_dictionary):
    max_bid = 0
    max_bidder = ""
    for bidder in bid_dictionary:
        current_user_bid = bid_dictionary[bidder]
        if current_user_bid > max_bid:
            max_bid = current_user_bid
            max_bidder = bidder
    print(f"The highest bidder is {max_bidder} with a bid of ${max_bid}.")

user_bids = {}
more_bidders = 'yes'
while more_bidders == 'yes':
    name = input("Please enter your name: ")
    bid = int(input("Please enter your bid: $"))
    user_bids[name] = bid  # Add the user and his/her bid to the dictionary
    more_bidders = input("Are there more bidders? Type 'yes' or 'no': ").lower()
    utilities.screen_clear()
get_highest_bidder(user_bids)


__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'

import os
import codecs
import datetime
from processing.tools.system import userFolder
from processing.core.ProcessingConfig import ProcessingConfig
from qgis.core import QgsMessageLog
from qgis.PyQt.QtCore import QCoreApplication

class ProcessingLog:

    LOG_ERROR = 'ERROR'
    LOG_INFO = 'INFO'
    LOG_WARNING = 'WARNING'
    LOG_ALGORITHM = 'ALGORITHM'
    DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
    recentAlgs = []

    @staticmethod
    def logFilename():
        logFilename = userFolder() + os.sep + 'processing.log'
        if not os.path.isfile(logFilename):
            logfile = codecs.open(logFilename, 'w', encoding='utf-8')
            logfile.write('Started logging at ' +
                          datetime.datetime.now().strftime(ProcessingLog.DATE_FORMAT) + '\n')
            logfile.close()

        return logFilename

    @staticmethod
    def addToLog(msgtype, msg):
        try:
            # It seems that this fails sometimes depending on the msg
            # added. To avoid it stopping the normal functioning of the
            # algorithm, we catch all errors, assuming that is better
            # to miss some log info than breaking the algorithm.
            if msgtype == ProcessingLog.LOG_ALGORITHM:
                line = msgtype + '|' + datetime.datetime.now().strftime(
                    ProcessingLog.DATE_FORMAT) + '|' \
                    + msg + '\n'
                logfile = codecs.open(ProcessingLog.logFilename(), 'a',
                                      encoding='utf-8')
                logfile.write(line)
                logfile.close()
                algname = msg[len('Processing.runalg("'):]
                algname = algname[:algname.index('"')]
                if algname not in ProcessingLog.recentAlgs:
                    ProcessingLog.recentAlgs.append(algname)
                    recentAlgsString = ';'.join(ProcessingLog.recentAlgs[-6:])
                    ProcessingConfig.setSettingValue(
                        ProcessingConfig.RECENT_ALGORITHMS,
                        recentAlgsString)
            else:
                if isinstance(msg, list):
                    msg = '\n'.join([m for m in msg])
                msgtypes = {ProcessingLog.LOG_ERROR: QgsMessageLog.CRITICAL,
                            ProcessingLog.LOG_INFO: QgsMessageLog.INFO,
                            ProcessingLog.LOG_WARNING: QgsMessageLog.WARNING, }
                QgsMessageLog.logMessage(msg, ProcessingLog.tr("Processing"), msgtypes[msgtype])
        except:
            pass

    @staticmethod
    def getLogEntries():
        entries = {}
        errors = []
        algorithms = []
        warnings = []
        info = []

        with open(ProcessingLog.logFilename()) as f:
            lines = f.readlines()
        for line in lines:
            line = line.strip('\n').strip()
            tokens = line.split('|')
            text = ''
            for i in range(2, len(tokens)):
                text += tokens[i] + '|'
            if line.startswith(ProcessingLog.LOG_ERROR):
                errors.append(LogEntry(tokens[1], text))
            elif line.startswith(ProcessingLog.LOG_ALGORITHM):
                algorithms.append(LogEntry(tokens[1], tokens[2]))
            elif line.startswith(ProcessingLog.LOG_WARNING):
                warnings.append(LogEntry(tokens[1], text))
            elif line.startswith(ProcessingLog.LOG_INFO):
                info.append(LogEntry(tokens[1], text))

        entries[ProcessingLog.LOG_ALGORITHM] = algorithms
        return entries

    @staticmethod
    def getRecentAlgorithms():
        recentAlgsSetting = ProcessingConfig.getSetting(
            ProcessingConfig.RECENT_ALGORITHMS)
        try:
            ProcessingLog.recentAlgs = recentAlgsSetting.split(';')
        except:
            pass
        return ProcessingLog.recentAlgs

    @staticmethod
    def clearLog():
        os.unlink(ProcessingLog.logFilename())

    @staticmethod
    def saveLog(fileName):
        entries = ProcessingLog.getLogEntries()
        with codecs.open(fileName, 'w', encoding='utf-8') as f:
            for k, v in entries.iteritems():
                for entry in v:
                    f.write('%s|%s|%s\n' % (k, entry.date, entry.text))

    @staticmethod
    def tr(string, context=''):
        if context == '':
            context = 'ProcessingLog'
        return QCoreApplication.translate(context, string)

class LogEntry:

    def __init__(self, date, text):
        self.date = date
        self.text = text


import psutil

from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider, ValueObserver
from opentelemetry.sdk.metrics.export import ConsoleMetricsExporter

metrics.set_meter_provider(MeterProvider())
meter = metrics.get_meter(__name__)
metrics.get_meter_provider().start_pipeline(meter, ConsoleMetricsExporter(), 5)

# Callback to gather cpu usage
def get_cpu_usage_callback(observer):
    for (number, percent) in enumerate(psutil.cpu_percent(percpu=True)):
        labels = {"cpu_number": str(number)}
        observer.observe(percent, labels)

meter.register_valueobserver(
    callback=get_cpu_usage_callback,
    name="cpu_percent",
    description="per-cpu usage",
    unit="1",
    value_type=float,
)

# Callback to gather RAM memory usage
def get_ram_usage_callback(observer):
    ram_percent = psutil.virtual_memory().percent
    observer.observe(ram_percent, {})

meter.register_valueobserver(
    callback=get_ram_usage_callback,
    name="ram_percent",
    description="RAM memory usage",
    unit="1",
    value_type=float,
)

input("Metrics will be printed soon. Press a key to finish...\n")


class Sequence:
    def __init__(
        self,
        label='',
        bbox_scale=1.0,
        tracker_name='kcf',
        anchor_bbox=[], # x, y, w, h
        anchor=0,
        insert=0,
        exit=0,
        grayscale=False
        ):
        self.label = label
        self.bbox_scale = bbox_scale
        self.tracker_name = tracker_name

        self.anchor_bbox = anchor_bbox
        self.anchor = anchor

        self.insert = insert
        self.exit = exit

        self.grayscale = grayscale

    def __str__(self):
        return '{}, {}, {}, {}'.format(
            self.label,
            self.tracker_name,
            self.anchor,
            self.anchor_bbox
        )


import random
import math
import py_osm_cluster.util.geom as geom
from py_osm_cluster.util.coords import Coords as C

#util below
def distance(a,b):
	return math.sqrt(math.pow(a[0]-b[0],2)+math.pow(a[1]-b[1],2))
#end util

def gauss_point(coords,sigma):
	return [random.gauss(0,sigma)+coords[x] for x in range(2)]

def weighted_gauss_point(coords,sigmas):
	return [random.gauss(0,x)+coords[num] for num,x in enumerate(sigmas)]

def linear_square_point(coords,side):
	return [random.uniform(coords[x]-side/2.0,coords[x]+side/2.0) for x in range(2)]

def linear_circle_point(coords,radius):
	while True:
		x = random.uniform(-radius,radius)
		y = random.uniform(-radius,radius)
		if geom.distance((0.0,0.0),(x,y))<radius:
			#print(math.sqrt(math.pow(x-coords[0],2)+math.pow(x-coords[0],2)))
			break
	return (x+coords[0],y+coords[1])

#below: helper functions generating linear list of points

"""generates a number of points on the line defined by two points. points generated are on the line in equal distances, not random"""
def segment_linear_division(coords_1,coords_2,number):
	out =[]
	length = math.sqrt(math.pow(coords_1[0]-coords_2[0],2)+math.pow(coords_1[1]-coords_2[1],2))
	distance = float(length)/float(number)
	print(length)
	print(distance)
	for i in range(number):
		print(distance*i)
		x = coords_1[0]+distance*(i/length)*(coords_2[0]-coords_1[0])
		y = coords_1[1]+distance*(i/length)*(coords_2[1]-coords_1[1])
		xy =(x,y)
		print(xy)
		out.append(xy)
	return out

"""generates a number of points on the arc defined by coords, radius and two angles. points generated are on the arc in equal distances, not random"""
def arc_linear_division(coords,radius,angle_1,angle_2,number):
	out =[]
	angle_unit = (angle_2-angle_1)/number
	for i in range(number):
		x = radius*math.sin(angle_1+i*angle_unit)
		y = radius*math.cos(angle_1+i*angle_unit)
		xy =(x+coords[0],y+coords[1])
		out.append(xy)
	return out

""" returns Coords object, with c_number and c_positions set, requires field size, min_distance and number of clusters"""
def _balanced_centers(field_size,dist_function,dist_function_params,num_of_clusters):
	data_obj = C()
	data_obj.c_number = num_of_clusters
	counter = 0
	passes = False
	while not passes:
		print("trying")
		data_obj.c_positions = [linear_square_point([field_size/2.0 for x in [0,1]],field_size)]
		while (not passes) and counter < 100*data_obj.c_number:
			newobj = linear_square_point([field_size/2.0 for x in [0,1]],field_size)
			temp_passes = True
			for i in data_obj.c_positions:
				if not dist_function(i,newobj,dist_function_params) and geom.distance(i,newobj) > 0 :
					temp_passes = False
					break
			if temp_passes:
				data_obj.c_positions.append(newobj)

			counter += 1
			passes = (len(data_obj.c_positions)==data_obj.c_number)
	return data_obj

def _euclidean_balanced(a,b,min_length):
	return geom.distance(a,b) > min_length

def _weighted_balanced(a,b,min_lengths):
	arr = [math.fabs(a[i]-b[i])for i in (0,1)]
	return arr[0]>min_lengths[0] and arr[1]>min_lengths[1]

def generate_balanced_centers(field_size,min_distance,num_of_clusters):
	return _balanced_centers(field_size,_euclidean_balanced,min_distance,num_of_clusters)

def generate_weighted_balanced_centers(field_size,min_distances,num_of_clusters):
	return _balanced_centers(field_size,_weighted_balanced,min_distances,num_of_clusters)
#below: functions generating multiple points

""" sigma = variance (0.1 = centered, 5= over large area )"""
def gauss_blob(coords,sigma,number):
	out =[]
	for i in range(number):
		out.append(gauss_point(coords,sigma))
	return out

def weighted_gauss_blob(coords,sigmas,number):
	out =[]
	for i in range(number):
		out.append(weighted_gauss_point(coords,sigmas))
	return out

def gauss_segment(coords_1,coords_2,sigma,number):
	points = segment_linear_division(coords_1,coords_2,number)
	out =[]
	for i in points:
		out.append(gauss_point(i,sigma))
	return out

def gauss_arc(coords,radius,angle_1,angle_2,sigma,number):
	points = arc_linear_division(coords,radius,angle_1,angle_2,number)
	out =[]
	for i in points:
		out.append(gauss_point(i,sigma))
	return out

def linear_circle(coords,radius,number):
	out =[]
	for i in range(number):
		out.append(linear_circle_point(coords,radius))
	return out

def linear_square(coords,side,number):
	out =[]
	for i in range(number):
		out.append(linear_square_point(coords,side))
	return out

#imperfect, but will do
def linear_imperfect_arc(coords,radius,thickness,angle_1,angle_2,number):
	points = arc_linear_division(coords,radius,angle_1,angle_2,number)
	out =[]
	for i in points:
		out.append(linear_circle_point(i,thickness))
	return out

#generators returning Coord objects

def balanced_multiple_linear_circles(field_size,min_distance_between_centers,n_in_blob,n_of_blobs,radius):
	data_obj = generate_balanced_centers(field_size,min_distance_between_centers,n_of_blobs)
	for num,val in enumerate(data_obj.c_positions):
		gb = linear_circle(val,radius,n_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(n_in_blob)]
	return data_obj

#generates gauss blobs given possible area (field size 0,0 to fs,fs), number of blobs and number of items per blob
def multiple_gauss_blobs(field_size,n_in_blob,n_of_blobs,sigma):
	data_obj =C()
	data_obj.c_number = n_of_blobs
	for i in range(n_of_blobs):
		data_obj.c_positions.append([random.uniform(0.0,field_size) for i in range(2)])
	for num,val in enumerate(data_obj.c_positions):
		gb = gauss_blob(val,sigma,n_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(n_in_blob)]
	return data_obj

def multiple_weighted_gauss_blobs(field_size,n_in_blob,n_of_blobs,sigmas):
	data_obj =C()
	data_obj.c_number = n_of_blobs
	for i in range(n_of_blobs):
		data_obj.c_positions.append([random.uniform(0.0,field_size) for i in range(2)])
	for num,val in enumerate(data_obj.c_positions):
		gb = weighted_gauss_blob(val,sigmas,n_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(n_in_blob)]
	return data_obj

#Warning! not always possible, may loop
def balanced_multiple_gauss_blobs(field_size,min_distance_between_centers,n_in_blob,n_of_blobs,sigma):
	data_obj = generate_balanced_centers(field_size,min_distance_between_centers,n_of_blobs)
	for num,val in enumerate(data_obj.c_positions):
		gb = gauss_blob(val,sigma,n_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(n_in_blob)]
	return data_obj

""" generates num integers that sum up to given number"""
def _integers_summing(num, sum):
    dividers = sorted(random.sample(list(range(1, sum)), num - 1))
    return [a - b for a, b in zip(dividers + [sum], [0] + dividers)]

#Warning! not always possible, may loop
def balanced_random_size_gauss_blobs(field_size,min_distance_between_centers,min_in_blob,total_points,n_of_blobs,sigma):
	data_obj = generate_balanced_centers(field_size,min_distance_between_centers,n_of_blobs)
	for num,val in enumerate(data_obj.c_positions):
		gb = gauss_blob(val,sigma,min_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(min_in_blob)]
	sum_no_min = total_points - (n_of_blobs*min_in_blob)
	points_to_add = _integers_summing(n_of_blobs, sum_no_min)
	#print(points_to_add)
	for num,i in enumerate(points_to_add):
		gb = gauss_blob(data_obj.c_positions[num],sigma,i)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(i)]
	#print(len(data_obj.coords))
	return data_obj

#Warning! not always possible, may loop
def balanced_multiple_weighted_gauss_blobs(field_size,min_distances_between_centers,n_in_blob,n_of_blobs,sigmas):
	data_obj = generate_weighted_balanced_centers(field_size,min_distances_between_centers,n_of_blobs)
	for num,val in enumerate(data_obj.c_positions):
		gb = weighted_gauss_blob(val,sigmas,n_in_blob)
		data_obj.coords = data_obj.coords + gb
		data_obj.labels = data_obj.labels + [num for j in range(n_in_blob)]
	return data_obj

def gauss_circle_in_other(outer_radius,p_in_central,p_in_outer,sigma_in,sigma_out):
	data_obj = C()
	data_obj.c_number = 2
	data_obj.coords = data_obj.coords + gauss_blob((0.0,0.0),sigma_in,p_in_central)
	data_obj.labels = data_obj.labels + [0]*p_in_central
	data_obj.coords = data_obj.coords + gauss_arc((0.0,0.0),outer_radius,0.0,2*math.pi,sigma_out,p_in_outer)
	data_obj.labels = data_obj.labels + [1]*p_in_outer
	return data_obj

def croissants(number_in_c,radius_distance,sigma):
	data_obj = C()
	data_obj.c_number = 2
	data_obj.coords = data_obj.coords + gauss_arc((0.0,0.0),radius_distance,0.0,1*math.pi,sigma,number_in_c)
	data_obj.labels = data_obj.labels + [0]*number_in_c
	data_obj.c_positions.append((radius_distance,0.0))

	data_obj.coords = data_obj.coords + gauss_arc((0.0,radius_distance),radius_distance,math.pi,2*math.pi,sigma,number_in_c)
	data_obj.labels =  data_obj.labels + [1]*number_in_c
	data_obj.c_positions.append((-radius_distance,radius_distance))
	return data_obj


# 11724
import sys
sys.setrecursionlimit(10**9) #최대 재귀 수 설정

n, m = map(int, sys.stdin.readline().split())
graph = [[] for i in range(n+1)]
result = [0 for i in range(n+1)]
count = 0

for i in range(m):
    u, v = map(int, sys.stdin.readline().split())
    graph[u].append(v)
    graph[v].append(u)

def findComponent(v):
    global count
    result[v] = 1
    for i in graph[v]:
        if not result[i]:
            findComponent(i)

for i in range(1, n+1):
    if not result[i]: # result의 값이 0이 아니라면 (방문하지 않았다면)
        findComponent(i)
        count += 1

print(count)


from Wordle_Agent import Wordle_Agent
class Wordle_Agent_LetterFreq(Wordle_Agent):
    """
    An agent to play Wordle, which extends the Wordle_Agent class.
    This agent will attempt to calculate the next guess based on the frequency
    of letters in the word list.
    """
    import re
    import sys

    def __init__(self, game, debug=False):
        """
        Augment the base class for this type of Agent
        Inputs: a Wordle_Game object
        Outputs: None. Modifies local attributes.
        """
        super().__init__(game, debug=debug) # instantiate the base class
        self.letter_counts = {} # position independent letter counts
        self.letter_freqs = {}  # position independent letter frequencies
        self.remaining_word_scores = {} # the remaining words and their scores. Starts full and will be reduced
        self._start_setup() # perform setup based on the available information

    def _start_setup(self):
        """
        Execute setup steps before making the first guess.
        Inputs: none.
        Outputs: none.
        """
        # initialize to zero, then calculate
        for w in self.word_list:
            self.remaining_word_scores[w] = 0

        self._calculate_letter_freqs() # calculate letter frequencies from words in the word list
        self._calculate_word_freq_scores() # calculate a score for each word in the list

    def _build_match_regex(self):
        """
        Build a regex pattern object that will match words that follow the
            rules of what we know about included and correct letters.
        Inputs: none; reads local attributes
        Outputs: a compiled re object.
        """
        patt_str = ''

        for i in range(self.word_length): # build an appropriately long regex from what is known

            if self.correct_letters[i] != '-': # a correctly placed letter so fix it in the regex

                patt_str += self.correct_letters[i]

            else: # include absence information (i.e., a returned lower case N means we can toss any word with an N in that position)

                without_patt = '' # a string to hold letters that are NOT in a particular position
                for j in range(len(self.guesses)):

                    # the guessed letter isn't in this position so add it to the regex pattern
                    if self.results[j][i] == '.' or self.results[j][i] == self.results[j][i].lower():

                        without_patt += self.guesses[j][i].upper()

                if without_patt != '': # add the pattern of letters not included in this position

                    patt_str += "[^{0}]".format(without_patt)

                else: # can match any letter

                    patt_str += "."

        return self.re.compile(patt_str)

    def _calculate_letter_freqs(self):
        """
        Calculate position-independent letter frequencies from the words in
            the word list parsed from the game object.
        Inputs: none.
        Outputs. None. Changes local attributes.
        """

        # reset counter dicts
        self.letter_counts = {}
        self.letter_freqs = {}

        if len(self.remaining_word_scores) == 0:
                raise ValueError("Oops, I ran out of options. My algorithm is broken?")

        for w in self.remaining_word_scores.keys(): # for each remaining word

            for i in range(self.word_length): # for each position

                if w[i] not in self.letter_counts: # initialize the letter

                    self.letter_counts[w[i]] = 0

                self.letter_counts[w[i]] += 1 # count an occurrence of this letter

        lowest_count_letter = min(self.letter_counts, key=lambda key: self.letter_counts[key])
        # use this to normalize the scores to be a multiple of the least frequent letter
        # i.e., if Q is the least frequent letter, frequency of Q = 1, and E ~= 55.

        for l in self.letter_counts.keys(): # turn counts into frequencies normalized to the lowest value
            self.letter_freqs[l] = self.letter_counts[l] / self.letter_counts[lowest_count_letter]

    def _calculate_word_freq_scores(self):
        """
        Calculate the letter frequency scores for each word remaining in the
            remaining word dict.
        Inputs: None.
        Outputs: none. Modifies local attributes.
        """
        for w in self.remaining_word_scores.keys():
            self.remaining_word_scores[w] = self._score_word(w)

    def _reduce_remaining_word_scores(self):
        """
        Reduce the remaining_word_scores dict given what we have learned through
            the scoring strings returned from the game object.
        Inputs: none.
        Outputs: none. Modifies local attributes.
        """

        to_remove = [] # words to remove from the dict
        correct_patt = '' # a pattern of letters in the correct places
        base_patt = self.re.compile('[^\-]')

        correct_patt = self._build_match_regex()

        for w in self.remaining_word_scores.keys(): # for each remaining guessable word

            # least stringent test: does the word contain an included letter?

            has_included_letter = True # edge case of first guess having no overlap with the secret word
            if (len(self.included_letters.keys()) > 0):
                has_included_letter = False

                for i in self.included_letters.keys():

                    if i in w:  # we have a hit so keep the word

                        has_included_letter = True

            # more stringent: does the letter match the pattern of correct letters?

            matches_regex = True

            if self.re.match(correct_patt, w) is None: # no match object = no _build_match_regex

                matches_regex = False

            # most stringent: does the word contain a banned letter?

            no_incorrect_letters = True
            for i in self.incorrect_letters.keys():

                if i in w:

                    no_incorrect_letters = False

            # do we keep this word or not?
            if (has_included_letter is True) and (matches_regex is True) and (no_incorrect_letters is True):

                keep_word = True

            else:

                keep_word = False
                to_remove.append(w)

        for r in to_remove: # drop all the removed words
            del self.remaining_word_scores[r]

    def _score_word(self, word):
        """
        calculate the frequency-based score for a word.
        Inputs: a word.
        Outputs: a float.
        """
        return sum([self.letter_freqs[l] for l in word])

    def _get_best_scoring_word(self):
        """
        Return the word with the highest letterfreq score
        Inputs: none.
        Outputs: the word with the highest score in the remaining_word_scores
            list.
        """
        return max(self.remaining_word_scores, key=lambda key: self.remaining_word_scores[key])

    def play(self, game):
        """
        Play the Wordle game from the passed-in Wordle_Game object.
        The agent will play the game autonomously to its conclusion.
        Inputs: a Wordle_Game object
        Outputs: changes local attributes, prints messages
        """
        while game.game_won is None: # until win or loss

            if self.debug:
                print(f"New round: {self}", file=self.sys.stderr)

            # set up the letter frequencies and word scores based on the current word list
            self._calculate_letter_freqs() # calculate letter frequencies from words in the word list
            self._calculate_word_freq_scores() # calculate a score for each word in the list

            # choose the best starting word
            best_word = self._get_best_scoring_word()

            if self.debug:
                print(f"Guessing {best_word}", file=self.sys.stderr)

            # submit our current best guess and remove from further consideration
            game.parse_guess(best_word)
            del self.remaining_word_scores[best_word]

            # parse the returned score
            self.guesses.append(best_word)
            self.results.append(game.messages[-1])
            self._record_guess_results(self.results[-1])

            # reduce the wordlist based on the score
            self._reduce_remaining_word_scores()

        self.outcome = game.game_won

        if self.debug: # get noisy about game state at every step, and outcome
            for i in range(len(self.guesses)):
                print("Round {0}: guess: {1} score {2}".format(i+1, self.guesses[i], self.results[i]))

            if self.outcome is True:

                print("Game won.")

            else:

                print("Game lost.")

    def __str__(self):
        """
        A human-friendly representation of the agent's state.
        """
        return "Wordle LetterFreq Agent (incorrect letters=" + ','.join(self.incorrect_letters.keys()) + " included letters=" + ','.join(self.included_letters.keys()) + " correct letters=" + ''.join(self.correct_letters) + ")"


from koza.cli_runner import koza_app

from loguru import logger

source_name = "mimtitles"
row = koza_app.get_row(source_name)
map = koza_app.get_map(source_name)

###
# From OMIM
#  An asterisk (*) before an entry number indicates a gene.
#
# A number symbol (#) before an entry number indicates that it is a descriptive entry,
# usually of a phenotype, and does not represent a unique locus. The reason for the use
# of the number symbol is given in the first paragraph of he entry. Discussion of any gene(s)
# related to the phenotype resides in another entry(ies) as described in the first paragraph.
#
# A plus sign (+) before an entry number indicates that the entry contains the description of
# a gene of known sequence and a phenotype.
#
# A percent sign (%) before an entry number indicates that the entry describes a confirmed
# mendelian phenotype or phenotypic locus for which the underlying molecular basis is not known.
#
# No symbol before an entry number generally indicates a description of a phenotype for which
# the mendelian basis, although suspected, has not been clearly established or that the separateness
# of this phenotype from that in another entry is unclear.
#
# A caret (^) before an entry number means the entry no longer exists because it was removed
# from the database or moved to another entry as indicated.
###

if row['Prefix'] == 'Asterisk':
    map[row['MIM Number']] = 'gene'

elif row['Prefix'] == 'NULL':
    map[row['MIM Number']] = 'suspected'

elif row['Prefix'] == 'Number Sign':
    map[row['MIM Number']] = 'disease'

elif row['Prefix'] == 'Percent':
    map[row['MIM Number']] = 'heritable_phenotypic_marker'

elif row['Prefix'] == 'Plus':
    map[row['MIM Number']] = 'gene'

elif row['Prefix'] == 'Caret':  # moved|removed|split -> moved twice
    map[row['MIM Number']] = 'obsolete'

    # populating a dict from an omim to a set of omims
    # Not sure we'll need this so commenting out for now
    # map['replaced by'] = []
    #
    # if row['Preferred Title; symbol'][:9] == 'MOVED TO ':
    #    token = row['Preferred Title; symbol'].split(' ')
    #    title_symbol = token[2]

    #    if not re.match(r'^[0-9]{6}$', title_symbol):
    #        logger.error(f"Report malformed omim replacement {title_symbol}")
    #        # clean up ones I know about

    #        if title_symbol[0] == '{' and title_symbol[7] == '}':
    #            title_symbol = title_symbol[1:7]
    #            logger.info(f"Repaired malformed omim replacement {title_symbol}")

    #        if len(title_symbol) == 7 and title_symbol[6] == ',':
    #            title_symbol = title_symbol[:6]
    #            logger.info(f"Repaired malformed omim replacement {title_symbol}")

    #    if len(token) > 3:
    #        map['replaced by'] = [title_symbol, token[4]]

    #    else:
    #        map['replaced by'] = [title_symbol]

else:
    logger.error(f"Unknown OMIM type line {row['omim_id']}")


# Python dictionaries are similar to lists in that they can store multiple
# values in a single variable. However, they are different in that there is no
# real order to the data stored in a dictionary and the data is accessed with
# the use of a key (or label) instead of its order in the list. You could think
# of a list as a Pringles can with all the chips stacked up neatly in order and
# a dictionary is a bag of Doritos with all the chips in the bag but in no
# particular order. This is Pythons most powerful data collection. Other
# languages have these and they go by different names: Property Bags, Hashmaps,
# Associative Arrays (for PHP and Perl), etc.

# To create a dictionary use the dict() Object. You can also use {}.

purse = dict()
bag = {}

# You can then put things into the dictonary by assigning each piece of data with a label.

purse['money'] = 12
purse['candy'] = 3
purse['tissues'] = 75

# If you print the dictionary, you'll get all three items in no particular
# order. However, each piece of data will be attached to its key.

print(purse) # Prints "{'money': 12, 'tissues': 75, 'candy': 3}"

# You can ask Python to return a single piece of data from the dictionary

print(purse['candy']) # Prints "3"

# You can over write any piece of data in a dictionary. It will always use the
# most recent assignment for each key

purse['money'] = 12
purse['candy'] = 3
purse['tissues'] = 75
purse['money'] = 98
print(purse) # Prints "{'money': 98, 'tissues': 75, 'candy': 3}"

# Dictionaries are really great for counting things. They can be used to make
# histograms to display how frequently a particular piece of data shows up.

# Create a dictionary that will count things for you. When you encounter a new
# thing, you'll have to add a new entry into the dictionary. If it is the second
# or time you're seeing the thing, add one to the count in the dictionary under
# that thing.

counts = dict()
names = ['csev', 'cwen', 'csev', 'zqian', 'cwen']
for name in names :
    if name not in counts :
        counts[name] = 1
    else :
        counts[name] = counts[name] + 1
print(counts)

# There is a handy method for dictionaries: .get(). To see if a key is already
# part of a dictionary (and assuming a default value if the key is not in the
# dictionary) you could write the code like this:

if name in counts :
    x = counts[name]
else :
    x = 0

# You can do the same exact thing with the .get() method and its a lot cleaner:

x = counts.get("key","default")
x = counts.get(name, 0)

# This makes the code above a lot simpler (memorize this!!!):

# This is the dictionary where the counting takes place
counts = dict()
# Here is the data to be analyzed
names = ['csev', 'cwen', 'csev', 'zqian', 'cwen']
for name in names :
    # This says that if the name is new, set it to 1.
    counts[name] = counts.get(name, 0) + 1 #
print(counts)

# Count words in provided text

# Creates an empty dictionary
counts = {}
# Prompts user for input text
print('Enter a line of text: ')
# Sets variable to input line of text
line = input('')
# Sets variable to list of words in provided text
words = line.split()
# Prints the list
print('Words: ', words)
print('Counting...')
# For every word in the list
for word in words :
    # Count the number of times each word shows up
    counts[word] = counts.get(word, 0) + 1
# Print the results
print('Counts: ', counts)

# If you have an established dictionary it is easy to run a definite loop on every entry

counts = {'chuck', 3, 'fred', 42, 'jan', 100}
for key in counts :
    print(key, counts[key])

# There are a few things you can specifically print out regarding dictionaries

jjj = {'chuck', 3, 'fred', 42, 'jan', 100}
print(list(jjj)) # Prints ['jan', 'chuck', 'fred'] in no particular order.
print(jjj.keys()) # Prints ['jan', 'chuck', 'fred'] in no particular order.
print(jjj.values()) # Prints [100, 3, 42] in no particular order.
# If you ask for the keys and values together they will print out in a corresponding order
print(jjj.items()) # Prints {('jan', 100), ('chuck', 3), ('fred', 42)}

# You can loop through key-value pairs in a dictionary using two iteration variables (Python Only)

jjj = {'chuck', 3, 'fred', 42, 'jan', 100}
for aaa,bbb in jjj.items() :
    print(aaa,bbb) # Prints individual key-value pairs

# Asks user for file name
name = input('Enter file: ')
# Assigns handle to file
handle = open(name)

# Creates new dictionary
counts = dict()
# for every line in the file
for line in handle :
    # Create a list of whitespace separated words
    words = line.split()
    # for each word in the list
    for word in words :
        # Counts the number of words, adding new entries for unique words
        counts[word] = counts.get(word, 0) + 1

# Initializes two varables
bigcount = None
bigword = None
# For each word-count key-value pair
for word,count in counts.items() :
    # Keeps track of the highest number and what word it belongs to
    if bigcount is None or count > bigcount :
        bigword = word
        bigcount = count

# Prints out the word that appeared the most and how many times it appeared.
print(bigword, bigcount)

# You can sort dictionaries by value instead of key. This code prints out the 10
# most common words in a text file

fhand = open(romeo.txt)
counts = dict()
for line in fhand:
    words = line.split()
    for word in words:
        counts[word] = counts.get(word, 0) + 1

lst = list()
for key, val in counts.items():
    newtup = (val, key)
    lst.append(newtup)

lst = sorted(lst, reverse=True)

for val, key in lst[:10]:
    print(key, val)

# This can be written in a much more succint way.

print(sorted([(val,key) for key,val in counts.items()]))
# Prints [(1, 'b'), (10, 'a'), (22, 'c')]


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import random

def coin():
    return random.randrange(0,2)

def coins20():
    X = []
    for i in range(0,20):
        X.append(coin())
    return X

def mili():
    E = []
    for i in range(0,1000000):
        E.append(coins20())
    return E

mil_reps = mili()
np.shape(mil_reps)
def frqs(bs):
    data = []
    a = 0.5
    while a < 1.05:
        count = 0
        for i in range(0,1000000):
            freq = 0.05*sum(bs[i])
            if freq >= a:
                count = count+1
        data.append(count)
        a = a+0.05
    return data

emp_freqs = frqs(mil_reps)
emp_freqs
aaaa = [a*0.05 for a in range(10,21)]

plt.figure(1)
plt.plot(aaaa, emp_freqs, label="Empirical freq. of observations", color="red", linestyle=':')
plt.title(" 20 coin flips plot of frequency", color="blue")
plt.xlabel("Alpha", color="blue")
plt.ylabel("Frequency greater than alpha", color="blue")
plt.legend()
plt.show()

def hoff(es):
    hoff_bound = []
    for e in es:
        hoff_bound.append(np.exp(-2*20*(e-0.5)**2)*1000000)
    return hoff_bound

def markov(aaaa):
    mark_bound=[]
    for a in aaaa:
        mark_bound.append(1000000*0.5/a);
    return mark_bound

plt.figure(2)
plt.plot(aaaa, emp_freqs, label="Empirical frequency", color="red", linestyle=':')
plt.plot(aaaa, hoff(aaaa), label = "Hoeffding's Bound", color="blue", linestyle=':')
plt.plot(aaaa, markov(aaaa), label = "Markov's Bound", color="green", linestyle=':')
plt.title("Hoeffding's and Markov's Bounds", color="blue")
plt.xlabel(" alpha", color="red")
plt.ylabel("Frequency of average greater than alpha", color="red")
plt.legend()
plt.axis([0.5,1.0, 0,1000000])
#plt.legend(bbox_to_anchor=(0, -0.15, 1, 0), loc=2, borderaxespad=0)
plt.legend()
plt.show()

#Handling Data
locationTrain = 'IrisTrainML.dt'
locationTest = 'IrisTestML.dt'
dfTrain = pd.read_csv(locationTrain, header=None, sep=' ')
dfTest = pd.read_csv(locationTest, header=None, sep=' ')

dfTrainNO2 = dfTrain.loc[dfTrain[2] != 2]
dfTestNO2 = dfTest.loc[dfTest[2] != 2]

irisTrainX = dfTrainNO2.as_matrix(columns=[0,1])
irisTrainY = dfTrainNO2.as_matrix(columns=[2])
irisTestX = dfTestNO2.as_matrix(columns=[0,1])
irisTestY = dfTestNO2.as_matrix(columns=[2])

np.place(irisTrainY, irisTrainY == 0, -1)
np.place(irisTestY, irisTestY == 0, -1)

def bigX(inputData):
    if inputData.shape[0] > inputData.shape[1]:
        inputNoTilde = inputData
    else:
        inputNoTilde = np.transpose(inputData)
    ones = np.ones((len(inputNoTilde), 1), dtype=np.int)
    inputX = np.hstack((inputNoTilde, ones))
    return inputX

# Weights
def initWeights(data):
    dimensions = data.shape[1]
    weights = np.zeros((dimensions))
    return weights

# Simple Gradient
def gradOneSimple(x, y, w):
    yMULTx = np.multiply(y,x)
    wDOTx = np.dot(np.transpose(w),x)
    yMULTwtx = np.multiply(y, wDOTx)
    exp = np.exp(yMULTwtx)
    gradient = np.divide(yMULTx, 1 + exp)
    return gradient

# Full Gradient
def gradient(dataX, dataY, weights):
    accum = initWeights(dataX)
    n = len(dataY)
    for i in range(len(dataX)):
        gradient = gradOneSimple(dataX[i], dataY[i], weights)
        accum += gradient
    mean = np.divide(accum, n)
    gradient = np.negative(mean)
    return gradient

# Function for updating weights.
def updateWeights(oldWeights, direction, learningRate):
    newWeight = oldWeights + np.multiply(learningRate, direction)
    return newWeight

# Logistic regression model. Implementation of LFD algorithm.
def logReg(dataX, dataY, learningRate):
    X = bigX(dataX)
    weights = initWeights(X)
    for i in range(0,1000):
        g = gradient(X, dataY, weights)
        direction = -g
        weights = updateWeights(weights, direction, learningRate)
    return weights

# Building affine linear model and reporting results.
vectorWandB = logReg(irisTrainX, irisTrainY, 0.1)

vectorW = np.transpose(vectorWandB[:-1])

b = vectorWandB[-1]

print(vectorWandB)
print('\n')
print('Affine linear model build. w: ' + str(vectorW) + '   b: '
                                             + str(b) + '\n')

# Function that computes conditional probability using logistic regression.
def conditionalProb(x, vectorW, b):
    wDOTx = np.dot(vectorW, x)
    y = wDOTx + b
    exp = np.exp(y)
    prob = np.divide(exp, 1 + exp)
    return prob

# Function that classifies using the probability from logistic regression.
def linearClassifier(x, vectorW, b ):
    y = -2
    prob = conditionalProb(x, vectorW, b)
    if prob > 0.5:
        y = 1
    else:
        y = -1
    return y

# Function that finds the number of wrong classifications for test data.
def testingFalse(trainX, trainY, testX, testY, learningRate):
    trueCount = 0
    falseCount = 0
    weights = logReg(trainX, trainY, learningRate)
    vectorW = weights[:-1]
    b = weights[-1]
    for i in range(0,len(testY)):
        if linearClassifier(testX[i], vectorW, b) == testY.item(i):
            trueCount += 1
        else:
            falseCount += 1
    return falseCount

# Finding the empirical loss of linear classification model with a zero-one loss
# function.
def zeroOneLoss(trainX, trainY, testX, testY, learningRate):
        N = len(testY)
        misClassified = testingFalse(trainX, trainY, testX, testY, learningRate)
        zeroOneLoss = (1/N)*misClassified
        return zeroOneLoss

lossTrain = zeroOneLoss(irisTrainX, irisTrainY, irisTrainX, irisTrainY, 0.1)
lossTest = zeroOneLoss(irisTrainX, irisTrainY, irisTestX, irisTestY, 0.1)
print("0-1 loss of logistic regression linear classifier on training data: " + str(lossTrain))
print("0-1 loss of logistic regression linear classifier on testing data: " + str(lossTest))


import functools
words=input().split()
def validate(word):
    letters=[]
    for i in word:
        if i.upper() not in letters:
            letters.append(i.upper())
    if len(letters)>3:
        return True
    return False
if __name__=='__main__':
    answer1=list(filter(validate, words))
    print(list(map(lambda a: a[0].swapcase()+a[1:], answer1)))
    answer2 = list(filter(lambda x: 'foo' in x, words))
    print(len(functools.reduce(lambda a,b: a+b, answer2)))