def sidel(arr):
    x_last=0
    y_last=0
    z_last=0
    counter=0
    eps = 0.001
    if abs(arr[0][2])+abs(arr[0][1])>abs(arr[0][0]):
        return False
    if abs(arr[1][0])+abs(arr[1][2])>abs(arr[1][1]):
        return False
    if abs(arr[2][0])+abs(arr[2][1])>abs(arr[2][2]):
        return False
    times = 0
    first = True
    second = True
    third = True
    while first or second or third:
        times +=1
        x = (arr[0][3] - arr[0][1]*(y_last) - arr[0][2]*z_last) / arr[0][0]
        y = (arr[1][3] - arr[1][0]*x - arr[1][2]*z_last) / arr[1][1]
        z = (arr[2][3] - arr[2][0]*x - arr[2][1]*y) / arr[2][2]

        if abs(x - x_last) <= eps:
            first = False
        else:
            x_last = x

        if abs(y - y_last) <= eps:
            second = False
        else:
            y_last = y

        if abs(y - y_last) <= eps:
            third = False
        else:
            z_last = z

    new_array=[]
    new_array.append(x_last)
    new_array.append(y_last)
    new_array.append(z_last)
    new_array.append(times)

    return new_array

arr=[[10,2,-1,5],
     [-2,-6,-1,24.42],
     [1,-3,12,36]]

print(sidel(arr))


import os
import socket
from easydict import EasyDict as edict
import utils.shapenet_provider as sp

def get_pointnet_config():
    base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    data_dir = os.path.join(base_dir, 'data/modelnet40_ply_hdf5_2048/')
    log_dir = os.path.join(base_dir, 'train_outputs/pointnet/log/')
    model_dir = os.path.join(base_dir, 'train_outputs/pointnet/model/')
    train_files = sp.getDataFiles(os.path.join(data_dir, 'train_files.txt'))
    test_files = sp.getDataFiles(os.path.join(data_dir, 'test_files.txt'))
    label_names = sp.getLabelNameDictionary(os.path.join(data_dir, 'shape_names.txt'))
    for i in range(len(train_files)):
        train_files[i] = os.path.join(base_dir, train_files[i])

    cfg = edict()
    cfg.base_lr = 0.001
    cfg.final_lr = 0.00001
    cfg.batch_size = 32
    cfg.decay_step = 200000
    cfg.decay_rate = 0.7
    cfg.max_epoch = 250
    cfg.point_num = 1024
    cfg.log_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'log/pointnet/')
    cfg.gpu_idx = 0
    cfg.model = 'pointnet_cls'
    cfg.hostname = socket.gethostname()
    cfg.base_dir = base_dir
    cfg.data_dir = data_dir
    cfg.model_dir = model_dir
    cfg.log_dir = log_dir
    cfg.train_files = train_files
    cfg.test_files = test_files
    cfg.label_names = label_names
    return cfg


'''
Script to download movie posters.

Approach used in this programm is to extract the poster url from The Movie DataBase(tmdb) using API, appending it with base url
i.e. 'http://image.tmdb.org/t/p/original' and saving the image. To get this script running, tmdb API Key will be required

To register for an API key, click the API Link from within your account settings page.

Click on your avatar or initials in the main navigation
Click the "Settings" link
Click the "API" link in the left sidebar
Click "Create" or "click here" on the API page

Comlplete documentation is available at 'https://developers.themoviedb.org/3/getting-started/introduction'

'''

# Importing necessary packages

import requests
import os
import tmdbsimple as tmdb

# define your API_KEY here
tmdb.API_KEY = 'Your_API_Key_Here'

# Creating tmdb search instance
search = tmdb.Search()

# running a loop inside video directory
# checking for valid video extension (all videos are in .mp4 format only)
for movie in os.listdir('E:\\DB\\Videos\\'):
	if movie.endswith('.mp4'):

		# pass the movie name in search.movie()
		# make sure it is proper movie name without any irrelevant or extra characters
		# for e.g. movie name should be 'Baahubali' and not 'Baahubali - Official Trailer' or something similar.
		# The trailers which I downloaded using video_downloader.py file follows the same pattern as 'Baahubali - Official Trailer'
		# so spliting the file name to get the proper movie name

		response = search.movie(query=movie.split('-')[0])

		# search.movie returns a list of jsons,
		# we will get the first element and target the 'poster_path' key which containes the poster url
		# if 'poster_path' is none in first json, we will get the second json and extract the 'poster_path'
		i = search.results[0]
		j = i['poster_path']
		if j == None:
			i = search.results[1]
			j = i['poster_path']
		print(movie.split('-')[0])

		# finally after getting the poster url,
		# append it with the base url and download the image
	try:
		img_data = requests.get('http://image.tmdb.org/t/p/original'+j).content
		with open(movie+'.jpg', 'wb') as handler:
		    handler.write(img_data)
	except:
		print('File Not Found')


"""doit Documentation Utilities."""

import json
import re
import webbrowser
from pathlib import Path
from typing import Dict, List, Optional, Pattern

from doit.tools import InteractiveAction, LongRunning
from loguru import logger
from transitions import Machine

from .base import debug_task, echo, open_in_browser, read_lines
from .doit_globals import DIG, DoItTask

# ----------------------------------------------------------------------------------------------------------------------
# Update __init__.py with Documentation

_INIT_DIVIDER: str = f'# {"=" * 15} Above is Auto-Generated by calcipy. User content goes below {"=" * 15}'
"""Divider between auto-generated content and possible user-content in the `__init__.py` file."""

_LOGGER_CONFIG: str = """{docstring}

from loguru import logger

__version__ = '{pkg_version}'
__pkg_name__ = '{pkg_name}'

logger.disable(__pkg_name__)
"""
"""Python code to be appended to `__init__.py`."""

def _write_pkg_init() -> None:
    """Write the package `__init__.py` file."""
    init_text = _LOGGER_CONFIG.format(
        docstring=f'"""{DIG.meta.pkg_name}."""',
        pkg_version=DIG.meta.pkg_version,
        pkg_name=DIG.meta.pkg_name,
    ) + '\n' + _INIT_DIVIDER
    init_path = (DIG.meta.path_project / DIG.meta.pkg_name / '__init__.py')
    init_lines = init_path.read_text().strip().split('\n')
    try:
        break_index = init_lines.index(_INIT_DIVIDER) + 1
        user_text = '\n'.join(init_lines[break_index:])
    except ValueError as err:
        logger.warning('Did not find a divider, so overwriting any existing user text', err=err)
        user_text = ''
    init_path.write_text((init_text.replace('\t', ' ' * 4) + user_text).strip() + '\n')

# ----------------------------------------------------------------------------------------------------------------------
# Manage Changelog

def task_cl_write() -> DoItTask:
    """Write a Changelog file with the raw Git history.

    Resources:

    - https://keepachangelog.com/en/1.0.0/
    - https://www.conventionalcommits.org/en/v1.0.0/
    - https://writingfordevelopers.substack.com/p/how-to-write-a-commit-message
    - https://chris.beams.io/posts/git-commit/
    - https://semver.org/
    - https://calver.org/

    Returns:
        DoItTask: doit task

    """
    return debug_task(['poetry run cz changelog'])

def task_cl_bump() -> DoItTask:
    """Bumps project version based on project history and settings in pyproject.toml.

    Returns:
        DoItTask: doit task

    """
    return debug_task([
        InteractiveAction('poetry run cz bump --changelog --annotated-tag'),
        (echo, ('Attempting to push tags to origin with pre-commit checks',)),
        'git push origin --tags',
    ])

def task_cl_bump_pre() -> DoItTask:
    """Bump with specified pre-release tag. Creates Changelog.

    Example: `doit run cl_bump_pre -p alpha` or `doit run cl_bump_pre -p rc`

    Returns:
        DoItTask: doit task

    """
    task = debug_task([
        InteractiveAction('poetry run cz bump --changelog --prerelease %(prerelease)s'),
        'git push origin --tags --no-verify',
    ])
    task['params'] = [{
        'name': 'prerelease', 'short': 'p', 'long': 'prerelease', 'default': '',
        'help': 'Specify prerelease version for bump (alpha, beta, rc)',
    }]
    return task

# ----------------------------------------------------------------------------------------------------------------------
# Manage README Updates

class _ReadMeMachine:  # noqa: H601
    """State machine to replace commented sections of readme with new text."""

    states: List[str] = ['readme', 'new']

    transitions: List[Dict[str, str]] = [
        {'trigger': 'start_new', 'source': 'readme', 'dest': 'new'},
        {'trigger': 'end', 'source': 'new', 'dest': 'readme'},
    ]

    readme_lines: Optional[List[str]] = None

    def __init__(self) -> None:
        """Initialize state machine."""
        self.machine = Machine(model=self, states=self.states, initial='readme', transitions=self.transitions)

    def parse(  # noqa: CCR001
        self, lines: List[str], comment_pattern: Pattern[str],
        new_text: Dict[str, str],
    ) -> List[str]:
        """Parse lines and insert new_text.

        Args:
            lines: list of text files
            comment_pattern: comment pattern to match (ex: ``)
            new_text: dictionary with comment string as key

        Returns:
            list: list of strings for README

        """
        self.readme_lines = []
        for line in lines:
            if comment_pattern.match(line):
                self.readme_lines.append(line)
                if line.strip().startswith('<!-- /'):
                    self.end()
                else:
                    key = comment_pattern.match(line).group(1)
                    self.readme_lines.extend(['', *new_text[key], ''])
                    self.start_new()
            elif self.state == 'readme':
                self.readme_lines.append(line)

            new_line = self.readme_lines[-1]
            made_change = (line != new_line)
            logger.debug(
                'Parsed README Line', self_state=self.state, line=line,
                made_change=made_change, new_line=new_line if made_change else None,
            )

        return self.readme_lines

# FIXME: This was for a very specific implementation. See #36 for variable defintion
def _write_to_readme(comment_pattern: Pattern[str], new_text: Dict[str, str]) -> None:
    """Wrap _ReadMeMachine. Handle reading then writing changes to the README.

    Args:
        comment_pattern: comment pattern to match (ex: ``)
        new_text: dictionary with comment string as key

    """
    readme_path = DIG.meta.path_project / 'README.md'
    readme_lines = _ReadMeMachine().parse(read_lines(readme_path), comment_pattern, new_text)
    readme_path.write_text('\n'.join(readme_lines))

def _write_code_to_readme() -> None:
    """Replace commented sections in README with linked file contents."""
    comment_pattern = re.compile(r'\s*<!-- /?(CODE:.*) -->')
    fn = 'tests/examples/readme.py'
    script_path = DIG.meta.path_project / fn
    if script_path.is_file():
        source_code = ['```py', *read_lines(script_path), '```']
        new_text = {f'CODE:{fn}': [f'{line}'.rstrip() for line in source_code]}
        _write_to_readme(comment_pattern, new_text)
    else:
        logger.warning(f'Could not locate: {script_path}')

def _write_coverage_to_readme() -> None:
    """Read the coverage.json file and write a Markdown table to the README file."""
    try:
        from subprocess_tee import run  # noqa: S404
    except ImportError:
        from subprocess import run  # noqa: S404
    # Attempt to create the coverage file
    run('poetry run python -m coverage json')  # noqa: S603, S607

    coverage_path = (DIG.meta.path_project / 'coverage.json')
    if coverage_path.is_file():
        # Read coverage information from json file
        coverage = json.loads(coverage_path.read_text())
        # Collect raw data
        legend = ['File', 'Statements', 'Missing', 'Excluded', 'Coverage']
        int_keys = ['num_statements', 'missing_lines', 'excluded_lines']
        rows = [legend, ['--:'] * len(legend)]
        for file_path, file_obj in coverage['files'].items():
            rel_path = Path(file_path).resolve().relative_to(DIG.meta.path_project).as_posix()
            per = round(file_obj['summary']['percent_covered'], 1)
            rows.append([f'`{rel_path}`'] + [file_obj['summary'][key] for key in int_keys] + [f'{per}%'])
        # Format table for Github Markdown
        table_lines = [f"| {' | '.join([str(value) for value in row])} |" for row in rows]
        table_lines.extend(['', f"Generated on: {coverage['meta']['timestamp']}"])
        # Replace coverage section in README
        comment_pattern = re.compile(r'<!-- /?(COVERAGE) -->')
        _write_to_readme(comment_pattern, {'COVERAGE': table_lines})

# ----------------------------------------------------------------------------------------------------------------------
# mkdocs

def task_serve_fast() -> DoItTask:
    """Serve the site with `--dirtyreload` and open in a web browser.

    Note: use only for large projects. `poetry run mkdocs serve` is preferred for smaller projects

    Returns:
        DoItTask: doit task

    """
    return debug_task([
        (webbrowser.open, ('http://localhost:8000',)),
        LongRunning('poetry run mkdocs serve --dirtyreload'),
    ])

def task_deploy() -> DoItTask:
    """Deploy to Github `gh-pages` branch.

    Returns:
        DoItTask: doit task

    """
    return debug_task([LongRunning('poetry run mkdocs gh-deploy')])

# ----------------------------------------------------------------------------------------------------------------------
# Main Documentation Tasks

def task_document() -> DoItTask:
    """Build the HTML documentation.

    Returns:
        DoItTask: doit task

    """
    return debug_task([
        (_write_code_to_readme, ()),
        (_write_coverage_to_readme, ()),
        (_write_pkg_init, ()),
        'poetry run mkdocs build',  # --site-dir DIG.doc.path_out
    ])

def task_open_docs() -> DoItTask:
    """Open the documentation files in the default browser.

    Returns:
        DoItTask: doit task

    """
    path_doc_index = DIG.doc.path_out / DIG.meta.pkg_name / 'index.html'
    return debug_task([
        (open_in_browser, (path_doc_index,)),
    ])


"""
#3.	В массиве случайных целых чисел поменять местами минимальный
# и максимальный элементы.
"""

from random import randint
from random import shuffle

IN_LIST = list(set(randint(0, 30) for i in range(30)))
# определим переменные, минимальному зададим максимальное значение,
# а максимальному минимальное
MIN_EL = 30
MAX_EL = 0
MIN_EL_KEY = 0
MAX_EL_KEY = 0

# перемешаем "массив", чтобы было интереснее
shuffle(IN_LIST)
for key, value in enumerate(IN_LIST):

    # поиск максимального и минимального
    # элементов и запоминаем их индексы
    # min() и max() неинтересны
    if value > MAX_EL:
        MAX_EL = value
        MAX_EL_KEY = key
    elif value < MIN_EL:
        MIN_EL = value
        MIN_EL_KEY = key

    # при случае, когда переменная MAX_EL равна максимальному значению
    # а MIN_EL минимальному - прекращаем поиск
    if MAX_EL == 30 and MIN_EL == 0:
        break

print(f'Исходный массив {IN_LIST}')
# переставляем местами минимальное и максимальное значение
IN_LIST[MIN_EL_KEY], IN_LIST[MAX_EL_KEY] = IN_LIST[MAX_EL_KEY], IN_LIST[MIN_EL_KEY]

print(f'В списке минимальное и максимальное переставлены местами {IN_LIST}')


# Автор: Соколов Андрей Николаевич
# Задача-1:
# Напишите скрипт, создающий директории dir_1 - dir_9 в папке,
# из которой запущен данный скрипт.
# И второй скрипт, удаляющий эти папки.

# Задача-2:
# Напишите скрипт, отображающий папки текущей директории.

# Задача-3:
# Напишите скрипт, создающий копию файла, из которого запущен данный скрипт.
import os
import shutil
import sys
def md(directory_name):
    k=os.mkdir(directory_name)
    return k
def dir():
    z=[]
    k=os.listdir(os.getcwd())
    print(k)
    '''for i in range(0,len(k)):
        if(os.path.isdir(k[i])==True):
                   z.append(k[i])
                   return z'''
def md(directory_name):
    os.mkdir(directory_name)
def rd(directory_name):
    os.rmdir(directory_name)
def cd(directory_name):
    os.chdir(directory_name)
def dir1_9c(directory_name):
    os.mkdir("dir_1")
    os.mkdir("dir_2")
    os.mkdir("dir_3")
    os.mkdir("dir_4")
    os.mkdir("dir_5")
    os.mkdir("dir_6")
    os.mkdir("dir_7")
    os.mkdir("dir_8")
    os.mkdir("dir_9")
def dir1_9d(directory_name):
    os.rmdir("dir_1")
    os.rmdir("dir_2")
    os.rmdir("dir_3")
    os.rmdir("dir_4")
    os.rmdir("dir_5")
    os.rmdir("dir_6")
    os.rmdir("dir_7")
    os.rmdir("dir_8")
    os.rmdir("dir_9")
def copy(target_name):
    k=os.path.basename(sys.argv[0]).split(".")
    z=k[0]+'_copy.'+k[1]
    shutil.copy(os.path.basename(sys.argv[0]), z)
    print ("Копия успешно создана")
"""print("Выберите задание")
print("1а. Создать папки")
print("1б. Удалить папки")
print("2. Узнать папки текущей директории")
print("3. Создать копию файла")
a=input()
if(a=="1а"):
    os.mkdir("dir_1")
    os.mkdir("dir_2")
    os.mkdir("dir_3")
    os.mkdir("dir_4")
    os.mkdir("dir_5")
    os.mkdir("dir_6")
    os.mkdir("dir_7")
    os.mkdir("dir_8")
    os.mkdir("dir_9")
    print("Выполнено! Папки созданы")
elif(a=="1б"):
    os.rmdir("dir_1")
    os.rmdir("dir_2")
    os.rmdir("dir_3")
    os.rmdir("dir_4")
    os.rmdir("dir_5")
    os.rmdir("dir_6")
    os.rmdir("dir_7")
    os.rmdir("dir_8")
    os.rmdir("dir_9")
    print("Выполнено! Папки удалены")
elif(a=="2"):
    print("Вижу следующие папки:")
    k=os.listdir(os.getcwd())
    for i in range(0,len(k)):
        if(os.path.isdir(k[i])==True):
                   print(k[i])
elif(a=="3"):
    k=os.path.basename(sys.argv[0]).split(".")
    z=k[0]+'_copy.'+k[1]
    shutil.copy(os.path.basename(sys.argv[0]), z)
    print ("Копия успешно создана")
else:
    print("Такого задания нет")"""


from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from core.base_page import BasePage
import time, sys, logging
# logging.basicConfig(level=logging.INFO, stream=sys.stdout)
# log = logging.getLogger()
class LightningArchive(BasePage):
    def __init__(self, driver):
        """
        :type browser: selenium.webdriver.*
        """
        self.driver = driver
        self.logger = logging.getLogger(self.__class__.__name__)
        self.timeout = 15

    def navigate_to_archive(driver):
        """
        navigate to lightning Archive page
        verify amplitude is present
        """
        driver.logger.info('navigate to lightning archive')
        if not 'i18n_button_currenttab_td_middle' in driver.get_attribute("//SPAN[text()='Home']/..",
                                                                          "class"):
                driver.click("//SPAN[text()='Home']")
        driver.click("//a[contains(@href, 'contentId=301500')]")
        driver.click("//a[contains(.,'Lightning Inspection')]")
        return driver.is_present("//input[@name='amplitude']")

    def reset_lightning_archive_page(driver):
        """
        reset lightning retrieval criteria
        """
        driver.logger.info('reset lightning archive to initial state for test')
        if driver.is_selected("//input[@type='checkbox']"):
            driver.click("//input[@type='checkbox']")
        driver.click("//span[@aria-controls='fromDatetimepicker_dateview']")
        if driver.get_attribute("//input[@name='amplitude']", 'value') != '0':
            driver.clear("//input[@name='amplitude']")
            driver.type("//input[@name='amplitude']", '0')
        driver.clear("//input[@name='distance']")
        driver.click("//div[@class='pane_single']//select[normalize-space(.)='Any Positive Negative']//option[1]")

    def initial_lightning_archive_page_elements_exist(driver):
        """
        validation of Lightning Inspection page when we first landing there

        """
        driver.logger.info('validation of Lightning Inspection page when we first landing there')
        if driver.get_attribute("//input[@name='distance']", "value") != '':
            driver.clear("//input[@name='distance']")
        yield 'Select All' in driver.get_text("//html")
        yield 'lousiana' in driver.get_text("//html")
        yield driver.get_attribute("//select[@id='timeZone']", "value") == 'US/Central'
        yield driver.get_attribute("//select[@id='unit']", "value") == 'Metric'
        # assert driver.get_text("//select[@name='polarity']/option[@selected='selected']") == 'Any'
        yield driver.get_attribute("//input[@id='retrievalbtn']", "value") == 'Retrieve'
        yield 'To query the archive, select the areas or assets and the date/time range you want, and any variables you wish to filter on, and click Retrieve.' in driver.get_text("//html")

    def deselect_all_asset_area(driver):
        driver.click("//div[@id='treeview']//span[@class='k-checkbox' and @role='presentation']/input")
        # time.sleep(.5)
        driver.click("//div[@id='treeview']//span[@class='k-checkbox' and @role='presentation']/input")

    def select_asset_area(driver, area):
        if not driver.get_attribute("//div[@id='treeview']//span[contains(.,'"+area+"')]/..//input", "checked"):
            driver.click("//div[@id='treeview']//span[contains(.,'" + area + "')]/..//input")

    def search_archive_with_date_range(driver):
        """
        validation of Lightning Archive when a valid date range and areas are selected
        """
        driver.logger.info('validation of Lightning Archive when a valid date range and areas are selected')
        # driver.execute_script("document.getElementById('fromDatetimepicker').value='5/6/2017 12:00 AM'")
        driver.execute_script("document.getElementById('fromDatetimepicker').value='7/14/2017 12:00 AM'")
        driver.click("//span[@aria-controls='fromDatetimepicker_dateview']")
        time.sleep(1)
        for i in range(10):
            if 'false' in  driver.get_attribute("//div[@id='fromDatetimepicker_dateview']", "aria-hidden"):
                break
            else:
                time.sleep(.2)
        driver.click(
            "//div[@id='fromDatetimepicker_dateview']//a[@title='Friday, July 14, 2017']")
        time.sleep(1)
        for i in range(10):
            if 'true' in driver.get_attribute("//div[@id='fromDatetimepicker_dateview']", "aria-hidden"):
                break
            else:
                time.sleep(.2)
        # driver.execute_script("document.getElementById('toDatetimepicker').value='5/17/2017 12:00 AM'")
        driver.execute_script("document.getElementById('toDatetimepicker').value='7/15/2017 12:00 AM'")
        driver.click("//span[@aria-controls='toDatetimepicker_dateview']")
        time.sleep(1)
        for i in range(10):
            if 'false' in  driver.get_attribute("//div[@id='toDatetimepicker_dateview']", "aria-hidden"):
                break
            else:
                time.sleep(.2)
        driver.click("//div[@id='toDatetimepicker_dateview']//a[@title='Saturday, July 15, 2017']")
        time.sleep(1)
        for i in range(10):
            if 'true' in driver.get_attribute("//div[@id='toDatetimepicker_dateview']", "aria-hidden"):
                break
            else:
                time.sleep(.2)
        driver.click("//input[@id='retrievalbtn']")
        yield 'Select at least one area or asset.' in driver.get_text("//html")
        driver.select_asset_area('lousiana')
        driver.select_asset_area('texas')
        # if not driver.is_selected("//div[@id='treeview']//input"):
        #     driver.click("//div[@id='treeview']//input")
        yield 'To query the archive, select the areas or assets and the date/time range you want, and any variables you wish to filter on, and click Retrieve.' in driver.get_text("//html")
        driver.click("//input[@id='retrievalbtn']")
        yield driver.is_visible("//div[@class='k-loading-image']")

    def lightning_archive_search_results(driver):
        """
        verify column names and other controls on Lightning Archive after successful search
        """
        driver.logger.info('verify column names and other controls on Lightning Archive after successful search')
        yield "Area - Asset" in driver.get_text("//div[@class='k-grid-header']")
        yield "Distance" in driver.get_text("//div[@class='k-grid-header']")
        yield "Polarity" in driver.get_text("//div[@class='k-grid-header']")
        yield "Amplitude" in driver.get_text("//div[@class='k-grid-header']")
        yield "DateTime" in driver.get_text("//div[@class='k-grid-header']")
        yield "Latitude" in driver.get_text("//div[@class='k-grid-header']")
        yield "Longitude" in driver.get_text("//div[@class='k-grid-header']")
        yield "Probability" in driver.get_text("//div[@class='k-grid-header']")
        yield "Go to the first page" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        yield "Go to the previous page" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        yield "Go to the next page" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        yield "Go to the last page" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        yield driver.get_attribute("//input[@id='exportbtn']", "value") == "Export"

    def lightning_archive_filtering_by_distance(driver):
        """
        filter by distance and verify counts
        counts based on value returned on bottom of grid
        Hardcoded for reg_lightning in tst and PRE
        """
        driver.logger.info('filter by distance and verify counts')
        driver.wait_for_ajax()
        yield "280 of 280 items" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        driver.clear("//input[@name='distance']")
        driver.type("//input[@name='distance']", "200")
        driver.click("//input[@id='retrievalbtn']")
        driver.wait_for_ajax()
        time.sleep(.5)
        yield "135 of 135 items" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        driver.clear("//input[@name='distance']")
        driver.click("//input[@id='retrievalbtn']")
        for i in range(10):
            if driver.is_element_present("//div[@class='k-loading-image']"):
                time.sleep(1)
            else:
                break
        yield "280 of 280 items" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        ## filter by polarity

    def lightning_archive_filtering_by_polarity(driver):
        """
        filter by polarity and verify counts
        counts based on value returned on bottom of grid
        Hardcoded for alauson_wind2 in PRE
        """
        driver.logger.info('filter by polarity and verify counts')

        if not driver.is_selected(
                "//div[@class='pane_single']//select[normalize-space(.)='Any Positive Negative']//option[2]"):
            driver.click(
                "//div[@class='pane_single']//select[normalize-space(.)='Any Positive Negative']//option[2]")
            driver.click("//input[@id='retrievalbtn']")
            for i in range(10):
                if driver.is_element_present("//div[@class='k-loading-image']"):
                    time.sleep(1)
                else:
                    break
        yield "25 of 25 items" in driver.get_text(
                "//div[@class='k-pager-wrap k-grid-pager k-widget']")
        if not driver.is_selected(
                "//div[@class='pane_single']//select[normalize-space(.)='Any Positive Negative']//option[1]"):
            driver.click(
                "//div[@class='pane_single']//select[normalize-space(.)='Any Positive Negative']//option[1]")
            driver.click("//input[@id='retrievalbtn']")
        time.sleep(1)
        for i in range(10):
            if driver.is_element_present("//div[@class='k-loading-mask']"):
                time.sleep(1)
            else:
                break

        yield "280 of 280 items" in driver.get_text(
            "//div[@class='k-pager-wrap k-grid-pager k-widget']")

    def lightning_archive_table_sorting(driver):
        """
        Sort Lightning ARchive by column
        Sort, verify, re-sort, verify
        Hardcoded for alauson_wind2 in PRE
        """
        driver.logger.info('Sort Lightning Archive by column, verify, re-sort, verify')

        ## sorting table
        area = '1'
        distance = '2'
        polarity = '3'
        amplitude = '4'
        datetime = '5'
        latitude = '6'
        longitude = '7'
        probability = '8'

        yield driver.lightning_archive_table_sorting_validation(area, 'lousiana-lou_0047', 'texas-tex_1560')
        yield driver.lightning_archive_table_sorting_validation(distance, '22', '1624')
        yield driver.lightning_archive_table_sorting_validation(polarity, '-', '+')
        yield driver.lightning_archive_table_sorting_validation(amplitude, '2', '82')
        yield driver.lightning_archive_table_sorting_validation(datetime, '7/14/17 10:58:51.027 CDT',
                                                        '7/14/17 23:54:37.337 CDT')
        yield driver.lightning_archive_table_sorting_validation(latitude, '28.3025', '31.2555')
        yield driver.lightning_archive_table_sorting_validation(longitude, '-97.5072', '-91.3681')
        yield driver.lightning_archive_table_sorting_validation(probability, '75', '99')

    def lightning_archive_table_sorting_validation(driver, column, expected_first, expected_last):
        driver.logger.info('verify that table is sorting as expected')
        driver.click("//div[@class='k-grid-header']//th[" + column + "]/a")
        yield expected_first in driver.get_text("//tbody[@role='rowgroup']/tr/td[" + column + "]")
        yield expected_last in driver.get_text("//tbody[@role='rowgroup']/tr[last()]/td[" + column + "]")
        #### sort other direction
        driver.click("//div[@class='k-grid-header']//th[" + column + "]/a")
        yield expected_last in driver.get_text("//tbody[@role='rowgroup']/tr/td[" + column + "]")
        yield expected_first in driver.get_text("//tbody[@role='rowgroup']/tr[last()]/td[" + column + "]")


# -*- coding: utf-8 -*-
import unittest

from mysolr import SolrResponse
from os.path import join, dirname
import requests
import sys
import json

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

    def setUp(self):
        mock_file = join(dirname(__file__), 'mocks/spellquery')
        with open(mock_file) as f:
            raw_content = None
            if sys.version_info[0] == 3 and sys.version_info[1] == 2:
                raw_content = json.dumps(eval(f.read())).encode('utf-8')
            else:
                raw_content = f.read()
            self.response = SolrResponse()
            self.response.raw_content = raw_content
            self.response.status = 200
            self.response.parse_content()

    def tearDown(self):
        pass

    def test_query(self):
        self.assertNotEqual(self.response.spellcheck, None)

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


#!/usr/bin/python3
# -*- coding:UTF-8 -*-
import urllib.request as req
from urllib.parse import urlencode

API = 'http://www.mois.go.kr/gpms/view/jsp/rss/rss.jsp'

values = {
  'ctxcd' : '1012'
}

params = urlencode(values)
url = API+'?'+params
reqData = req.urlopen(url).read().decode('utf-8')
print(reqData)

#콜백함수 살펴보기! https://opentutorials.org/course/2136/11861
#과제 : 네이버 홈페이지 상단/우측 광고 저장하기


from converter.items import *
from datetime import datetime
from w3lib.html import remove_tags, replace_escape_chars
from converter.spiders.lom_base import LomBase
from converter.spiders.json_base import JSONBase
import json
import time
import logging
from html.parser import HTMLParser

# base spider mapping data via LRMI inside the html pages
# Please override the lrmi_path if necessary and add your sitemap_urls
class LrmiBase(LomBase, JSONBase):
    friendlyName = "LRMI-Header Based spider"
    lrmi_path = '//script[@type="application/ld+json"]//text()'
    sitemap_urls = []

    def __init__(self, **kwargs):
        LomBase.__init__(self, **kwargs)

    def getLRMI(self, *params, response):
        try:
            lrmi = list(
                map(
                    lambda x: json.loads(x.replace("\r", "").replace("\n", " ")),
                    response.xpath(self.lrmi_path).getall(),
                )
            )
        except:
            logging.warning(
                "failed parsing lrmi at " + response.url + ", please check source"
            )
            return None
        for l in lrmi:
            value = JSONBase.get(self, *params, json=l)
            if value != None:
                return HTMLParser().unescape(value)
        return None

    def parse(self, response):
        return LomBase.parse(self, response)

    def getId(self, response):
        return self.getLRMI("identifier", "url", "name", response=response)

    def getHash(self, response):
        if self.get("version") != None:
            return self.getLRMI("version", response=response)
        return time.time()

    def getBase(self, response):
        base = LomBase.getBase(self, response)
        base.add_value("thumbnail", self.getLRMI("thumbnailUrl", response=response))
        base.add_value(
            "lastModified",
            self.getLRMI("dateModified", "datePublished", response=response),
        )
        return base

    def getLOMGeneral(self, response):
        general = LomBase.getLOMGeneral(self, response)
        general.add_value("identifier", self.getLRMI("identifier", response=response))
        general.add_value("title", self.getLRMI("name", response=response))
        general.add_value("keyword", self.getLRMI("keywords", response=response))
        general.add_value("language", self.getLRMI("inLanguage", response=response))
        general.add_value(
            "description", self.getLRMI("description", "about", response=response)
        )
        return general

    def getValuespaces(self, response):
        valuespaces = LomBase.getValuespaces(self, response)
        valuespaces.add_value(
            "intendedEndUserRole",
            self.getLRMI("audience.educationalRole", response=response),
        )
        return valuespaces

    def getLOMEducational(self, response):
        educational = LomBase.getLOMEducational(self, response)
        educational.add_value(
            "typicalLearningTime", self.getLRMI("timeRequired", response=response)
        )
        return educational

    def getValuespaces(self, response):
        valuespaces = LomBase.getValuespaces(self, response)
        valuespaces.add_value(
            "learningResourceType",
            self.getLRMI("learningResourceType", response=response),
        )
        return valuespaces

    def getLicense(self, response):
        license = LomBase.getLicense(self, response)
        license.add_value("url", self.getLRMI("license", response=response))
        return license

    def getLOMTechnical(self, response):
        technical = LomBase.getLOMTechnical(self, response)
        technical.add_value("format", self.getLRMI("fileFormat", response=response))
        technical.add_value("size", self.getLRMI("ContentSize", response=response))
        url = self.getLRMI("url", response=response)
        if not url:
            url = response.url
        technical.add_value("location", url)
        return technical


#Given an integer n, return True if n is within 10 of either 100 or 200

def almost(n):
    list1 = range(90, 111)
    list2 = range(190, 211)
    if n in list1 or n in list2:
        return True

print(almost(35))
print(almost(156))
print(almost(198))


from datetime import datetime
from discord import errors as discord_errors, ActivityType

from bot.modules.ModuleInterface import ModuleInterface
from bot.modules.modtools import modtools_help
from bot.modules.helpers import is_integer, get_full_username

class ModToolsModule(ModuleInterface):
    async def purge(self, message):
        async def inner(m):
            args = m.content.split()

            await self.delete(m)
            if len(args) < 2:
                await self.say(
                    m.channel, "Please specify the number of messages to purge."
                )
            else:
                if m.mentions and len(args) >= 3:
                    purge_user = m.mentions[0]  # Find id of first mentioned user
                    if not is_integer(args[2]):
                        await self.say(
                            m.channel,
                            "Please specify a valid number of messages to purge. (1-100)",
                        )
                    else:
                        num = int(args[2])
                        await self._purge_messages(
                            message=message, purge_user=purge_user, num=num
                        )
                else:
                    if not is_integer(args[1]):
                        await self.say(
                            m.channel,
                            "Please specify a valid number of messages to purge. (1-100)",
                        )
                    else:
                        num = int(args[1])
                        try:
                            deleted = await m.channel.purge(limit=num)
                            await self.temp_message(
                                m.channel, "Purged {} messages.".format(len(deleted))
                            )
                        except discord_errors.HTTPException:  # Delete individually
                            async for log in m.channel.history(limit=num):
                                await self.delete(log)

        await self.auth_function(inner)(
            message, manage_guild_auth=True, require_non_cakebot=True
        )

    async def del_user_messages(self, message):
        async def inner(m):
            args = m.content.split()
            if len(args) == 1 or (
                len(args) == 2 and is_integer(args[1]) and args[1] == "1"
            ):
                await self.delete(m)
                async for log in m.channel.history(limit=500):
                    if log.author.id == m.author.id:
                        await self.delete(log)
                        break
            elif len(args) == 2:
                await self.delete(m)
                purge_user_id = m.author
                if not is_integer(args[1]):
                    await self.say(
                        m.channel,
                        "Please specify a valid number of messages to delete. (1-100)",
                    )
                else:
                    num = int(args[1])
                    await self._purge_messages(
                        message=m, purge_user=purge_user_id, num=num
                    )

        await self.auth_function(inner)(message, require_non_cakebot=True)

    async def _print_log_channel(self, message):
        log_channel = self.client.get_channel(
            self._get_log_channel_id(message.guild.id)
        )
        if log_channel:
            await self.temp_message(
                message.channel, "Log channel is: {}".format(log_channel.mention)
            )
        else:
            await self.temp_message(
                message.channel,
                "No log channel configured! Add one with `!logchannel set`",
            )

    async def _set_log_channel(self, message):
        async def inner(m):
            log_channel = self.client.get_channel(self._get_log_channel_id(m.guild.id))
            if log_channel:
                self._update_log_channel(m.guild.id, m.channel.id)
            else:
                self._add_log_channel(m.guild.id, m.channel.id)
            await self.say(
                m.channel, "Set {} as the log channel!".format(m.channel.mention)
            )
            self.conn.commit()

        await self.auth_function(inner)(
            message,
            manage_guild_auth=True,
            cakebot_perm="logchannel",
            require_non_cakebot=True,
        )

    async def log_channel(self, message):
        args = message.content.split()
        if len(args) == 1:
            await self._print_log_channel(message)
        else:
            if len(args) == 2 and args[1] == "set":
                await self._set_log_channel(message)

    async def handle_guild_channel_update(self, before, after):
        log_channel = self.client.get_channel(self._get_log_channel_id(before.guild.id))

        if log_channel:
            local_message_time = datetime.now().strftime("%H:%M:%S")

            channel_mention = before.mention
            if before.name != after.name:
                message = (
                    "[{}] {} *changed channel name*\n"
                    "Before: {}\n"
                    "After+: {}".format(
                        local_message_time, channel_mention, before.name, after.name
                    )
                )
                await self.say(log_channel, message)

            if hasattr(before, "topic") and before.topic != after.topic:
                message = (
                    "[{}] {} *changed topic contents*\n"
                    "Before: {}\n"
                    "After+: {}".format(
                        local_message_time, channel_mention, before.topic, after.topic
                    )
                )
                await self.say(log_channel, message)

    async def handle_edited_message(self, before, after):
        log_channel = self.client.get_channel(self._get_log_channel_id(before.guild.id))
        if log_channel and before.content != after.content:
            await self.say(
                log_channel, ModToolsModule._gen_edit_message_log(before, after)
            )

    async def handle_deleted_message(self, message):
        log_channel = self.client.get_channel(
            self._get_log_channel_id(message.guild.id)
        )

        if log_channel:
            await self.say(log_channel, ModToolsModule._gen_delete_message_log(message))

    async def handle_member_update(self, before, after):
        log_channel = self.client.get_channel(self._get_log_channel_id(before.guild.id))

        if log_channel:
            local_message_time = datetime.now().strftime("%H:%M:%S")
            before_roles = ", ".join(
                [role.name for role in before.roles if role.name != "@everyone"]
            )
            after_roles = ", ".join(
                [role.name for role in after.roles if role.name != "@everyone"]
            )

            if before.nick != after.nick:
                message = (
                    "[{}] {} *changed nickname*\n"
                    "Before: {}\n"
                    "After+: {}".format(
                        local_message_time,
                        get_full_username(before),
                        before.display_name,
                        after.display_name,
                    )
                )
                await self.say(log_channel, message)

            elif before_roles != after_roles:
                message = (
                    "[{}] {} *changed roles*\n"
                    "Before: {}\n"
                    "After+: {}".format(
                        local_message_time,
                        get_full_username(before),
                        before_roles,
                        after_roles,
                    )
                )
                await self.say(log_channel, message)

        # TODO UPDATE FOR discord.py 1.0+
        """
        before_activities = [a for a in before.activities if a.type == ActivityType.playing]
        after_activities = [a for a in after.activities if a.type == ActivityType.playing]
        if before_activities != after_activities:
            await self._auto_rename_voice_channel(after, before, after)
        """

    async def _auto_rename_voice_channel(self, before, after):
        # TODO UPDATE FOR discord.py 1.0+
        pass
        """
        if member.guild.id in (139345703800406016, 178312027041824768):  # Only use on main/dev server
            default_list = ["Gaming Channel 1", "Gaming Channel 2", "Gaming Channel 3", "Music Channel"]

            if after.channel:
                game_count = {}

                for member in after.channel.members:
                    member_activities = [a for a in member.activities if a.type == ActivityType.playing]
                    if member_activities:
                        if member_activities[0].name not in game_count:
                            game_count[member_activities[0].name] = 1
                        else:
                            game_count[member_activities[0].name] += 1
                if game_count:
                    # Select game with highest current players
                    new_channel_names = [key for m in [max(game_count.values())] for key, val in game_count.items() if
                                         val == m]
                    for new_channel_name in new_channel_names:
                        if new_channel_name:  # Non-blank new channel name, set as new channel name
                            await before.channel.edit(name=new_channel_name)
                            break
                else:
                    default_name = default_list[after.channel.position]
                    await after.channel.edit(name=default_name)

                if before.channel:
                    if len(before.channel.members) == 0:  # No more members, reset to default name
                        default_name = default_list[before.channel.position]
                        await before.channel.edit(name=default_name)

            # If voice channel being left has no more members, reset to default name
            if before.channel:
                if len(before.channel.members) == 0:
                    default_name = default_list[before.channel.position]
                    await before.channel.edit(name=default_name)
        """

    async def handle_voice_channel_update(self, member, before, after):
        await self._auto_rename_voice_channel(member, before, after)

    def _get_log_channel_id(self, server_id):
        self.c.execute(
            "SELECT channel_id FROM log_channel WHERE server_id = ?", (server_id,)
        )
        res = self.c.fetchone()
        if res:
            return int(res[0])
        return None

    def _add_log_channel(self, server_id, channel_id):
        self.c.execute(
            "INSERT INTO log_channel(server_id, channel_id) VALUES (?, ?)",
            (server_id, channel_id),
        )

    def _update_log_channel(self, server_id, channel_id):
        self.c.execute(
            "UPDATE log_channel SET channel_id = ? WHERE server_id = ?",
            (channel_id, server_id),
        )

    @staticmethod
    def _gen_edit_message_log(before, after):
        before_content = before.clean_content
        after_content = after.clean_content
        local_message_time = datetime.now().strftime("%H:%M:%S")

        if before.attachments:
            before_content += " " + before.attachments[0]["proxy_url"]
        if after.attachments:
            after_content += " " + after.attachments[0]["proxy_url"]

        log_message = (
            "[{}] {} *edited their message in* {}\n"
            "Before: {}\n"
            "After+: {}".format(
                local_message_time,
                get_full_username(before.author),
                before.channel.mention,
                before_content,
                after_content,
            )
        )
        return log_message

    @staticmethod
    def _gen_delete_message_log(message):
        clean_content = message.clean_content
        local_message_time = datetime.now().strftime("%H:%M:%S")
        username = get_full_username(message.author)

        if message.attachments:
            clean_content += " " + message.attachments[0]["proxy_url"]

        return "[{}] {} *deleted their message in* {}\n" "{}".format(
            local_message_time, username, message.channel.mention, clean_content
        )

    async def _purge_messages(self, message, purge_user, num):
        if 1 <= num <= 100:
            to_delete = []
            async for log in message.channel.history(limit=500):
                if log.author.id == purge_user.id:
                    to_delete.append(log)
                if len(to_delete) == num:  # Found num amount of messages
                    break

            if len(to_delete) == 1:
                await to_delete[0].delete()
            else:
                await message.channel.delete_messages(to_delete)
            await self.temp_message(
                message.channel,
                "Purged {} messages from {}.".format(len(to_delete), purge_user),
            )
        else:
            await self.temp_message(
                message.channel,
                "Please specify a valid number of messages to purge. (1-100)",
            )

    command_handlers = {
        "!logchannel": log_channel,
        "!purge": purge,
        "!del": del_user_messages,
    }

    help_entries = modtools_help.help_entries


# -*- coding: utf-8 -*-
# Copyright (C) 2006-2007  Vodafone España, S.A.
# Author:  Pablo Martí
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
Base classes for Controllers
"""

#from gtkmvc import Controller
from gui.contrib.gtkmvc import Controller

from wader.common.utils import revert_dict

TV_DICT = {0: 'inbox_treeview',
           1: 'inbox_treeview',
           2: 'drafts_treeview',
           3: 'sent_treeview',
           4: 'contacts_treeview'}

TV_DICT_REV = revert_dict(TV_DICT)

class WidgetController(Controller):
    """I maintain a list of widgets"""

    def __init__(self, model):
        super(WidgetController, self).__init__(model)
        self._widgets = []

    def hide_widgets(self):
        """Hides all the widgets that we're weeping track of"""
        for widget in self._widgets:
            try:
                widget.close()
            except:
                pass

        self._widgets = []

    def append_widget(self, widget):
        """Appends a widget to C{self._widgets}"""
        self._widgets.append(widget)


import tensorflow as tf

class padding_handler :
    """When a tensor is padded with dummy padding (to convert variable length to fixed length tensor),
    the padded string shouldn't contribute to the loss and gradients shouldn't be propagated into the padded string.
    padding_handler achieves this by identifing all the padded tokens and multiplying the embeddings of the pad by 0
    :arg
        padded_tensor : a 2-dim tensor, with padded tokens
        embeddings_dict : embeddings_dict to lookup the embeddings for tokens
        padding_index : index of the padded token
    :var
        tensor_embeddings : embeddings tensor of the padded_tensor (by looking up into the dict)
                            and paddings replaced by 0
        tensor_embeddings_sum : sum of tensor_embeddings along the first dimension
        tensor_embedding_mean : mean of the tensor_embeddings ignoring the padded tokens
        """

    def __init__(self, padded_tensor, embeddings_dict, padding_index = 0):
        self.padded_tensor = padded_tensor
        self._padding_mask = tf.not_equal(self.padded_tensor, padding_index)
        self._padding_mask = tf.cast(self._padding_mask, tf.float32)
        self._padding_mask = tf.expand_dims(self._padding_mask, 2)
        self._click_embeddings_pre_pad = tf.nn.embedding_lookup(embeddings_dict, self.padded_tensor)

        # num_non_pad is needed to compute the mean embedding, padded tokens should not contribute to the denominator of the mean
        self._num_non_pad = tf.reduce_sum(self._padding_mask, reduction_indices=[1])
        # when the entire padded_tensor is made of paddings the num_non_pad will be 0,
        # mean computation breaks in such cases, since num_non_pad is used in the denominator
        # Handling for the case to make num_non_pad 1 when num_non_pad is zero
        self._num_non_pad_zero_mask = tf.cast(tf.equal(self._num_non_pad, 0), tf.float32)
        self._num_non_pad = self._num_non_pad + self._num_non_pad_zero_mask

        self.tensor_embeddings = tf.multiply(self._click_embeddings_pre_pad, self._padding_mask)
        self.tensor_embeddings_sum = tf.reduce_sum(self.tensor_embeddings, reduction_indices=[1])
        self.tensor_embeddings_mean = self.tensor_embeddings_sum / self._num_non_pad
        self.num_non_pad = self._num_non_pad


import gc
import itertools
import matplotlib.pyplot as plt
from utils import *
import seaborn as sns

def call_api():
    print(np.array([1,2,3]))
    print(pd.DataFrame({1:['a', 'b']}))

class Data_Preprocess():
    def __init__(self):
        self.train = None
        self.test = None
        self.items = None
        self.shops = None

    def __call__(self, *args, **kwargs):
        self.load_data()
        self.data_cleansing()
        matrix = self.create_testlike_train()
        del (self.test)
        gc.collect()
        matrix = reduce_mem_usage(matrix, silent=False)
        oldcols = matrix.columns
        return matrix, oldcols, self.train, self.items, self.shops

    def load_data(self):
        self.items = pd.read_csv("../data/items.csv")
        self.shops = pd.read_csv("../data/shops.csv")
        self.train = pd.read_csv("../data/sales_train.csv")
        self.test = pd.read_csv("../data/test.csv")
        self.train["date"] = pd.to_datetime(self.train["date"], format="%d.%m.%Y")

    def data_cleansing(self):
        # Merge some duplicate shops
        self.train["shop_id"] = self.train["shop_id"].replace({0: 57, 1: 58, 11: 10, 40: 39})
        # Keep only shops that are in the test set
        self.train = self.train.loc[self.train.shop_id.isin(self.test["shop_id"].unique()), :]
        # Drop training items with extreme or negative prices or sales counts
        self.train = self.train[(self.train["item_price"] > 0) & (self.train["item_price"] < 50000)]
        self.train = self.train[(self.train["item_cnt_day"] > 0) & (self.train["item_cnt_day"] < 1000)]

    def create_testlike_train(self):
        indexlist = []
        for i in self.train.date_block_num.unique():
            x = itertools.product(
                [i],
                self.train.loc[self.train.date_block_num == i].shop_id.unique(),
                self.train.loc[self.train.date_block_num == i].item_id.unique(),
            )
            indexlist.append(np.array(list(x)))
        df = pd.DataFrame(
            data=np.concatenate(indexlist, axis=0),
            columns=["date_block_num", "shop_id", "item_id"],
        )

        # Add revenue column to self.train
        self.train["item_revenue_day"] = self.train["item_price"] * self.train["item_cnt_day"]
        # Aggregate item_id / shop_id item_cnts and revenue at the month level
        self.train_grouped = self.train.groupby(["date_block_num", "shop_id", "item_id"]).agg(
            item_cnt_month=pd.NamedAgg(column="item_cnt_day", aggfunc="sum"),
            item_revenue_month=pd.NamedAgg(column="item_revenue_day", aggfunc="sum"),
        )

        # Merge the grouped data with the index
        df = df.merge(
            self.train_grouped, how="left", on=["date_block_num", "shop_id", "item_id"],
        )

        if self.test is not None:
            self.test["date_block_num"] = 34
            self.test["date_block_num"] = self.test["date_block_num"].astype(np.int8)
            self.test["shop_id"] = self.test.shop_id.astype(np.int8)
            self.test["item_id"] = self.test.item_id.astype(np.int16)
            self.test = self.test.drop(columns="ID")
            df = pd.concat([df, self.test[["date_block_num", "shop_id", "item_id"]]])

        # Fill empty item_cnt entries with 0
        df.item_cnt_month = df.item_cnt_month.fillna(0)
        df.item_revenue_month = df.item_revenue_month.fillna(0)
        return df


from pyspark import SparkContext
import json as json
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

today = sys.argv[1]

def valid_jsontxt(content):
    if isinstance(content,unicode):
        res = content.encode("utf-8")
    else:
        res = str(content)
    return res.replace('\n', "").replace("\r", "").replace('\001', "").replace("\u0001", "")

def to_json_str_1(data):
    fields = [valid_jsontxt(i) for i in data.split("\001")]
    ob = {}
    ob.setdefault("number",fields[0])
    ob.setdefault("one",int(fields[1]))
    ob.setdefault("three",int(fields[2]))
    ob.setdefault("six",int(fields[3]))
    ob.setdefault("twelve",int(fields[4]))
    ob.setdefault("category",fields[5])
    return json.dumps(ob,ensure_ascii=False)

def to_json_str_2(data):
    fields = [valid_jsontxt(i) for i in data.split("\001")]
    ob = {}
    ob.setdefault("phone",fields[0])
    ob.setdefault("banknum",fields[1])
    ob.setdefault("idcard",fields[2])
    ob.setdefault("name",fields[3])
    ob.setdefault("time",fields[4])
    ob.setdefault("times",int(fields[5]))
    ob.setdefault("category",fields[6])
    return json.dumps(ob,ensure_ascii=False)

sc = SparkContext(appName="data_backflow_product" + today)
phone_idcard_stat =sc.textFile("/hive/warehouse/wl_service.db/t_lel_record_data_backflow_phone_idcard_res")\
        .map(lambda a:to_json_str_1(a))\
        .saveAsTextFile("/commit/data_backflow/datamart/stat_back/phone_idcard_stat_"+today)
stat_all = sc.textFile("/hive/warehouse/wl_service.db/t_lel_record_data_backflow_multifields_standard_res") \
    .map(lambda a:to_json_str_2(a)) \
    .saveAsTextFile("/commit/data_backflow/datamart/stat_back/stat_all_"+today)


from flask import url_for, render_template, request, redirect, Flask
from model import Player, Match, app, db, Play
from datetime import datetime

@app.route('/')
def index(name=None):
    return render_template("welcome.html")

@app.route('/show-players', methods=['GET'])
def show_players():
    players = Player.query.all()
    return render_template("player.html", players=players)

@app.route('/add-player', methods=['POST', 'GET'])
def add_player():
    name_player = request.form.get("name_player")
    lastname_player = request.form.get("lastname_player")
    player = Player(name=name_player, lastname=lastname_player)
    db.session.add(player)
    db.session.commit()
    return redirect('/show-players')

@app.route('/delete-player/<int:id_player>', methods=['GET'])
def delete_player(id_player):
    player = Player.query.filter_by(id=id_player).first()
    db.session.delete(player)
    db.session.commit()
    return redirect('/show-players')

@app.route('/show-matchs', methods=['GET'])
def show_matchs():
    matchs = Match.query.all()
    players = Player.query.all()
    return render_template("match.html", matchs=matchs, players=players)

@app.route('/add-match', methods=['POST', 'GET'])
def add_match():

    # Creation object Match
    match = Match()
    db.session.add(match)
    db.session.commit()

    # Get the id of the players
    team1player1_id = request.form.get("team1player1")
    team1player2_id = request.form.get("team1player2")
    team2player1_id = request.form.get("team2player1")
    team2player2_id = request.form.get("team2player2")

    # Get the results of the match
    result1 = request.form.get("result1")
    result2 = request.form.get("result2")

    # Cration association object : play for each player in the match
    team1play1 = Play(result=result1, match_id=match.id)
    team2play1 = Play(result=result2, match_id=match.id)

    # Set the player and add to the match
    team1play1.player = Player.query.filter_by(id=team1player1_id).first()
    team2play1.player = Player.query.filter_by(id=team2player1_id).first()

    match.plays.append(team1play1)
    match.plays.append(team2play1)

    # Set the second players if they played
    if team1player2_id:
        team1play2 = Play(result=result1)
        team1play2.player = Player.query.filter_by(id=team1player2_id).first()
        match.plays.append(team1play2)

    if team2player2_id:
        team2play2 = Play(result=result2)
        team2play2.player = Player.query.filter_by(id=team2player2_id).first()
        match.plays.append(team2play2)

    # Add in the database and commit
    db.session.add(match)
    db.session.commit()

    return redirect("/show-matchs")

@app.route('/delete-match/<int:id_match>', methods=['GET'])
def delete_match(id_match):
    plays = Play.query.filter_by(match_id=id_match).all()
    for play in plays:
        db.session.delete(play)
    match = Match.query.filter_by(id=id_match).first()
    db.session.delete(match)
    db.session.commit()
    return redirect('/show-matchs')


def palindrome(s):
    i = 0
    j = len(s)-1

    # Edgecase, len s <=2
    if len(s) == 1:
      return True

    while i < j:
        while not s[i].isalpha():
            i += 1
        while not s[j].isalpha():
            j -=1

        if s[i].lower() != s[j].lower():
            return False

        i += 1
        j -=1
    return True

print(palindrome("A man, a plan, a canal: Panama")) # True
# print(palindrome(".,")) # True
# print(palindrome(' Race car !!')) # True
# print(palindrome('raceacar')) # False
# print(palindrome('p')) # True
# # print(palindrome('.,')) # False
# print(palindrome('a.')) # True

def palindrome2(s):
  s = s.lower()
  s = "".join(letter for letter in s if letter.isalnum()).lower()
  if len(s) ==0:
    return False
  return s == s[::-1]

# print(palindrome2('.')) # True
# print(palindrome2('a.')) # True
# print(palindrome2('.,')) # False
# print(palindrome2('')) # True
# print(palindrome2(' ')) # False
# print(palindrome2(' Race car !!')) # True


from typing import List

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        """
        Determine if a 9x9 Sudoku board is valid.

        Only the filled cells need to be validated according to the following rules:

        - Each row must contain the digits 1-9 without repetition.
        - Each column must contain the digits 1-9 without repetition.
        - Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.

        :param board: a 2D matrix that represents a sudoku board
        :return: true if the sudoku is valid, false otherwise
        """
        return self.hash_table(board)

    def hash_table(self, board: List[List[str]]) -> bool:
        """
        T: O(n^2)
        A HashTable solution

        :param board: a 2D matrix that represents a sudoku board
        :return: true if the sudoku is valid, false otherwise
        """
        # a hash table [number : list of coordinates on the board]
        # O(n^2)
        num_to_coord = {str(key): [] for key in range(1, 10)}
        for row_idx in range(len(board)):
            for col_idx in range(len(board[0])):
                num = board[row_idx][col_idx]
                if num != '.':
                    num_to_coord[num].append((row_idx, col_idx))

        # find duplicates within each row, each col and each 3*3 block for each number
        # O(n^2)
        for num, coords in num_to_coord.items():
            # rows and cols for a number cannot have duplicates
            rows = [coord[0] for coord in coords]
            cols = [coord[1] for coord in coords]
            if len(rows) != len(set(rows)) or len(cols) != len(set(cols)):
                return False

            # check duplicates for every 3 * 3 block
            blocks_tpl = [(coord[0] // 3, coord[1] // 3) for coord in coords]
            if len(blocks_tpl) != len(set(blocks_tpl)):
                return False
        return True

    def brute_force(self, board: List[List[str]]) -> bool:
        """
        T: O(n^4)
        The brute force solution

        :param board: a 2D matrix that represents a sudoku board
        :return: true if the sudoku is valid, false otherwise
        """
        # check rows O(n^3)
        for row in board:  # O(n)
            for curr_idx in range(len(row)):  # O(n)
                curr = row[curr_idx]
                if curr != ".":
                    for compare_idx in range(len(row)):  # O(n)
                        compare = row[compare_idx]
                        if compare_idx != curr_idx and compare != "." and curr == compare:
                            return False

        # check cols O(n^3)
        for idx in range(len(board[0])):
            for curr_row_idx in range(len(board)):
                curr_row = board[curr_row_idx]
                curr = curr_row[idx]
                if curr == ".":
                    continue
                for compare_row_idx in range(len(board)):
                    compare_row = board[compare_row_idx]
                    compare = compare_row[idx]
                    if compare_row_idx != curr_row_idx and compare != "." and curr == compare:
                        return False

        # check 3*3 blocks O(n^4)
        for row_idx in range(0, len(board), 3):  # O(n)
            for col_idx in range(0, len(board[0]), 3):  # O(n)
                curr_block = []
                curr_block.extend(board[row_idx][col_idx: col_idx + 3])
                curr_block.extend(board[row_idx + 1][col_idx: col_idx + 3])
                curr_block.extend(board[row_idx + 2][col_idx: col_idx + 3])
                for curr_idx in range(len(curr_block)):  # O(n)
                    curr = curr_block[curr_idx]
                    if curr == ".":
                        continue
                    for compare_idx in range(len(curr_block)):  # O(n)
                        compare = curr_block[compare_idx]
                        if compare_idx != curr_idx and compare != "." and curr == compare:
                            return False

        return True

if __name__ == '__main__':
    # True example
    b = [["5", "3", ".", ".", "7", ".", ".", ".", "."],
         ["6", ".", ".", "1", "9", "5", ".", ".", "."],
         [".", "9", "8", ".", ".", ".", ".", "6", "."],
         ["8", ".", ".", ".", "6", ".", ".", ".", "3"],
         ["4", ".", ".", "8", ".", "3", ".", ".", "1"],
         ["7", ".", ".", ".", "2", ".", ".", ".", "6"],
         [".", "6", ".", ".", ".", ".", "2", "8", "."],
         [".", ".", ".", "4", "1", "9", ".", ".", "5"],
         [".", ".", ".", ".", "8", ".", ".", "7", "9"]]
    print(Solution().isValidSudoku(b))

    # False example
    # Comparing to the example above, only b[0][0] is changed from 5 to 8
    # Then the first col contains 2 8s. Invalid
    b = [['8', '3', '.', '.', '7', '.', '.', '.', '.'],
         ['6', '.', '.', '1', '9', '5', '.', '.', '.'],
         ['.', '9', '8', '.', '.', '.', '.', '6', '.'],
         ['8', '.', '.', '.', '6', '.', '.', '.', '3'],
         ['4', '.', '.', '8', '.', '3', '.', '.', '1'],
         ['7', '.', '.', '.', '2', '.', '.', '.', '6'],
         ['.', '6', '.', '.', '.', '.', '2', '8', '.'],
         ['.', '.', '.', '4', '1', '9', '.', '.', '5'],
         ['.', '.', '.', '.', '8', '.', '.', '7', '9']]
    print(Solution().isValidSudoku(b))

    # False example
    b = [['.', '.', '.', '.', '5', '.', '.', '1', '.'],
         ['.', '4', '.', '3', '.', '.', '.', '.', '.'],
         ['.', '.', '.', '.', '.', '3', '.', '.', '1'],
         ['8', '.', '.', '.', '.', '.', '.', '2', '.'],
         ['.', '.', '2', '.', '7', '.', '.', '.', '.'],
         ['.', '1', '5', '.', '.', '.', '.', '.', '.'],
         ['.', '.', '.', '.', '.', '2', '.', '.', '.'],
         ['.', '2', '.', '9', '.', '.', '.', '.', '.'],
         ['.', '.', '4', '.', '.', '.', '.', '.', '.']]
    print(Solution().isValidSudoku(b))


class Solution:
    # @param {integer[]} digits
    # @return {integer[]}
    def plusOne(self, digits):
        for i in range(len(digits)):
            string=str(digits[i])
            digits[i]=string
        string=''.join(digits)
        number=int(string)
        number=number+1
        string=str(number)
        num=[]
        for i in range(len(string)):
            if i<len(string):
                num.append(int(string[i]))
        return num


import collections
import threading

class BlockingQueueSemaphore:

    def __init__(self, size):
        self.size = size
        self.queue = collections.deque()
        self.lock = threading.Lock() # queue lock
        self.sem_size = threading.Semaphore(size) # protect overflow
        self.sem_avail = threading.Semaphore(0) # protect underflow

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

    def put(self, item):
        self.sem_size.acquire()
        # Deque is thread-safe, but here for pattern completeness
        with self.lock:
            self.queue.append(item)
        self.sem_avail.release()

    def get(self):
        self.sem_avail.acquire()
        # Deque is thread-safe, but here for pattern completeness
        with self.lock:
            item = self.queue.popleft()
        self.sem_size.release()
        return item


import pubchempy as pcp #api query
import pandas as pd #data loading
import os #to change dir
import requests #query uniprot
from Bio import SeqIO #parse fasta
from requests.adapters import HTTPAdapter #for retries
from requests.packages.urllib3.util.retry import Retry
import numpy as np #save dict
from scipy import sparse #for spare matrices
import math #to compute log10
import time #to sleep
from Bio.ExPASy import ScanProsite

def isNaN(num):
	return num != num

def requests_retry_session(
	###########
	#from: https://www.peterbe.com/plog/best-practice-with-retries-with-requests
	###########
	retries=3,
	backoff_factor=0.3,
	status_forcelist=(500, 502, 504),
    	session=None,
	):
	session = session or requests.Session()
	retry = Retry(
		total=retries,
		read=retries,
		connect=retries,
		backoff_factor=backoff_factor,
		status_forcelist=status_forcelist,
    		)
	adapter = HTTPAdapter(max_retries=retry)
	session.mount('http://', adapter)
	session.mount('https://', adapter)
	return session

#read drugcommons db
os.chdir("../data/Round2")
df=pd.read_csv("round_2_template.csv")
print(df.shape)

uniqueInchiKeys=df["Compound_InchiKeys"].unique()

####2.Fetch chemical structures AND other features
#declare feature lists
#this is the cactvs fingerprint dictionary using the inchi keys as keys
cactvsFingerprint_dict={}

#fetch canonical smiles
type='inchikey' #query by inchi key
otherFeaturesName=["atom_stereo_count", "bond_stereo_count", "charge","complexity", \
"covalent_unit_count","defined_atom_stereo_count", "exact_mass", "h_bond_acceptor_count", \
"h_bond_donor_count","heavy_atom_count","isotope_atom_count", "molecular_weight", \
"monoisotopic_mass","rotatable_bond_count", "tpsa", "xlogp"]

#Int: bonds, atoms, elements, fingerprint, molecular formula, record

#the following dataframe contains a set of nuelrical features collected from pubchem
#the columns are features from the otehrFeaturesName list
#the rowas are the drugs listed in keys_list variable by inchi keys
chemFeatMat= pd.DataFrame(columns=otherFeaturesName)
missingDrugs=0 #missing compounds
counter=0
keys_list=list()
for key in uniqueInchiKeys:
	print(key)
	if not isNaN(key):
		try:
			results = pcp.get_compounds(key, type)
		except Exception:
			time.sleep(60)
			results = pcp.get_compounds(key, type) # try again
		if results==[]:
			#for missing compounds we can search using another key such as name
			missingDrugs=missingDrugs+1
			print('missing')
			continue
		counter=counter+1
		#take the first result here, should be fine because smiles are unique I think
		#cactvs fingerprint
		cactvs=results[0].to_dict(properties=["fingerprint"])
		cactvsFingerprint_dict.update({key:cactvs['fingerprint']})
		#other features
		otherFeat=results[0].to_dict(properties=otherFeaturesName)
		chemFeatMat.loc[counter]=np.zeros(len(otherFeaturesName))
		chemFeatMat.loc[counter]=otherFeat.values()
		#keys name
		keys_list.append(key)

#print(smiles_dict)
print(missingDrugs) #414
np.save("Round2_cactvsFingerprint.npy", cactvsFingerprint_dict)
#save key names: these are the inchi key of drugs (rows)
#the columns names are the featrues name (otehrFetaures variable)
with open('Round2_drug_names.txt', 'w') as f:
    for key in keys_list:
        f.write("%s\n" % key)
#save the other features matrix
chemFeatMat.to_csv("Round2_chemFeatMat.csv",sep=',')

####3.Fetch protein sequence
seq_dict={}
uniqueProts=df["UniProt_Id"].unique()

missingProts=0
for prot in uniqueProts:
	if not isNaN(prot):
		print(prot)
		r=requests_retry_session().get('https://www.uniprot.org/uniprot/' + prot + '.fasta', timeout=10)
		if r.status_code != requests.codes.ok:
			missingProts=missingProts+1
			print('missing')
			continue
		#parsing fasta with biopython requeries a file
		text_file = open("prot.fasta", "w")
		text_file.write(r.text)
		text_file.close()

		for record in SeqIO.parse("prot.fasta", "fasta"):
			seq_dict.update({prot:record.seq})
		#deleting file
		os.remove("prot.fasta")

print(missingProts)
np.save('Round2_protStructure.npy', seq_dict)
####4.Extract kinase domain and ATP binding pocket
kinaseDict={}
ATPDict   ={}

amissing,kmissing,count=0,0,0
for key, sequence in seq_dict.items():
	count=count+1
	print(key)
	if count % 50 ==0:
		time.sleep(60) # sleep 1 mn for very 50 query to avoid timeout
	handle = ScanProsite.scan(seq=sequence)
	result = ScanProsite.read(handle)
	kinase,atp=0,0
	for i in range(len(result)): #I am looping over all results but there should be only one that ha$
		if result[i]['signature_ac']=='PS50011': # Protein kinase domain
			kinaseDict[key]=sequence[result[i]['start']:result[i]['stop']]
			kinase=1
		elif result[i]['signature_ac']=='PS00107': # ATP binding pocket
			ATPDict[key]=sequence[result[i]['start']:result[i]['stop']]
			atp=1
	if kinase==0:
		kmissing=kmissing+1
		print('kinase missing')
	if atp==0:
		amissing=amissing+1
		print('atp missing')

print(kmissing)
print(amissing)
np.save('Round2_kinaseDomain.npy', kinaseDict)
np.save('Round2_ATPDomain.npy', ATPDict)


"""@package RPi_Master_Script

Takes pictures and checks for faces in each picture. If there was a face found
it uploads the picture to thte server and also sends a message to the server
announcing that a file was uploaded and provides the name of said file

Communication via serial to and from an arduino is providing a constant stream of
information about the movement of the robot and any obsticals in its way.
this data is then processed and the instructions are given back to the arduino
for it to then carry out

"""
import cv2
import numpy as np
import picamera
from picamera.array import PiRGBArray
import time
import FTPUpload as ftp
import os
import socket
import sys
import RPi.GPIO as GPIO
from threading import Thread
import serial

start_stop = 38  #GPIO start_stop pin
kill = 40; #GPIO pin for killing

#sets up GPIO settings
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(start_stop, GPIO.OUT)
GPIO.setup(kill, GPIO.OUT)
GPIO.output(start_stop, GPIO.HIGH)

SocketConnected = False

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ser = None

ArduinoState = 1
ArduinoPreviousState = 0

isTakingPictures = True

def cameraStream():
    """Documentation for the cameraStream thread

    Takes a picture and starts a new faceDetector thread for facial detection.
    Does this repeatedly until the program ends

    """
    global isTakingPictures
    camera = picamera.PiCamera()
    camera.vflip = False

    fileCounter = 0

    while True:
        while isTakingPictures:
            filename = 'image' + str(fileCounter) + '.jpg'
            faceThread = Thread(target=faceDetector, args=(filename,)) #comma is not a mistake
            camera.capture(filename)
            fileCounter += 1;
            faceThread.start()
            time.sleep(0.1)

    camera.close()

def faceDetector(filename):
    """Documentation for the faceDetector thread

    Opens an image file and searches for a face by means of haarcascades. If a face is found it uploads the picture to the server.
    It also changes the state of GPIO start_stop to LOW
    """

    global isTakingPictures

    fFace2 = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.0.0/data/haarcascades_cuda/haarcascade_frontalface_default.xml')
    image = np.asarray(cv2.imread(filename))
    grayScale = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    numFaces = len(fFace2.detectMultiScale(grayScale, 1.3, 4))

    if numFaces > 0: #if there is a face
        Stop()
        ftp.Upload(filename)
        print('IMAGE')
        WriteToServer('IMAGE ' + filename)
        GPIO.output(start_stop, GPIO.LOW) #changes state of start_stop to LOW
        isTakingPictures = False

    os.remove(filename)

def socketListener():
    """Documentation for the socketListener Class

    Connects to the server and listenes for messages,
    then changes the states of the GPIO pins to match the status sent by the server
    as well as sending serial data to the arduino communicating the message to the arduino
    """
    TCP_IP = '192.168.168.1'
    TCP_PORT = 10000
    BUFFER_SIZE = 1024

    global s
    global SocketConnected
    global isTakingPictures

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #assigns the variable s to a generic socket
    SocketConnected = True
    print('Socket Created')

    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #assigns the variable s to a generic socket
            s.connect((TCP_IP, TCP_PORT)) #connects s to the server at the IP and PORT
            SocketConnected = True
        except Exception as e:
            #print(e)
            SocketConnected = False
        while SocketConnected:
            try:
                msg = s.recv(BUFFER_SIZE) #gets bytes from server and convers to text
                msgString = msg.decode('ASCII')
                print(msg)
                if(len(msgString) > 0):
                    if(msgString == 'STOP'):
                       print('Stopping');
                       GPIO.output(start_stop, GPIO.LOW)
                       #Stop()
                    if (msgString == 'START'):
                       print('Started')
                       GPIO.output(start_stop, GPIO.HIGH)
                       #DriveForward()
                    if(msgString == 'KILL'):
                        print('Killing')
                        GPIO.output(kill, GPIO.HIGH)
                        #Stop()
                    if(msgString == 'SAFE'):
                        print('Safe')
                    if(msgString == 'UNSAFE'):
                        print('Unsafe')
                        #Stop()
                    if(msgString == 'MATCHYES'):
                        print('Match')
                        isTakingPictures = False
                        #Stop()
                    if(msgString == 'MATCHNO'):
                        print('Not a Match');
                        isTakingPictures = True

            except:
                print('Disconected')
                SocketConnected = False
                s.close()
                break
def DriveForward():
    global ser
    try:
        ser.write('120,69\n'.encode('ASCII'))
    except Exception as e:
        None

def DriveBackward():
    global ser
    try:
        ser.write('60,160\n'.encode('ASCII'))
    except Exception as e:
        None;

def Stop():
    global ser
    try:
        ser.write('0,0\n'.encode('ASCII'))
    except Exception as e:
        None

def WriteToServer( str ):
    global SocketConnected
    global s

    if SocketConnected:
        str = str + ' DEBUG '
        s.send(str.encode('ASCII'))
        time.sleep(0.2)

def WriteToArduino(str):
    global ser

    try:
        str = str + '/n'
        ser.writeline(str.encode('ASCII'))
    except Exception as e:
        None

def ReadSerial():
    """Documentation for the ReadSerial Thread
    Serial data is read in through /dev/tty/ACM0 which is what the arduino communicates on
    The data is passed to a function for parsing"""

    global ser
    global s
    global SerialConnected

    print('>> Connecting to Arduino via Serial. . .')

    while True:
        try:
            ser = serial.Serial('/dev/ttyACM0', 115200)
            SerialConnected = True
        except Exception as e:
            None
            #print(e)

        while ser is not None:
            ser.flushInput() #Flush buffer to avoid backing up data and lagging updates
            mesg = ""
            try:
                mesg = ser.readline().decode('ASCII')
            except Exception as e:
                print(e)
                if 'disconnected' in str(e):
                    ser = None
                print('Attempting Reconection. . .')
            finally:
                HandleSerial(mesg)

def HandleSerial(mesg):
    """Documentation for HandleSerial Function

    This function parses each bit of data and sends it to the server with the proper formmating"""
    global ser

    #Arduino Message Format: x1,y1,x2,y2,IR,SONIC,VOLTAGE

    mesg = mesg[:-2] #to remove junk character from end of string
    print(mesg)

    if 'hello' in mesg and ser is not None: # checks for Arduino handshake
        ser.write('world\n'.encode('ASCII'))
        print('>> Wrote \'world\' to Arduino')

    data = mesg.split(',') #splits message into each feild

    if len(data) == 7: #if the message made it in full - with all 7 fields
        UpdateLocation(data[0], data[1], data[2], data[3], data[4], data[5])
        WriteToServer('VOLTAGE ' + data[6])

def UpdateLocation(x1, y1, x2, y2, ir, sonic):
    """Documentation for UpdateLocation Function

    This function is for calculation of the angle that the robot is facing
    and sending that back to the server"""

    global ArduinoState
    global ArduinoPreviousState

    #dX dY Angle

    dX = x2 - x1
    dY = y2 - y1
    theta = Math.atan2(dY, dX)
    WriteToServer('LOCATION ' + str(dX) +  ' ' + str(dY) + ' ' + str(theta))

    #only update the arduino when something changes
    ArduinoPreviousState = ArduinoState

    if int(ir) > 1000 or float(sonic) < 7:
        ArduinoState = 0
    else:
        ArduinoState = 1

    if ArduinoPreviousState is not ArduinoState:
        if ArduinoState is 0:
            Stop()
        elif ArduinoState is 1:
            DriveForward()

#####################################################################
#Thread

camStr = Thread(target=cameraStream, args=())
socList = Thread(target=socketListener, args=())
serRead = Thread(target=ReadSerial, args=())

camStr.start()
socList.start()
serRead.start()


# %load q02_Max_important_feature/build.py
# Default imports
from greyatomlib.advanced_linear_regression.q01_load_data.build import load_data

# We have already loaded the data for you
data_set, X_train, X_test, y_train, y_test = load_data('data/house_prices_multivariate.csv')
target_variable = 'SalePrice'
n = 4
# Write your code here
def Max_important_feature(data_set, target_variable = 'SalePrice', n = 4):
    CorrelationAll = data_set.corr()
    CorrelationAll = CorrelationAll[target_variable].sort_values(ascending=False).drop(labels=[target_variable])
    Correlation = CorrelationAll.nlargest(n=4).index.values
    return Correlation


from enum import Enum
import json

class SlackMessageBuilder(object):
    """
    Construct messages that Slack will understand.

    See the SlackMessageBuilder to test the messages:
    https://api.slack.com/docs/formatting/builder?msg=%7B%22text%22%3A%22I%20am%20a%20test%20message%20http%3A%2F%2Fslack.com%22%2C%22attachments%22%3A%5B%7B%22text%22%3A%22And%20here%27s%20an%20attachment!%22%7D%5D%7D

    """
    class FormatType(Enum):
        """
        Enumeration describing the text formatting options available in Slack.
        See https://api.slack.com/docs/formatting.
        """
        BOLD = "*"
        ITALIC = "_"
        PRE_FORMATTED = "```"
        CODE = "`"
        STRIKE = "~"

    class ColorNames(Enum):
        """
        Slack formatting accepts hex colours, but they also have these pre-defined names.
        """
        GOOD = "good"
        WARNING = "warning"
        DANGER = "danger"

    @staticmethod
    def build_slack_response(in_channel=None, text="", attachments_list=None):
        """
        Builds up a response in the way Slack expects. Replies to Slack's GET requests.
        :param in_channel: whether the response should go to everyone in the channel or just to the user that requested
        it.
        :param text: the main text of the message. Doesn't allow formatting.
        :param attachments_list: 0 or more Slack attachments.
        :return: a JSON response to send to slack.
        """
        response = {
            "text": text
        }

        if in_channel:
            response_type = "in_channel" if in_channel else "Ephemeral"
            response["response_type"] = response_type

        if attachments_list:
            response["attachments"] = attachments_list

        return response

    @staticmethod
    def build_slack_post_data(slack_response):
        """
        Used for sending messages to post to Slack's incoming web hooks.

        :param text: the main text of the message. No formatting.
        :param attachments_list: optional list of formatted attachments.
        :return: the Slack message.
        """
        return json.dumps(slack_response)

    @staticmethod
    def build_slack_attachment(fallback="",
                               title="",
                               title_link="",
                               pretext="",
                               author_name="",
                               author_link="",
                               author_icon="",
                               text="",
                               image_url="",
                               color="",
                               footer="",
                               footer_icon="",
                               ts="",
                               fields_list=None):
        """
        It is possible to create more richly-formatted messages using Attachments.
        Messages can have zero or more attachments, defined as an array.
        Each hash in that array will contain multiple properties:

        :param fallback: This text will be used in clients that don't show formatted text (eg. IRC, mobile
        notifications) and should not contain any markup.
        :param title: The title is displayed as larger, bold text near the top of a message attachment.
        :param title_link: By passing a valid URL in the title_link parameter (optional), the title text will be
        hyperlinked.
        :param pretext: This is optional text that appears above the message attachment block.
        :param author_name: Small text used to display the author's name
        :param author_link: A valid URL that will hyperlink the author_name text mentioned above. Will only work if
        author_name is present
        :param author_icon: A valid URL that displays a small 16x16px image to the left of the author_name text. Will
        only work if author_name is present.
        :param text: This is the main text in a message attachment, and can contain standard message markup.
        The content will automatically collapse if it contains 700+ characters or 5+ linebreaks, and will display a
        "Show more..." link to expand the content.
        :param image_url: A valid URL to an image file that will be displayed inside a message attachment. We currently
        support the following formats: GIF, JPEG, PNG, and BMP.
        :param color: An optional value that can either be one of good, warning, danger, or any hex color code
        (eg. #439FE0). This value is used to color the border along the left side of the message attachment.
        :param footer: Add some brief text to help contextualize and identify an attachment. Limited to 300 characters,
        and may be truncated further when displayed to users in environments with limited screen real estate.
        :param footer_icon: To render a small icon beside your footer text, provide a publicly accessible URL string in
        the footer_icon field. You must also provide a footer for the field to be recognized.
        :param ts: By providing the ts field with an integer value in "epoch time", the attachment will display an
        additional timestamp value as part of the attachment's footer.
        :param fields_list: see __build_slack_attachment_field__
        :return:
        """
        return {
            "fallback": fallback,
            "title": title,
            "title_link": title_link,
            "pretext": pretext,
            "author_name": author_name,
            "author_link": author_link,
            "author_icon": author_icon,
            "text": text,
            "image_url": image_url,
            "color": color,
            "footer": footer,
            "footer_icon": footer_icon,
            "ts": ts,
            "fields": fields_list,
            "mrkdwn_in": ["text", "pretext", "value", "fields"]
        }

    @staticmethod
    def __build_slack_attachment_field__(title, value, is_short):
        """
        Fields are defined as an array, and hashes contained within it will be displayed in a table inside the message
        attachment.
        Note: this is one way to simulate a table, but there are no rows - so you'd have to put newlines. Generally
        seems to show two 'columns' on one line. You could simulate rows by putting in new lines in each field's
        value property - however, if you want those 'rows' to match another field be wary that text wraps on smaller
        screens. Best way to simulate a simple table would be to use preformmated attachment text with tabs.

        :param title: Shown as a bold heading above the value text. It cannot contain markup and will be escaped for
        you.
        :param value: The text value of the field. It may contain standard message markup (see details below) and must
        be escaped as normal. May be multi-line.
        :param is_short: An optional flag indicating whether the value is short enough to be displayed side-by-side
        with other values.

        :return: dictionary representing an attachment field.
        """
        return {"title": title, "value": value, "short": is_short}

    @staticmethod
    def __build_slack_link__(link_text, link_href):
        """
        Make a link in slack's markdown.
        :param link_text: the link text.
        :param link_href: the URL.
        :return: the link formatted for slack.
        """
        return "<{href}{text}>".format(text=link_text, href=link_href)

    @staticmethod
    def format_string(message, format_type=""):
        """
        Just a simple method to format a string with one of the formatting types.
        :param message: the message to format.
        :param format_type: the type of formatting to surround the text in - see FormatType enum.
        :return: the formatted text.
        """
        return "{format}{message}{format}".format(format=format_type, message=message)


# test = None

# if(test == None):
# 	print('Test');

#Dictionary - словарь

test = {
	"Key_1" : "Value_1",
	"Key_2" : {
		"Key_2_1" : "Value_2_1"
	},
	"Key_3" : "Value_3",
	125 	: "Сто двадцять пять"
}

if 125 in test:
	print("Isset")
else:
	print("No isset")

if 125 not in test:
	print("No isset")
else:
	print("Isset")

try:
	print(test["Key_1"])
except KeyError:
	print("Not key!")

contacts = {
	"Yura" : "+380955455789",
	"Roma" : "+380955587895",
	"Ostap" : "+380955412369"
}

testing = input('Enter name : ')

if testing in contacts:
	print('contact isset ' + contacts[testing])
else:
	print('contact no isset')

print(contacts.get("Yura", "Not nomer!"))
print(contacts.get("Yura1", "Not nomer!"))