#!/usr/bin/env python
# coding: utf-8

# In[133]:

import pandas as pd
import requests
from bs4 import BeautifulSoup as bs
from datetime import datetime

# In[134]:

link = "https://www.walmart.com/reviews/product/14898365"

# In[135]:

page=requests.get(link)

# In[136]:

page

# In[137]:

page.content

# In[101]:

soup = bs(page.content, "html.parser")

# In[102]:

print(soup.prettify())

# In[189]:

date = soup.find_all("span", class_="review-date-submissionTime")

# In[190]:

date

# In[192]:

datenew=[]
for i in range(0,len(date)):
    datenew.append(date[i].get_text())
datenew

# In[197]:

revdate=[]
for i in range(0, len(date)):
    revdate.append(datetime.strptime(date[i].get_text(), '%B %d, %Y'))
#    dates.skey = lambda date: datetime.strptime(date, '%B %d, %Y'))

# In[ ]:

# In[198]:

revdate.sort()

# In[ ]:

# In[199]:

revdate

# In[200]:

from datetime import datetime

# In[201]:

def printDates(dates):

    for i in range(len(dates)):
        print(dates[i])

if __name__ == "__main__":

    dates = ['April 10 2021',
             'April 26 2020',
             'April 3 2021',
             'August 21 2020',
             'August 29 2020',
             'August 3 2020',
             'December 21 2020',
             'December 23 2020',
             'December 27 2020',
             'January 12 2014',
             'July 13 2021',
             'July 27 2020',
             'July 27 2021',
             'July 28 2021',
             'July 29 2020',
             'March 12 2021',
             'March 17 2021',
             'May 13 2021',
             'May 16 2020',
             'September 3 2020']
dates.sort(key = lambda date: datetime.strptime(date, '%B %d %Y'))

# In[202]:

printDates(dates)

# In[203]:

title = soup.find_all("h3", class_="review-title font-bold")

# In[204]:

title

# In[205]:

titlenew=[]
for i in range(0, len(title)):
    titlenew.append(title[i].get_text())

# In[206]:

titlenew

# In[207]:

body= soup.find_all("p")

# In[208]:

body

# In[209]:

bodynew=[]
for i in range(0, len(body)):
    bodynew.append(body[i].get_text())

# In[210]:

bodynew

# In[211]:

stars = soup.find_all("div", class_="arranger stars stars-small arranger--items-center")

# In[212]:

stars

# In[213]:

starsnew=[]
for i in range(0, len(stars)):
    starsnew.append(stars[i].get_text())

# In[214]:

starsnew

# In[215]:

purchaser = soup.find_all("div", class_="verified")

# In[216]:

purchaser

# In[217]:

purchasernew=[]
for i in range(0, len(purchaser)):
    purchasernew.append(purchaser[i].get_text())

# In[218]:

purchasernew

# In[219]:

revdate
titlenew
bodynew
starsnew
purchasernew

# In[230]:

hs = pd.DataFrame()

# In[231]:

hs["Sorted Date"]=dates

# In[232]:

hs

# In[234]:

hs.to_csv(r"E:\webscrapdatesort.csv", index=True)

# In[221]:

hs["Review Date"]=pd.Series(datenew)
hs["Title"]=pd.Series(titlenew)
hs["Review Body"]=pd.Series(bodynew)
hs["Stars"]=pd.Series(starsnew)
hs["Purchaser"]=pd.Series(purchasernew)

# In[222]:

hs

# In[233]:

hs.to_csv(r"E:\webscrapwallmart.csv", index=True)

# In[ ]:

# In[ ]:


#поиск сложноподчиненных предложений
inwords=open('words.txt')
inconst=open('const.txt')
intext=open('text.txt')
outfile=open('outfile.txt', 'w')

import re
output=[]
words=[]
const=[]
for line in inwords.readlines(): words.append(line.strip())
for line in inconst.readlines(): const.append(line.strip())
text=intext.read()
ortext=re.sub('\n','',text).split('. ')
worktext=list(map(lambda x: x.lower(), ortext))
#проверка 1
for i in range(0, len(worktext)):
    for j in range(0, len(words)):
        temp=re.findall(words[j]+' ', worktext[i])
        if temp!=[] and ',' in worktext[i]:
            #print(temp)
            strtemp=''.join(temp)
            #print(strtemp)
            t=ortext[i].index(strtemp)
            ortext[i] = re.sub(ortext[i][t:t + len(strtemp)], ortext[i][t:t + len(strtemp)].upper(), ortext[i])
            #print(ortext[i])
            if ortext[i] not in output: output.append(ortext[i])
#проверка 2
for i in range(0, len(worktext)):
    for j in range (0, len(const), 2):
        temp1=re.findall(const[j]+' ', worktext[i])
        temp2=re.findall(const[j+1]+' ', worktext[i])
        if temp1!=[] and temp2!=[] and ',' in worktext[i]:
            strtemp1=''.join(temp1)
            strtemp2 = ''.join(temp2)
            t1=ortext[i].index(strtemp1)
            t2 = ortext[i].index(strtemp2)
            ortext[i] = re.sub(ortext[i][t1:t1 + len(strtemp1)], ortext[i][t1:t1 + len(strtemp1)].upper(), ortext[i])
            ortext[i] = re.sub(ortext[i][t2:t2 + len(strtemp2)], ortext[i][t2:t2 + len(strtemp2)].upper(), ortext[i])
            if ortext[i] not in output: output.append(ortext[i])
outfile.write(str(output))
print(output)
inwords.close()
inconst.close()
intext.close()
outfile.close()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, shutil
import unittest
import tb, tempfile
from tbcore import get_random_string, ComponentSourceException, ComponentException, Project

class TestTbLinkedProject(unittest.TestCase):

    def setUp(self):
        self.root_dir = tempfile.mkdtemp()
        #shutil.copytree("mock/mockprojects", self.root_dir, dirs_exist_ok=True)
        #self.d_orig = os.getcwd()
        #os.chdir(self.root_dir)

    def tearDown(self):
        shutil.rmtree(self.root_dir)

    def test_mock_project_a_reads_foo(self):

        pdira = "mock/mockprojects/a"
        cdir = "component_a1"

        a_tfstore = get_random_string(10)

        retcode = tb.main(["tb", "apply", cdir, '--force',
                           '--project-dir', pdira,
                           '--set-var', "tfstate_store_path_a={}".format(os.path.join(self.root_dir, a_tfstore))])
        assert retcode == 0

        retcode = tb.main(["tb", "refresh", cdir,
                           '--project-dir', pdira,
                           '--key', 'foo',
                           '--set-var', "tfstate_store_path_a={}".format(os.path.join(self.root_dir, a_tfstore))])
        assert retcode == 0

        project = Project(git_filtered=False,  wdir=pdira, project_vars={
            "tfstate_store_path_a" : os.path.join(self.root_dir, a_tfstore)
        })
        project.set_component_dir(cdir)
        project.setup_component_tfstore()
        assert project.component.get_output("foo") == "bar"

        assert "random_string" in project.component.get_output_keys()

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


#!/usr/bin/env python
# -*-coding:utf-8-*-
# @Time : 2017/11/1 ~ 2019/9/1
# @Author : Allen Woo
import time
from werkzeug.routing import BaseConverter
from apps.app import mdbs, cache
from apps.utils.format.time_format import time_to_utcdate

class RegexConverter(BaseConverter):
    """
    让路由支持正则
    """

    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]

def push_url_to_db(app):
    """
    同步url到数据库
    :param app:
    :return:
    """
    # back up
    now_time = time.time()
    ud = time_to_utcdate(now_time, "%Y%m%d%H")
    days_ago_t = now_time - 86400 * 7
    days_ago_d = time_to_utcdate(days_ago_t, "%Y%m%d%H")
    if not mdbs["sys"].dbs["sys_urls_back"].find_one({"backup_time": ud}):
        sys_urls = list(mdbs["sys"].dbs["sys_urls"].find({}, {"_id": 0}))
        for sys_url in sys_urls:
            sys_url["backup_time"] = ud
        mdbs["sys"].dbs["sys_urls_back"].insert(sys_urls)
        mdbs["sys"].dbs["sys_urls_back"].delete_many({"backup_time": {"$lt": days_ago_d}})

    for rule in app.url_map.iter_rules():
        if rule.endpoint.startswith("api.") or rule.endpoint.startswith("open_api."):
            type = "api"
        else:
            continue
        now_time = time.time()
        r = mdbs["sys"].dbs["sys_urls"].find_one({"url": rule.rule.rstrip("/")})
        if not r:
            # 不存在
            mdbs["sys"].dbs["sys_urls"].insert_one({
                "url": rule.rule.rstrip("/"),
                "methods": list(rule.methods),
                "endpoint": rule.endpoint,
                "custom_permission": {},
                "type": type,
                "create": "auto",
                "update_time": now_time})

        elif r:
            new_methods = list(rule.methods)
            old_methods = r["methods"]
            if old_methods:
                new_methods.extend(old_methods)
            else:
                old_methods = []
            new_methods = list(set(new_methods))
            mdbs["sys"].dbs["sys_urls"].update_one({"_id": r["_id"]},
                                               {"$set": {"methods": new_methods,
                                                         "endpoint": rule.endpoint,
                                                         "type": type,
                                                         "create": "auto",
                                                         "update_time": now_time}})
            new_methods.sort()
            old_methods.sort()
            if new_methods != old_methods or rule.endpoint != r["endpoint"]:
                # 清理缓存
                cache.delete_autokey(fun="get_sys_url", key_base64=False, db_type="redis", url=r["url"])

    """
    # 清理已不存在的api
    # 时间7天是为了防止多台服务器同时启动时造成误删
    """
    ut = time.time() - 86400*7
    mdbs["sys"].dbs["sys_urls"].delete_many(
        {"type": {"$ne": "page"}, "update_time": {"$lt": ut}})


"""
bartocsuggest is a Python module that suggests vocabularies given a list of words based on the BARTOC FAST API
(https://bartoc-fast.ub.unibas.ch/bartocfast/api).

Documentation available at: https://bartocsuggest.readthedocs.io/en/latest/

Codebase available at: https://github.com/MHindermann/bartocsuggest
"""

from __future__ import annotations
from typing import List, Optional, Dict, Union, Tuple
from time import sleep
from os import path
from datetime import datetime
from annif_client import AnnifClient

from .utility import _Utility
from .jskos import _Concept, _ConceptBundle, _ConceptMapping, _ConceptScheme, _Concordance, _LanguageMap

import Levenshtein
import requests
import urllib.parse

FAST_API = "https://bartoc-fast.ub.unibas.ch/bartocfast/api"

class _Result:
    """ A BARTOC FAST result.

    :param uri: the result's URI
    :param pref_label: https://www.w3.org/2009/08/skos-reference/skos.html#prefLabel, defaults to None
    :param alt_label: https://www.w3.org/2009/08/skos-reference/skos.html#altLabel, defaults to None
    :param hidden_label: https://www.w3.org/2009/08/skos-reference/skos.html#hiddenLabel, defaults to None
    :param definition: https://www.w3.org/2009/08/skos-reference/skos.html#definition, defaults to None
    """

    def __init__(self,
                 uri: str,
                 pref_label: str = None,
                 alt_label: str = None,
                 hidden_label: str = None,
                 definition: str = None) -> None:
        self.uri = uri
        self.pref_label = pref_label
        self.alt_label = alt_label
        self.hidden_label = hidden_label
        self.definition = definition

    def get_concept(self) -> _Concept:
        """ Return the result as JSKOS concept. """

        concept = _Concept(uri=self.uri)
        labels = ["pref_label", "alt_label", "hidden_label", "definition"]  # i.e., relevant attributes

        for label in labels:
            label_value = self.__getattribute__(label)
            if label_value is None:
                continue
            else:
                concept.__setattr__(label, _LanguageMap({"und": label_value}))

        return concept

class _Query:
    """ A BARTOC FAST query, see https://bartoc-fast.ub.unibas.ch/bartocfast/api (version 1.0.3).

    :param concept: the input JSKOS concept
    :param searchword: the search word, defaults to None
    :param maxsearchtime: the threshold search time in seconds, defaults to 5
    :param duplicates: toggle keeping duplicates between resources, defaults to True
    :param disabled: the disabled resources, defaults to None
    :param response: the query response, defaults to None
    """

    def __init__(self,
                 concept: _Concept,
                 searchword: str = None,
                 maxsearchtime: int = 5,
                 duplicates: bool = True,
                 disabled: List[str] = None,
                 response: Union[Dict, requests.models.Response] = None) -> None:
        self.concept = concept
        if searchword is None:
            self.searchword = concept.get_pref_label()
        else:
            self.searchword = searchword
        self.maxsearchtime = maxsearchtime
        self.duplicates = duplicates
        if disabled is None:
            self.disabled = ["Research-Vocabularies-Australia", "Loterre"]
        else:
            self.disabled = disabled
        self.response = response

    def send(self) -> None:
        """ Send query as HTTP request to BARTOC FAST API.

        The response is saved to the response attribute.
        """

        payload = self.get_payload()
        try:
            self.response = requests.get(url=FAST_API, params=payload)
        except requests.exceptions.ConnectionError:
            print(f"requests.exceptions.ConnectionError! Trying again in 5 seconds...")
            sleep(5)
            self.send()

    def dict2result(self, dictionary: dict) -> _Result:
        """ Transform a raw result into a result object.

        :param dictionary: the raw result
        """

        result = _Result(uri=dictionary.get("uri"),
                         pref_label=dictionary.get("prefLabel"),
                         alt_label=dictionary.get("altLabel"),
                         hidden_label=dictionary.get("hiddenLabel"),
                         definition=dictionary.get("definition"))

        return result

    def update_sources(self, session: Session) -> None:
        """ Update the score vectors of a session's sources based on the query response.

        :param session: the active session
        """

        # extract results from response:
        response = self.get_response()
        results = response.get("results")

        if results is None:
            return None

        for dictionary in results:
            # transform raw result into object:
            result = self.dict2result(dictionary)
            # get source, add if new:
            name = self.result2name(result)
            source = session._get_source(name)
            if source is None:
                source = _Source(name)
                session._add_source(source)
            # update source's score vector:
            source.levenshtein_vector.update_score(self.concept, result)

    def result2name(self, result: _Result) -> str:
        """ Return the source name based on the result.

         :param result: a result
         """
        parsed_uri = urllib.parse.urlparse(result.uri)

        # define (categories of) aggregated sources and split them accordingly:
        if parsed_uri.netloc in ["bartoc-skosmos.unibas.ch", "data.ub.uio.no", "vocab.getty.edu"]:
            return self.uri2name(parsed_uri, n=1)
        elif parsed_uri.netloc in ["isl.ics.forth.gr", "linkeddata.ge.imati.cnr.it", "www.yso.fi"]:
            return self.uri2name(parsed_uri, n=2)
        elif parsed_uri.netloc in ["vocabs.ands.org.au"]:
            return self.uri2name(parsed_uri, n=5)
        else:
            return parsed_uri.netloc

    def uri2name(self, parsed_uri: urllib.parse.ParseResult, n: int = 1) -> str:
        """ Return the source name based on the parsed URI.

        The source name is a substring of the URI.

        :param parsed_uri: the path
        :param n: the number of identifying components on the path
        """

        path = parsed_uri.path
        components = path.split("/")
        name = parsed_uri.netloc

        i = 1
        while True:
            if i > n:
                break
            else:
                identifier = components[i]
                name = name + f"/{identifier}"
                i += 1

        return name

    def get_payload(self) -> Dict:
        """ Return the payload (i.e., parameters passed in the URL) of the query. """

        if self.duplicates is True:
            duplicates = "on"
        else:
            duplicates = "off"

        payload = {"searchword": self.searchword,
                   "maxsearchtime": self.maxsearchtime,
                   "duplicates": duplicates,
                   "disabled": self.disabled}

        return payload

    def get_response(self, verbose: bool = False) -> Dict:
        """ Return the query response.

        :param verbose: toggle status updates along the way, defaults to False
        """

        # fetch response if not available:
        if self.response is None:
            self.send()
            if verbose is True:
                print(self.response.text)
            return self.response.json()

        # response is cached:
        elif self.response is requests.models.Response:
            return self.response.json()

        # response is preloaded:
        else:
            return self.response

    @classmethod
    def make_query_from_json(cls, json_object: Dict) -> Optional[_Query]:
        """ Return query object initialized from a preloaded query response.

         :param json_object: the preloaded response
         """

        # extract query parameters from json object:
        context = json_object.get("@context")
        url = context.get("results").get("@id")
        parsed_url = urllib.parse.urlparse(url)
        parsed_query = (urllib.parse.parse_qs(parsed_url.query))

        # make query object from instantiated parameters and json object:
        try:
            searchword = parsed_query.get("searchword")[0]
            maxsearchtime = parsed_query.get("maxsearchtime")[0]
            duplicates = parsed_query.get("duplicates")[0]
            if duplicates == "on":
                duplicates = True
            else:
                duplicates = False
            disabled = parsed_query.get("disabled")
            scheme = _Utility.words2scheme([searchword])
            concept = _Utility.word2concept(word=searchword, scheme_uri=scheme.uri)
            query = _Query(concept=concept,
                           maxsearchtime=int(maxsearchtime),
                           duplicates=duplicates,
                           disabled=disabled,
                           response=json_object)
        except IndexError:
            return None

        return query

class ScoreType:
    """ A score type.

    All score types are relative to a specific vocabulary and a list of words.
    There are four score type classes: :class:`bartocsuggest.Recall`, :class:`bartocsuggest.Average`,
    :class:`bartocsuggest.Coverage`, :class:`bartocsuggest.Sum`.
    Use the help method on these classes for more information.
    """

    pass

class Recall(ScoreType):
    """ The number of words over a vocabulary's coverage.

    The lower the better (minimum is 1). See https://en.wikipedia.org/wiki/Precision_and_recall#Recall.

    For example, for words [a,b,c] and coverage 2, recall is len(words)/coverage = len([a,b,c])/2 = 1.5.
    """

    @classmethod
    def __str__(cls) -> str:
        return "recall"

class Average(ScoreType):
    """ The average over a vocabulary's match scores.

    The lower the the better (minimum is 0).
    The score of a match is defined by the Levenshtein distance between word and match.

    For example, for scores [1,1,4], the average is scores/len(scores) = (1+1+4)/3 = 2.
    """

    @classmethod
    def __str__(cls) -> str:
        return "score_average"

class Coverage(ScoreType):
    """ The number of a vocabulary's matches in the list of words.

    Note that this is dependent on the sensitivity parameter of :meth:`bartocsuggest.Session.suggest`.

    For example, for words [a,b,c] and vocabulary matches a,c, the coverage is a,c in [a,b,c] = 2.
    """

    @classmethod
    def __str__(cls) -> str:
        return "score_coverage"

class Sum(ScoreType):
    """ The sum over a vocabulary's match scores.

    The lower the average the better (minimum is 0).
    The score of a match is defined by the Levenshtein distance between word and match.

    For example, for scores [1,1,4], the sum is (1+1+4) = 6.
    """

    @classmethod
    def __str__(cls) -> str:
        return "score_sum"

class Session:
    """ Vocabulary suggestion session using the BARTOC FAST API.

    :param words: the input words (list of strings, or path to XLSX file, or JSKOS concept scheme)
    :param preload_folder: the path to the preload folder, defaults to None
    :param language: the language of the words given as RFC 3066 language tag, defaults to "und" (for undefined)
    """

    def __init__(self,
                 words: Union[List[str], str, _ConceptScheme],
                 preload_folder: str = None,
                 language: str = "und") -> None:
        self._scheme = self._set_input(words, language)
        self._preload_folder = preload_folder
        self._sources = []

    def _set_input(self, words: Union[list, str, _ConceptScheme], language) -> _ConceptScheme:
        """ Set words as JSKOS concept scheme.

        If the words are not yet a JSKOS concept scheme, they are transformed into one.

        :param words: the input words (list of strings, or path to XLSX file, or JSKOS concept scheme)
        :param language: the language of the words given as RFC 3066 language tag, defaults to "und"
        """

        if type(words) is list:
            scheme = _Utility.words2scheme(words=words, language=language)
        elif type(words) is _ConceptScheme:
            scheme = words
        else:
            scheme = _Utility.load_file(words)

        print(f"{words} loaded successfully, {len(scheme.concepts)} words detected.")
        return scheme

    def _add_source(self, source: _Source) -> None:
        """ Add a source to the session.

         :param source: the source to be added
         """

        self._sources.append(source)

    def _get_source(self, uri: str) -> Optional[_Source]:
        """ Return source by URI.

         :param uri: the URI
         """

        for source in self._sources:
            if uri == source.uri:
                return source

        return None

    def _fetch_and_update(self, remote: bool = True, maximum: int = 100000, verbose: bool = False) -> None:
        """ Fetch query responses and update sources.

        :param remote: toggle fetching responses from BARTOC FAST or preload folder, defaults to True
        :param maximum: the maximum number of responses fetched, defualts to 10000
        :param verbose: toggle status updates along the way, defaults to False
        """

        if verbose is True:
            print(f"Querying BARTOC FAST...")

        counter = 0

        # fetch from preload:
        if remote is False:
            while True:
                if counter > maximum:  # debug
                    break
                try:
                    filename = f"query_{counter}"
                    json_object = _Utility.load_json(self._preload_folder, filename)
                    query = _Query.make_query_from_json(json_object)
                    query.update_sources(self)
                    counter += 1
                except FileNotFoundError:
                    break

        # fetch from remote:
        else:
            for concept in self._scheme.concepts:
                if counter > maximum:  # debug
                    break
                if verbose is True:
                    searchword = concept.get_pref_label()
                    print(f"Fetching '{searchword}'...", end=" ")
                query = _Query(concept=concept)
                query.update_sources(self)
                counter += 1
                if verbose is True:
                    print("done.")

        if verbose is True:
            print("Responses collected.")

    def _update_rankings(self, sensitivity: int, verbose: bool = False):
        """ Update the sources' rankings.

        :param sensitivity: the used sensitivity
        :param verbose: toggle status updates along the way, defaults to False
        """

        if verbose is True:
            print("Updating source rankings...")

        for source in self._sources:
            source.update_ranking(self, sensitivity, verbose)

        if verbose is True:
            print("Source rankings updated.")

    def _make_suggestion(self, sensitivity: int, score_type: ScoreType, verbose: bool = False) -> Suggestion:
        """ Return sources from best to worst base on score type.

        :param sensitivity: the used sensitivity
        :param score_type: the used score type
        :param verbose: toggle status updates along the way, defaults to False
        """

        if verbose is True:
            print("Calculating suggestions...", end=" ")

        # determine sorting direction:
        high_to_low = False
        if score_type is Recall:
            high_to_low = True

        # sort sources by score type:
        contenders = []
        disqualified = []
        for source in self._sources:
            if getattr(source.ranking, score_type.__str__()) is None:
                disqualified.append(source)
            else:
                contenders.append(source)
        contenders.sort(key=lambda x: getattr(x.ranking, score_type.__str__()), reverse=high_to_low)

        suggestion = Suggestion(self._scheme, contenders, sensitivity, score_type)

        if verbose is True:
            print("calculated.")
            suggestion.print()

        return suggestion

    def preload(self,
                max: int = 100000,
                min: int = 0,
                verbose: bool = False) -> None:
        """ Preload responses.

        For each word in :attr:`self.words`, a query is sent to the BARTOC FAST API.
        The response is saved to :attr:`self.preload_folder`. Use this method for batchwise handling of large
        (>100) :attr:`self.words`.

        :param max: stop with the max-th word in self.words, defaults to 100000
        :param min: start with min-th word in self.words, defaults to 0
        :param verbose: toggle running comment printed to console, defaults to False
        """

        if self._preload_folder is None:
            print("ERROR: No preload folder specified! Specify preload folder before calling Session.preload!")
            return None
        elif path.exists(self._preload_folder) is False:
            raise FileExistsError(self._preload_folder)

        counter = 0

        for concept in self._scheme.concepts:

            if counter > max:  # debug
                break
            elif counter < min:
                counter += 1
                continue

            if verbose is True:
                searchword = concept.get_pref_label()
                print(f"Preloading word number {counter + 1} '{searchword}'...", end=" ")
            _Utility.save_json(_Query(concept=concept).get_response(), self._preload_folder, f"query_{counter}")
            counter += 1
            if verbose is True:
                print(f"done.")

        if verbose is True:
            print(f"{(counter - min)} responses preloaded.")

    def suggest(self,
                remote: bool = True,
                sensitivity: int = 1,
                score_type: ScoreType = Recall,
                verbose: bool = False) -> Suggestion:
        """ Suggest vocabularies based on :attr:`self.words`.

        :param remote: toggle between remote BARTOC FAST querying and preload folder, defaults to True
        :param sensitivity: set the maximum allowed Levenshtein distance between word and result, defaults to 1
        :param score_type: set the score type on which the suggestion is based, defaults to :class:`bartocsuggest.Recall`
        :param verbose: toggle running comment printed to console, defaults to False
        """
        self._fetch_and_update(remote=remote, verbose=verbose)
        self._update_rankings(sensitivity=sensitivity, verbose=verbose)
        suggestion = self._make_suggestion(sensitivity=sensitivity, score_type=score_type, verbose=verbose)

        return suggestion

class AnnifSession(Session):
    """ Wrapper for the Annif REST API based on the Annif-client module.

    Annif indexes the input text based on the project identifier with an optional limit or threshold.
    Use this Session to get vocabulary suggestions for full texts instead of words.
    :class:`bartocsuggest.AnnifSession` inherits its methods preload and suggest from :class:`bartocsuggest.Session`.

    :param text: the input text
    :param project_id: the project identifier
    :param limit: the maximum number of results to return, defaults to None
    :param threshold: the minimum score threshold, defaults to None
    """

    def __init__(self,
                 text: str,
                 project_id: str,
                 limit: int = None,
                 threshold: int = None,
                 preload_folder: str = None) -> None:
        self._scheme = self._set_input(text, project_id=project_id, limit=limit, threshold=threshold)
        self._preload_folder = preload_folder
        self._sources = []

    def _set_input(self, text: str, **kwargs) -> _ConceptScheme:
        """ Use words suggested by Annif on the basis of text to set JSKOS Concept Scheme.

        :param text: input text
        :param **kwargs: required or optional Annif parameters
        """

        annif = AnnifClient()
        annif_suggestion = annif.suggest(project_id=kwargs.get("project_id"),
                                         text=text,
                                         limit=kwargs.get("limit"),
                                         threshold=kwargs.get("threshold"))

        scheme = _Utility.annif2jskos(annif_suggestion, kwargs.get("project_id"))

        return scheme

class _Score:
    """ A score.

    The score's value is derived by a comparison between a concept and a BARTOC FAST result.

    :param value: the score's numerical value, defaults to None
    :param comparandum: a concept, defaults to None
    :param comparans: a result, defaults to None
    """

    def __init__(self,
                 value: int = None,
                 comparandum: _Concept = None,
                 comparans: _Result = None) -> None:
        self.value = value
        self.comparandum = comparandum
        self.comparans = comparans

class _Vector:
    """ A vector of scores.

    :param vector: the vector
    """

    def __init__(self,
                 vector: List[_Score] = None) -> None:
        if vector is None:
            self._vector = []
        else:
            self._vector = vector

    def get_vector(self) -> Optional[List[_Score]]:
        """ Return the vector (if any). """

        if len(self._vector) is 0:
            return None
        else:
            return self._vector

class _LevenshteinVector(_Vector):
    """ A vector of Levenshtein distance scores. """

    def make_score(self, concept: _Concept, result: _Result) -> Optional[_Score]:
        """ Make the Levenshtein score for a result.

        The Levenshtein score is the minimum Levenshtein distance over all labels and languages.

        :param concept: the concept from which the distance is measured
        :param result: contains matches to which the distance is measured
        """

        scores = []
        labels = ["pref_label", "alt_label", "hidden_label", "definition"]  # i.e., relevant attributes

        for label in labels:
            label_string = result.__getattribute__(label)
            if label_string is None:
                continue
            distances = []
            # check if label_string has more than one language:
            for foundword in label_string.split(";"):
                distance = Levenshtein.distance(concept.get_pref_label().lower(), foundword.lower())
                distances.append((distance, foundword))
            # add the best foundword and distance tuple per label over all languages:
            scores.append(min(distances))

        # catch malformed (= empty labels) results:
        try:
            min(scores)
        except ValueError:
            return None

        return _Score(value=min(scores)[0], comparandum=concept, comparans=result)

    def update_score(self, concept: _Concept, result: _Result) -> None:
        """ Update the Levenshtein vector with the Levenshtein score for the concept and result.

        :param concept: the concept from which the distance is measured
        :param result: contains matches to which the distance is measured
        """

        score = self.make_score(concept, result)
        if score is None:
            pass
        else:
            self._vector.append(score)

class _Ranking:
    """ The ranking of a source given its best Levenshtein vector.

    :param score_sum: the sum of all scores in the vector, defaults to None
    :param score_average: the vector's average score, defaults to None
    :param score_coverage: the number of scores in the vector, defaults to None
    :param recall: the recall, defaults to None
    """

    def __init__(self,
                 score_sum: int = None,
                 score_average: float = None,
                 score_coverage: int = None,
                 recall: float = None) -> None:
        self.score_sum = score_sum
        self.score_average = score_average
        self.score_coverage = score_coverage
        self.recall = recall

class _Analysis:
    """ A collection of methods for analyzing score vectors. """

    @classmethod
    def make_score_sum(cls, vector: _LevenshteinVector) -> Optional[int]:
        """ Return the sum of all scores in the vector.

        The lower the sum the better.

        :param vector: the vector
        """

        try:
            return sum(score.value for score in vector.get_vector())
        except (TypeError, AttributeError):
            return None

    @classmethod
    def make_score_average(cls, vector: _LevenshteinVector) -> Optional[float]:
        """ Return the vector's average score.

        The lower the average the better.

        :param vector: the vector
        """

        score_sum = cls.make_score_sum(vector)
        if score_sum is None:
            return None
        else:
            return round(score_sum / len(vector.get_vector()), 2)

    @classmethod
    def make_score_coverage(cls, vector: _LevenshteinVector) -> Optional[int]:
        """ Return the number of scores in the vector.

        :param vector: the vector
        """

        try:
            return len(vector.get_vector())
        except (TypeError, AttributeError):
            return None

    @classmethod
    def make_best_vector(cls, vector: _LevenshteinVector, sensitivity: int) -> Optional[_LevenshteinVector]:
        """ Return the best vector of a vector.

        The best vector has the best score for each search word.

        :param vector: the vector
        :param sensitivity: the used sensitivity
        """

        # collect all unique searchwords in vector:
        initial_vector = vector.get_vector()
        if initial_vector is None:
            return None
        else:
            searchwords = set(score.comparandum.get_pref_label() for score in initial_vector)

        # choose best (=lowest) score for each seachword:
        best_vector = []
        for word in searchwords:
            scores = [score for score in initial_vector if score.comparandum.get_pref_label() == word]
            best_score = sorted(scores, key=lambda x: x.value)[0]
            # check sensitivity:
            if best_score.value <= sensitivity:
                best_vector.append(best_score)

        return _LevenshteinVector(best_vector)

    @classmethod
    def make_recall(cls, relevant: int, retrieved: int) -> Optional[float]:
        """ Return recall.

        See https://en.wikipedia.org/wiki/Precision_and_recall#Recall.

        :param relevant: the number of relevant hits
        :param retrieved: the number of retrieved hits
        """

        try:
            return retrieved / relevant
        except (TypeError, AttributeError):
            return None

class _Source:
    """ A BARTOC FAST source.

    :param uri: the source's URI
    :param levenshtein_vector: the source's Levenshtein vector, defaults to None
    :param ranking: the source's ranking, defaults to None
    """

    def __init__(self,
                 uri: str,
                 levenshtein_vector: _LevenshteinVector = None,
                 ranking: _Ranking = None) -> None:
        self.uri = uri
        if levenshtein_vector is None:
            self.levenshtein_vector = _LevenshteinVector()
        self.ranking = ranking

    def update_ranking(self, session: Session, sensitivity: int, verbose: bool = False) -> None:
        """ Update the sources ranking. """

        if verbose is True:
            print(f"Updating {self.uri}...", end=" ")

        best_vector = _Analysis.make_best_vector(self.levenshtein_vector, sensitivity)

        self.ranking = _Ranking()
        self.ranking.score_sum = _Analysis.make_score_sum(best_vector)
        self.ranking.score_average = _Analysis.make_score_average(best_vector)
        self.ranking.score_coverage = _Analysis.make_score_coverage(best_vector)
        self.ranking.recall = _Analysis.make_recall(len(session._scheme.concepts), self.ranking.score_coverage)

        if verbose is True:
            print("updated.")

class Suggestion:
    """ A suggestion of vocabularies.

    :param _scheme: the input concept scheme
    :param _vocabularies: the suggested vocabularies
    :param _sensitivity: the used sensitivity
    :param _score_type: the used score type
    """

    def __init__(self,
                 _scheme: _ConceptScheme,
                 _vocabularies: List[_Source],
                 _sensitivity: int,
                 _score_type: ScoreType) -> None:
        self._scheme = _scheme
        self._sources = _vocabularies
        self._sensitivity = _sensitivity
        self._score_type = _score_type

    def get(self, scores: bool = False, max: int = None) -> Union[List[str], List[Tuple[str, int]]]:
        """ Return the suggested vocabularies sorted from best to worst.

        :param scores: toggle returning results and their scores, defaults to False
        :param max: limit the number of suggestions to max, defaults to None
        """

        results = []
        for source in self._sources:
            try:
                if len(results) + 1 > max:
                    break
            except TypeError:
                pass
            if scores is True:
                results.append([source.uri, getattr(source.ranking, self._score_type.__str__())])
            else:
                results.append(source.uri)

        return results

    def print(self):
        """ Print the suggestion to the console. """

        print(f"{len(self._sources)} vocabularies given sensitivity {self._sensitivity}."
              f" From best to worst (vocabularies with no matches are excluded):")
        for source in self._sources:
            print(f"{source.uri}, {self._score_type.__str__()}: {getattr(source.ranking, self._score_type.__str__())}")

    def get_score_type(self) -> ScoreType:
        """ Return the suggestion's score type. """

        return self._score_type

    def get_sensitivity(self) -> int:
        """ Return the suggestion's sensitivity. """

        return self._sensitivity

    def _get_concordance(self, vocabulary_uri: str = None) -> Optional[_Concordance]:
        """ Return the concordance between the input words and the vocabulary.

        If no vocabulary URI is selected, the most highly suggested vocabulary is used.
        To see the suggested vocabularies and their URIs, use the print method of this class.

        :param vocabulary_uri: the URI of the vocabulary, defaults to None
        """

        # get the correct source (if any) given vocabulary_name:
        vocabulary = None
        if vocabulary_uri is None:
            vocabulary = self._sources[0]
        else:
            for source in self._sources:
                if source.uri == vocabulary_uri:
                    vocabulary = source
        if vocabulary is None:
            print("The selected vocabulary does not exist!")
            return None

        # make the best vector (on which the ranking of self._vocabularies is based):
        best_vector = _Analysis.make_best_vector(vocabulary.levenshtein_vector, self._sensitivity)

        # make concordance:
        source_scheme = self._scheme
        target_scheme = _ConceptScheme(uri=vocabulary.uri)
        concordance = _Concordance(from_scheme=source_scheme, to_scheme=target_scheme, mappings=set())

        # make concept mappings:
        for score in best_vector.get_vector():
            source_concept = score.comparandum
            target_concept = score.comparans.get_concept()
            source_member_set = {source_concept}
            target_member_set = {target_concept}
            source_bundle = _ConceptBundle(member_set=source_member_set)
            target_bundle = _ConceptBundle(member_set=target_member_set)

            mapping = _ConceptMapping(from_=source_bundle,
                                      to=target_bundle,
                                      from_scheme=source_scheme,
                                      to_scheme=target_scheme)

            concordance.mappings.add(mapping)

        return concordance

    def print_concordance(self, vocabulary_uri: str = None) -> None:
        """ Print the concordance as JSKOS to the console.

        The concordance is between the session's input words from which this suggestion was derived and a vocabulary
        to be chosen by URI. If no vocabulary URI is selected, the most highly suggested vocabulary is used.
        To see the suggested vocabularies and their URIs, use the print method of this class.
        For JSKOS, see https://gbv.github.io/jskos/jskos.html (version 0.4.6).

        :param vocabulary_uri: the URI of the vocabulary, defaults to None
        """

        concordance = self._get_concordance(vocabulary_uri)
        _Utility.print_json(concordance.get_dict())

    def save_concordance(self, folder: str, filename: str = None, vocabulary_uri: str = None) -> None:
        """ Save the concordance as JSKOS in the JSON format.

        :param folder: the path to the save folder
        :param filename: the name of the file, defaults to None
        :param vocabulary_uri: the URI of the vocabulary, defaults to None
        """

        concordance = self._get_concordance(vocabulary_uri)
        _Utility.save_json(dictionary=concordance.get_dict(), filename=filename, folder=folder)

    def save_mappings(self, folder: str, filename: str = None, vocabulary_uri: str = None) -> None:
        """ Save the mappings as JSKOS in the NDJSON format.

        Mappings in this format can be used in the Cocoda Mapping Tool, see https://coli-conc.gbv.de/cocoda/app/
        (version 1.3.6). For NDJSON, see https://github.com/ndjson/ndjson-spec (version 1.0.0).

        :param folder: the path to the save folder
        :param filename: the name of the file, defaults to None
        :param vocabulary_uri: the URI of the vocabulary, defaults to None
        """

        concordance = self._get_concordance(vocabulary_uri)

        if filename is None:
            filename = str(datetime.now()).split(".")[0].replace(":", "-")

        full_filename = folder + f"{filename}.ndjson"
        with open(full_filename, "w") as file:
            for mapping in concordance.mappings:
                print(f"{mapping.get_dict()}".replace("'", '"').replace(" ", ""), file=file)


import cv2
from matplotlib import pyplot as plt
import numpy as np

def editar_tono(img):
    R =  img[:,:,0]
    G =  img[:,:,1]
    R_bright = (R*1.5).astype('uint8')
    G_bright = (G*1.5).astype('uint8')
    R_bright[R_bright<R]=255 # Solucionar overflow uint8
    G_bright[G_bright<G]=255 # Solucionar overflow uint8
    red = np.array(img)
    red[:,:,0]=R_bright
    green = np.array(img)
    green[:,:,1]=G_bright

    plt.subplot(1,3,1), plt.title('Original'), plt.imshow(img), plt.axis(False)
    plt.subplot(1,3,2), plt.title('Enrojecida'), plt.imshow(red), plt.axis(False)
    plt.subplot(1,3,3), plt.title('Verdosa'), plt.imshow(green), plt.axis(False)
    plt.show()

def planos_grises(img):
    grayscale = (.3*img[:,:,2]+.59*img[:,:,1]+.11*img[:,:,0]).astype('uint8')
    inverted = 255-grayscale
    binary = grayscale>127
    bright = grayscale+100
    bright[bright<grayscale]=255 # Solucionar overflow uint8
    dark = grayscale-100
    dark[dark>grayscale]=0 # Solucionar overflow uint8
    colored = np.zeros(shape=(grayscale.shape[0],grayscale.shape[1],3)).astype('uint8')
    colored[:,:,1] = grayscale

    plt.subplot(2,3,1), plt.title('gris'), plt.imshow(grayscale,'gray'), plt.axis(False)
    plt.subplot(2,3,2), plt.title('invertida'), plt.imshow(inverted,'gray'), plt.axis(False)
    plt.subplot(2,3,3), plt.title('binarizada'), plt.imshow(binary,'gray'), plt.axis(False)
    plt.subplot(2,3,4), plt.title('brilllante'), plt.imshow(bright,'gray'), plt.axis(False)
    plt.subplot(2,3,5), plt.title('oscura'), plt.imshow(dark,'gray'), plt.axis(False)
    plt.subplot(2,3,6), plt.title('coloreada'), plt.imshow(colored), plt.axis(False)
    plt.show()

img = cv2.cvtColor(cv2.imread('./images/toysflash.png'), cv2.COLOR_BGR2RGB)

editar_tono(img)
# planos_grises(img)


import numpy as np

FILE = open("input.txt", 'r').read().split(',')
def solution1(days):
    fish = []
    for ch in FILE:
        fish.append(int(ch))

    for i in range(0, days):
        for x in range(0, len(fish)):
            fish[x] -= 1
            if fish[x] < 0:
                fish[x] = 6
                fish.append(8)

    print(len(fish))

def get_fish():
    fish = np.array([int(x) for x in FILE])
    ret_val = np.zeros((9,), dtype=np.longlong)
    for i in range(9):
        ret_val[i] = np.count_nonzero(fish == i)
    return ret_val

def solution2(days):
    fish = get_fish()
    for i in range(days):
        reproducing_fish = fish[0]
        fish[0:8] = fish[1:9]
        fish[6] += reproducing_fish
        fish[8] = reproducing_fish

    print(fish.sum())

if __name__ == "__main__":
    solution1(80)
    solution2(80)
    solution2(256)


from fastapi import APIRouter, Query, Response

from opentrons.system import log_control
from robot_server.service.legacy.models.logs import LogIdentifier, LogFormat

router = APIRouter()

@router.get("/logs/{log_identifier}", description="Get logs from the robot.")
async def get_logs(
    log_identifier: LogIdentifier,
    format: LogFormat = Query(LogFormat.text, title="Log format type"),
    records: int = Query(
        log_control.DEFAULT_RECORDS, title="Number of records to retrieve",
        gt=0, le=log_control.MAX_RECORDS
    ),
) -> Response:
    identifier = 'opentrons-api-serial'
    if log_identifier == LogIdentifier.api:
        identifier = 'opentrons-api'

    modes = {LogFormat.json: ("json", "application/json"),
             LogFormat.text: ("short", "text/plain")}
    format_type, media_type = modes[format]
    output = await log_control.get_records_dumb(
        identifier, records, format_type
    )
    return Response(
        content=output.decode('utf-8'), media_type=media_type)


import os
from tkinter import ttk, DISABLED, NORMAL, END, messagebox
import tkinter as tk

import networkx as nx

from calcoloPercorso import compute, impGraph, tempAddWord
from src.preprocessingDictionary import buildGraph

def onClick(start, end, text, lbl):
    text.config(state=NORMAL)
    text.delete('1.0', END)
    try:
        res = compute(start, end)
    except nx.NetworkXException:
        res = "no path between " + start + " and " + end + "#---"
    text.insert(END, res.split("#")[0])
    lbl.config(text=res.split("#")[1])
    text.config(state=DISABLED)

def changeDictionary(variable, label, label2):
    global dictionary
    if os.path.exists("../Dictionaries/" + variable + "/adj_" + variable):
        dictionary = variable
        label.config(text="Dictionary: " + dictionary)
        label2.config(text="Dictionary: " + dictionary)
        impGraph(dictionary)
        return
    answer = messagebox.askyesno("Question", "The dictionary chose needs to be preprocessed (it could take a lot of "
                                             "time)")
    if answer:
        dictionary = variable
        buildGraph(dictionary)
        label.config(text="Dictionary: " + dictionary)
        label2.config(text="Dictionary: " + dictionary)
        impGraph(dictionary)
        return

def addWordToGraph(text):
    tempAddWord(text.get("1.0", "end-1c"))
    text.delete('1.0', END)

def main(window):
    global dictionary
    window.title("WordToWord")
    window.geometry("800x600")
    tabControl = ttk.Notebook(window)
    tab1 = ttk.Frame(tabControl)
    tab2 = ttk.Frame(tabControl)
    tabControl.add(tab1, text="Paths")
    tabControl.add(tab2, text="Dictionary")
    tabControl.pack(expand=1, fill="both")

    startLabel = tk.Label(tab1, text="Start:", font=("Arial", 15))
    startLabel.place(x=5 + 250, y=10)
    startInput = tk.Text(tab1, width=20, height=1.2, font=("Helvetica", 15))
    startInput.place(x=60 + 250, y=10)

    endLabel = tk.Label(tab1, text="End:", font=("Arial", 15))
    endLabel.place(x=5 + 250, y=50)
    endInput = tk.Text(tab1, width=20, height=1.2, font=("Helvetica", 15))
    endInput.place(x=60 + 250, y=50)

    textArea = tk.Text(tab1, width=86, height=20, font=("Arial", 13), bd=2)
    textArea.place(x=5, y=140)

    lblTime = tk.Label(tab1, text="", font=("Arial", 15))
    lblTime.place(x=5, y=530)

    separator = ttk.Separator(tab1, orient='vertical')
    separator.place(x=400, y=526, height=50)

    lblDictionary = tk.Label(tab1, text="Dictionary: " + dictionary, font=("Arial", 15))
    lblDictionary.place(x=410, y=530)

    lblDictionary2 = tk.Label(tab2, text="Dictionary: " + dictionary, font=("Arial", 15))
    lblDictionary2.place(x=410, y=530)

    button = tk.Button(tab1, text="Find!", font=("Arial", 15),
                       command=lambda: onClick(startInput.get("1.0", "end-1c"), endInput.get("1.0", "end-1c"),
                                               textArea,
                                               lblTime))
    button.place(x=370, y=90)

    options = next(os.walk("../Dictionaries"))[1]
    var = tk.StringVar(root)
    var.set(options[0])  # default value
    w = tk.OptionMenu(tab2, var, *options)
    w.place(x=240, y=50)

    lblTab2 = tk.Label(tab2, text="Choose dictionary:", font=("Arial", 15))
    lblTab2.place(x=50, y=50)
    button2 = tk.Button(tab2, text="Change!", font=("Arial", 15),
                        command=lambda: changeDictionary(var.get(), lblDictionary, lblDictionary2))
    button2.place(x=50, y=90)

    separator2 = ttk.Separator(tab2, orient="horizontal")
    separator2.place(x=0, y=250, width=800)

    wordLabel = tk.Label(tab2, text="Add word: ", font=("Arial", 15))
    wordLabel.place(x=50, y=260)
    wordInput = tk.Text(tab2, width=20, height=1.2, font=("Helvetica", 15))
    wordInput.place(x=200, y=260)
    button3 = tk.Button(tab2, text="Add!", font=("Arial", 15),
                        command=lambda: addWordToGraph(wordInput))
    button3.place(x=50, y=300)

    separator = ttk.Separator(tab2, orient='vertical')
    separator.place(x=400, y=526, height=50)

dictionary = "words_italian"
if __name__ == "__main__":
    root = tk.Tk()
    main(root)
    impGraph(dictionary)
    root.mainloop()


soma = 0
contador = 0
for c in range(1, 501):
    if c % 2 != 0 and c % 3 == 0:
        print(c)
        contador = contador + 1
        soma = soma + c #acomulador

print('A soma de todos os {} valores é {}!'.format(contador, soma))


import multiprocessing as mp
import numpy as np
import pyC

def pyc(a):
    nproc = mp.cpu_count()
    n = len(a)
    m = n*(n+1)/2
    b = np.zeros(m*nproc)

    pool = mp.Pool(nproc)
    for i in range(nproc):
        bi = b[i*m: (i+1)*m]
        pool.apply_async(pyC.tri_copy(a, n, bi))
    return b


import random
import time
import numpy as np
from copy import deepcopy

def Minimax_agent(observation, configuration):
    start_time = time.time()
    # Number of Columns on the Board.
    columns = configuration.columns
    # Number of Rows on the Board.
    rows = configuration.rows
    # Number of Checkers "in a row" needed to win.
    inarow = configuration.inarow
    # The current serialized Board (rows x columns).
    board = observation.board
    # Which player the agent is playing as (1 or 2).
    mark = observation.mark
    boardarray = np.array(board).reshape(rows, columns).tolist()
    inf = np.inf
    nodesExpanded = 0
    depth = 0
    maxDepth = 1
    timeAmount = configuration.timeout - 1

    #a class representing the board and containing helper functions for board tree search
    class Connect(object):
        def __init__(self, board, columns, rows, mark, inarow, depth=0, parent=None, indexNum=None):
            self.board = board #board state
            self.columns = columns #number of columns
            self.rows = rows #number of rows
            self.mark = mark #what the newly placed mark should be
            self.inarow = inarow #how many to match in a row
            self.depth = depth #how far the tree has been expanded so far
            self.parent = parent #the parent that the board came from
            self.indexNum = indexNum #the piece that was just placed
        def getMoves(self):
            #get all possible moves by checking if the top of the board is empty for each column
            moves = []
            if len(moves) == 0:
                for col in range(self.columns):
                    if self.board[0][col] == 0:
                        moves.append(col)
            return moves

        def evaluate(self):

            #return a score evaluating the board, positive for favoring player 1, negative for favoring player 2, and magnitude of infinity for if a certain player has won
            score = 0
            #how much more weight a longer sequence of pieces should have over a shorter one (ex. 3 in a row is [branchConstant] times more important than 2 in a row)
            branchConstant = 6
            #lists marks on board that are beneficial for each respective player (ex. player 1 can have 0 or 1, player 2 can have 0 or 2)
            allowed = [[0, self.mark], [0, 3 - self.mark]]

            #code that counts the marks of each side to determine which player moves next
            playerTurn = 0
            for row in range(self.rows):
                for col in range(self.columns):
                    if self.board[row][col] == 1:
                        playerTurn += 1
                    elif self.board[row][col] == 2:
                        playerTurn -= 1
            playerTurn += 1

            #checks conditions for both players to compare them
            for turn in range(len(allowed)):
                #iterates over rows from bottom to top
                for row in range(self.rows - 1, -1, -1):
                    #iterates over columns
                    for col in range(self.columns):
                        #the following code checks for certain conditions in the patterns:
                        #the four patterns: vertical line, horizontal line, diagonal 1 and diagonal 2
                        #consistency: how much of a line is filled with 0's or the player's mark

                        #vertical lines
                        #don't go so far down the board that the vertical line goes off the board
                        if row < self.rows - (self.inarow - 1):
                            consistency = 0

                            #counts how many places in the vertical line are 0 or the player's mark
                            for inc in range(self.inarow):
                                if self.board[row + inc][col] in allowed[turn]:
                                    consistency += 1
                            #if there are no opponent's marks in that line, then calculate and add score
                            if consistency == self.inarow:
                                consistency = 0

                                #code to check how many marks are in a row
                                for inc2 in range(self.inarow):
                                    consistency += allowed[turn].index(self.board[row + inc2][col])
                                #add score
                                score += branchConstant ** consistency if turn == 0 else -1 * branchConstant ** consistency
                                #if the winning amount is in a row then return winning magnitude score
                                if consistency == self.inarow:
                                    return inf if turn == 0 else -inf
                                #if one more mark in a row to win and its that players turn then return winning magnitude score
                                if consistency == self.inarow - 1:
                                    for inc3 in range(self.inarow):
                                        if self.board[row + inc3][col] == 0:
                                            if playerTurn == allowed[turn][1] and (row + inc3 == self.rows - 1 or self.board[row + inc3 + 1][col] != 0):
                                                return inf if turn == 0 else -inf

                        #horizontal lines
                        #don't go so far left on the board that the horizontal line goes off the board
                        if col < self.columns - (self.inarow - 1):
                            consistency = 0

                            #counts how many places in the vertical line are 0 or the player's mark
                            for inc in range(self.inarow):
                                if self.board[row][col + inc] in allowed[turn]:
                                    consistency += 1
                            #if there are no opponent's marks in that line, then calculate and add score
                            if consistency == self.inarow:
                                consistency = 0

                                #code to check how many marks are in a row
                                for inc2 in range(self.inarow):
                                    consistency += allowed[turn].index(self.board[row][col + inc2])
                                #add score
                                score += branchConstant ** consistency if turn == 0 else -1 * branchConstant ** consistency
                                #if the winning amount is in a row then return winning magnitude score
                                if consistency == self.inarow:
                                    return inf if turn == 0 else -inf
                                #if one more mark in a row to win and its that players turn then return winning magnitude score
                                if consistency == self.inarow - 1:
                                    for inc3 in range(self.inarow):
                                        if self.board[row][col + inc3] == 0:
                                            if playerTurn == allowed[turn][1] and (row == self.rows - 1 or self.board[row + 1][col + inc3] != 0):
                                                return inf if turn == 0 else -inf

                        #diagonal 1
                        #don't go so far to the bottom right of the board that the diagonal line goes off the board
                        if row < self.rows - (self.inarow - 1) and col < self.columns - (self.inarow - 1):
                            consistency = 0

                            #counts how many places in the vertical line are 0 or the player's mark
                            for inc in range(self.inarow):
                                if self.board[row + inc][col + inc] in allowed[turn]:
                                    consistency += 1
                            #if there are no opponent's marks in that line, then calculate and add score
                            if consistency == self.inarow:
                                consistency = 0

                                #code to check how many marks are in a row
                                for inc2 in range(self.inarow):
                                    consistency += allowed[turn].index(self.board[row + inc2][col + inc2])
                                #add score
                                score += branchConstant ** consistency if turn == 0 else -1 * branchConstant ** consistency
                                #if the winning amount is in a row then return winning magnitude score
                                if consistency == self.inarow:
                                    return inf if turn == 0 else -inf
                                #if one more mark in a row to win and its that players turn then return winning magnitude score
                                if consistency == self.inarow - 1:
                                    for inc3 in range(self.inarow):
                                        if self.board[row + inc3][col + inc3] == 0:
                                            if playerTurn == allowed[turn][1] and (row + inc3 == self.rows - 1 or self.board[row + inc3 + 1][col + inc3] != 0):
                                                return inf if turn == 0 else -inf

                        #diagonal 2
                        #don't go so far to the bottom left of the board that the diagonal line goes off the board
                        if row > self.inarow - 2 and col < self.columns - (self.inarow - 1):
                            consistency = 0

                            #counts how many places in the vertical line are 0 or the player's mark
                            for inc in range(self.inarow):
                                if self.board[row - inc][col + inc] in allowed[turn]:
                                    consistency += 1
                            #if there are no opponent's marks in that line, then calculate and add score
                            if consistency == self.inarow:
                                consistency = 0

                                #code to check how many marks are in a row
                                for inc2 in range(self.inarow):
                                    consistency += allowed[turn].index(self.board[row - inc2][col + inc2])
                                #add score
                                score += branchConstant ** consistency if turn == 0 else -1 * branchConstant ** consistency
                                #if the winning amount is in a row then return winning magnitude score
                                if consistency == self.inarow:
                                    return inf if turn == 0 else -inf
                                #if one more mark in a row to win and its that players turn then return winning magnitude score
                                if consistency == self.inarow - 1:
                                    for inc3 in range(self.inarow):
                                        if self.board[row - inc3][col + inc3] == 0:
                                            if playerTurn == allowed[turn][1] and (row - inc3 == self.rows - 1 or self.board[row - inc3 + 1][col + inc3] != 0):
                                                return inf if turn == 0 else -inf

            return score
        def makeMove(self, col, marker):
            #gets the 'child' of the current board created by making move in the [col] column
            board2 = [row[:] for row in self.board]
            for row in range(self.rows - 1,-1,-1):
                if board2[row][col] == 0:
                    board2[row][col] = marker
                    return Connect(board2, self.columns, self.rows, self.mark, self.inarow, self.depth + 1, self, row * self.columns + col)
                    break
        def display(self):
            #displays the connect grid
            boardstring = ""
            for row in range(self.rows):
                for col in range(self.columns):
                    boardstring += str(self.board[row][col])
                boardstring += "\n"
            print(boardstring)
        def terminal_test(self):
            #returns -2 if the maximum depth or search time is exceeded, 0 if the game isn't over, or 1/-1 for which player won
            #its the same code as evaluate but without the score adding

            nonlocal maxDepth, timeAmount
            #no need to check if the game is won if depth is 0 because then it wouldn't be called
            if self.depth == 0:
                return 0
            allowed = [self.mark, 3 - self.mark]
            for turn in allowed:
                for row in range(self.rows - 1, -1, -1):
                    for col in range(self.columns):
                        #vertical
                        if row < self.rows - (self.inarow - 1):
                            consistency = 0
                            for inc in range(self.inarow):
                                if self.board[row + inc][col] == turn:
                                    consistency += 1
                            if consistency == self.inarow:
                                return 1 if turn == self.mark else -1
                        #horizontal
                        if col < self.columns - (self.inarow - 1):
                            consistency = 0
                            for inc in range(self.inarow):
                                if self.board[row][col + inc] == turn:
                                    consistency += 1
                            if consistency == self.inarow:
                                return 1 if turn == self.mark else -1
                        #diagonal 1
                        if row < self.rows - (self.inarow - 1) and col < self.columns - (self.inarow - 1):
                            consistency = 0
                            for inc in range(self.inarow):
                                if self.board[row + inc][col + inc] == turn:
                                    consistency += 1
                            if consistency == self.inarow:
                                return 1 if turn == self.mark else -1
                        #diagonal 2
                        if row > self.inarow - 2 and col < self.columns - (self.inarow - 1):
                            consistency = 0
                            for inc in range(self.inarow):
                                if self.board[row - inc][col + inc] == turn:
                                    consistency += 1
                            if consistency == self.inarow:
                                return 1 if turn == self.mark else -1
            #if depth or time is exceeded, return -2
            if time.time() - start_time > timeAmount or self.depth == maxDepth:
                return -2
            return 0

    def minimize(state, alpha, beta, useAB):
        #minimax with useAB determining whether to use alpha-beta pruning
        nonlocal depth, nodesExpanded
        depth = state.depth if state.depth > depth else depth
        termScore = state.terminal_test()
        if termScore == -1:
            return (None, -inf)
        elif termScore == 1:
            return (None, inf)
        elif termScore == -2:
            return (None, state.evaluate())

        minChildMinUtility = (None, inf)
        possibleMoves = state.getMoves()
        for move in possibleMoves:
            nodesExpanded += 1
            child = state.makeMove(move, 3 - state.mark)
            maxChildMaxUtility = maximize(child, alpha, beta, useAB)
            if maxChildMaxUtility[1] < minChildMinUtility[1]:
                minChildMinUtility = (child, maxChildMaxUtility[1])
            if minChildMinUtility[1] == -inf:
                return minChildMinUtility
            if useAB and minChildMinUtility[1] <= alpha:
                break
            if useAB and minChildMinUtility[1] < beta:
                beta = minChildMinUtility[1]
        return minChildMinUtility

    def maximize(state, alpha, beta, useAB):
        #minimax with useAB determining whether to use alpha-beta pruning
        nonlocal depth, nodesExpanded
        depth = state.depth if state.depth > depth else depth
        termScore = state.terminal_test()
        if termScore == -1:
            return (None, -inf)
        elif termScore == 1:
            return (None, inf)
        elif termScore == -2:
            return (None, state.evaluate())

        maxChildMaxUtility = (None, -inf)
        possibleMoves = state.getMoves()
        for move in possibleMoves:
            nodesExpanded += 1
            child = state.makeMove(move, state.mark)
            minChildMinUtility = minimize(child, alpha, beta, useAB)
            if minChildMinUtility[1] > maxChildMaxUtility[1]:
                maxChildMaxUtility = (child, minChildMinUtility[1])
            if maxChildMaxUtility[1] == inf:
                return maxChildMaxUtility
            if useAB and maxChildMaxUtility[1] >= beta:
                break
            if useAB and maxChildMaxUtility[1] > alpha:
                alpha = maxChildMaxUtility[1]
        return maxChildMaxUtility
    #create board, and check if there is only one move to make, and make that move if there is (no need to search the tree)
    currentBoard = Connect(boardarray, columns, rows, mark, inarow)
    moves = currentBoard.getMoves()
    if len(moves) == 0:
        return None
    if len(moves) == 1:
        return moves[0]

    #iterative deepening with the minimax search
    #starts at depth 1 and continues increasing depth until time limit is reached and makes a conclusion on the best move to make
    childUtility = (None, 0)
    prevChildUtility = (None, 0)
    utilities = []
    #while loop keeps expanding depth until the time limit is exceeded or a guaranteed win is calculated
    while time.time() - start_time < timeAmount and childUtility[1] != inf:
        prevChildUtility = childUtility
        childUtility = maximize(currentBoard, -inf, inf, True)
        utilities.append(childUtility[1])
        maxDepth += 1
    #print(str(utilities) + " " + str(time.time() - start_time)[0:4] + " " + str(nodesExpanded) + " " + str(maxDepth) + " " + str(mark))
    #code to check possible errors before selecting the move
    if time.time() - start_time < timeAmount and childUtility[1] == inf:
        return childUtility[0].indexNum % childUtility[0].columns
    if prevChildUtility[0] == None:
        if childUtility[0] == None:
            #print(str(maxDepth) + "error found")
            return moves[random.randint(0, len(moves) - 1)] if moves else None
        return childUtility[0].indexNum % childUtility[0].columns
    return prevChildUtility[0].indexNum % prevChildUtility[0].columns


from unit_test_common import execute_csv2_request, initialize_csv2_request, ut_id, sanity_requests, parameters_requests
from sys import argv

# lno: CV - error code identifier.

def main(gvar):
    if not gvar:
        gvar = {}
        if len(argv) > 1:
            initialize_csv2_request(gvar, selections=argv[1])
        else:
            initialize_csv2_request(gvar)

    # 01 - 05
    sanity_requests(gvar, '/cloud/update/', ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctu1'), ut_id(gvar, 'ctg2'), ut_id(gvar, 'ctu2'))

    parameters = {
        # 06 Send a GET request.
        # 07 Give an invalid parameter.
        # 08 Omit cloud_name.
        # 09 Give two cloud_names.
        'cloud_name': {'valid': ut_id(gvar, 'ctc3'), 'test_cases': {
            # 10
            '': 'cloud update value specified for "cloud_name" must not be the empty string.',
            # 11
            'Invalid-unit-test': 'cloud update value specified for "cloud_name" must be all lowercase letters, digits, dashes, underscores, periods, and colons, and cannot contain more than one consecutive dash or start or end with a dash.',
            # 12
            'invalid-unit-test-': 'cloud update value specified for "cloud_name" must be all lowercase letters, digits, dashes, underscores, periods, and colons, and cannot contain more than one consecutive dash or start or end with a dash.',
            # 13
            'invalid-unit-test!': 'cloud update value specified for "cloud_name" must be all lowercase letters, digits, dashes, underscores, periods, and colons, and cannot contain more than one consecutive dash or start or end with a dash.',
        }, 'mandatory': True},
        # 14 Give two authurls.
        # 15
        'authurl': {'valid': gvar['cloud_credentials']['authurl'], 'test_cases': {'': 'parameter "authurl" contains an empty string which is specifically disallowed.'}},
        # 16 Give two usernames.
        # 17
        'username': {'valid': gvar['cloud_credentials']['username'], 'test_cases': {'': 'insufficient credentials to establish openstack v3 session, check if missing any user/project info'}},
        # 18 Give two passwords.
        # 19
        'password': {'valid': gvar['cloud_credentials']['password'], 'test_cases': {'': 'insufficient credentials to establish openstack v3 session, check if missing any user/project info'}},
        # 20 Give two projects.
        # 21
        'project': {'valid': gvar['cloud_credentials']['project'], 'test_cases': {'': 'parameter "project" contains an empty string which is specifically disallowed.'}},
        # 22 Give two regions.
        # 23
        'region': {'valid': gvar['cloud_credentials']['region'], 'test_cases': {'': 'parameter "region" contains an empty string which is specifically disallowed.'}},
        # 24 Give two cloud_types.
        # 25
        'cloud_type': {'valid': 'local', 'test_cases': {'invalid-unit-test': 'value specified for "cloud_type" must be one of the following options: [\'amazon\', \'local\', \'openstack\'].'}},
        # 26 Give two enableds.
        # 27
        'enabled': {'valid': 0, 'test_cases': {'invalid-unit-test': 'boolean value specified for "enabled" must be one of the following: true, false, yes, no, 1, or 0.'}},
        # 28 Give two vm_keep_alives.
        # 29
        'vm_keep_alive': {'valid': 0, 'test_cases': {'invalid-unit-test': 'value specified for "vm_keep_alive" must be an integer value.'}},
        # 30 Give two spot_prices.
        # 31
        'spot_price': {'valid': 0.0, 'test_cases': {'invalid-unit-test': 'cloud update value specified for "spot_price" must be a floating point value.'}},
        # 32 Give both metadata_name and metadata_name.1.
        # 33
        'metadata_name': {'valid': ut_id(gvar, 'cty2'), 'test_cases': {'invalid-unit-test': 'cloud update, "{}" failed - specified metadata_name "invalid-unit-test" does not exist.'.format(ut_id(gvar, 'ctc3'))}, 'array_field': True},
        # 34 Give two metdata_options.
        # 35
        'metadata_option': {'valid': 'add', 'test_cases': {'invalid-unit-test': 'value specified for "metadata_option" must be one of the following options: [\'add\', \'delete\'].'}},
        # 36 Give two vm_images.
        # 37
        'vm_image': {'valid': '', 'test_cases': {'invalid-unit-test': 'cloud update, "{0}" failed - specified item does not exist: vm_image=invalid-unit-test, group_name={1}, cloud_name={0}.'.format(ut_id(gvar, 'ctc3'), ut_id(gvar, 'ctg1'))}},
        # 38 Give two vm_flavors.
        # 39
        'vm_flavor': {'valid': '', 'test_cases': {'invalid-unit-test': 'cloud update, "{0}" failed - specified item does not exist: vm_flavor=invalid-unit-test, group_name={1}, cloud_name={0}.'.format(ut_id(gvar, 'ctc3'), ut_id(gvar, 'ctg1'))}},
        # 40 Give two vm_networks.
        # 41
        'vm_network': {'valid': '', 'test_cases': {'invalid-unit-test': 'cloud update, "{0}" failed - specified item does not exist: vm_network=invalid-unit-test, group_name={1}, cloud_name={0}.'.format(ut_id(gvar, 'ctc3'), ut_id(gvar, 'ctg1'))}},
        # 42 Give two vm_keynames.
        # 43
        'vm_keyname': {'valid': '', 'test_cases': {'invalid-unit-test': 'cloud update, "{0}" failed - specified item does not exist: vm_keyname=invalid-unit-test, group_name={1}, cloud_name={0}.'.format(ut_id(gvar, 'ctc3'), ut_id(gvar, 'ctg1'))}},
        # 44 give two vm_boot_volume_types
        # 45
        'vm_boot_volume_type': {'valid': 'None', 'test_cases': {'invalid-unit-test': 'At least one of base size or size per core must be specified'}},
    }

    parameters_requests(gvar, '/cloud/update/', ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctu1'), parameters)

    # 46
    execute_csv2_request(
        gvar, 1, None, 'specified item does not exist: vm_boot_volume_type=invalid-unit-test',
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'csc3'), 'vm_boot_volume_type': 'invalid-unit-test', 'vm_boot_volume_size': 20},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 47
    execute_csv2_request(
        gvar, 1, None, 'specified item does not exist: vm_boot_volume_type=invalid-unit-test',
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'csc3'), 'vm_boot_volume_type': 'invalid-unit-test', 'vm_boot_volume_per_core': 20},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 48 Ensure that metadata_option by itself does not qualify as a field to update.
    execute_csv2_request(
        gvar, 1, 'CV', 'cloud update must specify at least one field to update',
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'ctc3'), 'metadata_option': 'add'},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 49 Attempt to implicitly add metadata that does not exist.
    execute_csv2_request(
        gvar, 1, 'CV', 'cloud update, "{}" failed - specified metadata_name "invalid-unit-test" does not exist.'.format(ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'ctc3'), 'metadata_name': 'invalid-unit-test'},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 50 Attempt to delete non-existent metadata.
    execute_csv2_request(
        gvar, 1, 'CV', 'cloud update, "{}" failed - specified metadata_name "invalid-unit-test" does not exist.'.format(ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'ctc3'), 'metadata_name': 'invalid-unit-test', 'metadata_option': 'delete'},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 51 Ensures that values are as expected before executing requests that are expected to succeed. Known to fail if run twice without setup / cleanup in between.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'group_name': ut_id(gvar, 'ctg1'), 'cloud_name': ut_id(gvar, 'ctc3')},
        values={
            'authurl': gvar['cloud_credentials']['authurl'],
            'cacertificate': None,
            'cascading_vm_flavor': None,
            'cascading_vm_image': None,
            'cascading_vm_keep_alive': 300,
            'cascading_vm_keyname': None,
            'cascading_vm_network': None,
            'cascading_vm_security_groups': None,
            'cloud_priority': 0,
            'cloud_type': 'openstack',
            'cores_ctl': -1,
            'cores_foreign': '0',
            'cores_native': '0',
            'cores_softmax': -1,
            'enabled': 1,
            'flavor_exclusions': None,
            'group_exclusions': None,
            # We would check metadata_names here, but their order is unpredictable as far as I know.
            'project': gvar['cloud_credentials']['project'],
            'project_domain_id': '',
            'project_domain_name': 'Default',
            'ram_ctl': -1,
            'ram_foreign': '0',
            'ram_native': '0',
            'region': gvar['cloud_credentials']['region'],
            'spot_price': -1.0,
            'user_domain_id': '',
            'user_domain_name': 'Default',
            'username': gvar['cloud_credentials']['username'],
            'vm_flavor': '',
            'vm_image': '',
            'vm_keep_alive': -1,
            'vm_keyname': None,
            'vm_network': '',
            'vm_security_groups': ''
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 52 Update several values and explicitly add one metadata.
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'ram_ctl': 5,
            'cores_ctl': 5,
            'vm_flavor': '',
            'vm_image': '',
            'vm_keep_alive': 10,
            'vm_keyname': '',
            'vm_network': '',
            'spot_price': 1,
            'metadata_name': ut_id(gvar, 'cty1'),
            'metadata_option': 'add'
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 53 Ensure that 48 updated correctly. Known to fail if one's cloud_credentials (in ~/cloudscheduler/unit_tests/credentials.yaml) are invalid.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'group_name': ut_id(gvar, 'ctg1'), 'cloud_name': ut_id(gvar, 'ctc3')},
        values={
            'ram_ctl': 5,
            'cores_ctl': 5,
            'vm_keep_alive': 10,
            'vm_flavor': '',
            'vm_image': '',
            'vm_keyname': None,
            'vm_network': '',
            'spot_price': 1,
            'group_exclusions': ut_id(gvar, 'cty1')
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 54 Implicitly add one metadata.
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'metadata_name': ut_id(gvar, 'cty2')
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 55 Ensure that 50 added metadata.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'group_name': ut_id(gvar, 'ctg1'), 'cloud_name': ut_id(gvar, 'ctc3')},
        values={'group_exclusions': ut_id(gvar, 'cty1,cty2')},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 56 Delete one metadata.
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'metadata_name': ut_id(gvar, 'cty2'),
            'metadata_option': 'delete'
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 57 Ensure that 52 deleted metadata.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'group_name': ut_id(gvar, 'ctg1'), 'cloud_name': ut_id(gvar, 'ctc3')},
        values={'group_exclusions': ut_id(gvar, 'cty1')},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 58 Explicitly add a metadata.
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'metadata_name': ut_id(gvar, 'cty1'),
            'metadata_option': 'add'
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 59 Ensure that 54 added metadata.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'cloud_name': ut_id(gvar, 'ctc3')},
        values={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'group_name': ut_id(gvar, 'ctg1'),
            'group_exclusions': ut_id(gvar, 'cty1')
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 60 Implicitly add metadata.
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={
            'cloud_name': ut_id(gvar, 'ctc3'),
            'metadata_name': ut_id(gvar, 'cty2'),
            },
        server_user=ut_id(gvar, 'ctu1')
    )

    # 61 Ensure that 58 added metadata.
    execute_csv2_request(
        gvar, 0, None, None,
        '/cloud/list/', group=ut_id(gvar, 'ctg1'), expected_list='cloud_list', list_filter={'group_name': ut_id(gvar, 'ctg1'), 'cloud_name': ut_id(gvar, 'ctc3')},
        values={'group_exclusions': ut_id(gvar, 'cty1,cty2')},
        server_user=ut_id(gvar, 'ctu1')
    )

    # 62
    execute_csv2_request(
        gvar, 0, None, 'cloud "{}::{}" successfully updated.'.format(ut_id(gvar, 'ctg1'), ut_id(gvar, 'ctc3')),
        '/cloud/update/', group=ut_id(gvar, 'ctg1'), form_data={'cloud_name': ut_id(gvar, 'ctc3'), 'vm_boot_volume_type': 'None'},
        server_user=ut_id(gvar, 'ctu1')
    )

if __name__ == "__main__":
    main(None)


class Grid:
    def __init__(self, size):
        self.size = size
        self.grid = self._build_empty_grid()

    def _build_empty_grid(self):
        grid = [["."] * self.size for _ in range(self.size)]
        return grid

    def insert_row_to_grid(self, row, row_num):
        col_num = 0
        for value in row:
            if value == "X":
                self.insert_value_to_grid(value, row_num, col_num)
            col_num += 1

    def insert_column_to_grid(self, column, column_num):
        row_num = 0
        for value in column:
            if value == "X":
                self.insert_value_to_grid(value, row_num, column_num)
            row_num += 1

    def insert_value_to_grid(self, value, row, column):
        self.grid[row][column] = value

    def get_row_as_string(self, row_num):
        row = self.grid[row_num]
        return ''.join(str(x) for x in row)

    def get_column_as_string(self, column_num):
        column = []
        for row in self.grid:
            column.append(row[column_num])
        return ''.join(str(x) for x in column)

    def calculate_line_numbers(self, row=True):
        all_line_nums = []
        for line_num in range(self.size):
            if row:
                line_string = self.get_row_as_string(line_num)
            else:
                line_string = self.get_column_as_string(line_num)
            line_string = line_string.split("_")
            row_nums = [x for x in line_string if x]
            all_line_nums.append(row_nums)
        return all_line_nums

    def __str__(self):
        printed_grid = ""
        for i in range(self.size):
            printed_grid = printed_grid + self.get_row_as_string(i) + "\n"
        return printed_grid


class Solution:
	def maxProfit(self, prices: List[int]) -> int:
		# If can't buy and sell, return 0
		if len(prices) < 2:
			return 0
		# Initialize variables
		buy, sell, prev_buy, prev_sell = float('-inf'), 0, 0, 0

		# For all the items
		for i in range(0, len(prices)):
			# Store previous buy (buy[i-1])
			prev_buy = buy
			# New buy = maximum of [prev_buy (no buy), prev_sell-prices[i] (buy)]
			buy = max(prev_buy, prev_sell - prices[i])
			# Store previous sell (sell[i-1])
			prev_sell = sell
			# New sell = maximum of [prev_sell (no sell), prices[i] + prev_buy (buy[i-2])]
			# This is where cooldown is incorporated
			sell = max(prev_sell, prices[i] + prev_buy)
		return sell


# main file
import telebot
from config.config import BOT_API_TOKEN

bot = telebot.TeleBot(BOT_API_TOKEN)

@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, 'Start command')

@bot.message_handler(commands=['help'])
def start(message):
    bot.send_message(message.chat.id, 'Help command')

## should be at the bottom, after all other function
@bot.message_handler(func=lambda messages: True)
def any_message(message):
    msg = "Cannot understand you. Please, enter '/help' or '/start' "
    bot.reply_to(message, msg)

## load next step handlers if needed here
if __name__ == "__main__":
    bot.infinity_polling()


import cv2
import smtplib,ssl
import os
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
cap = cv2.VideoCapture(0)
model = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
def SendMail(ImgFileName):
    with open(ImgFileName, 'rb') as f:
        img_data = f.read()
    msg = MIMEMultipart()
    msg['Subject'] = 'Cropped Image'
    msg['From'] = 'Tinkal Shakya'
    msg['To'] = 'recevier'
    text = MIMEText("I have cropped the face from the live video")
    msg.attach(text)
    image = MIMEImage(img_data, name=os.path.basename(ImgFileName))
    msg.attach(image)
    context=ssl.create_default_context()
    s =  smtplib.SMTP_SSL("smtp.gmail.com",465,context=context)
    s.login("sender_mail","password")
    s.sendmail('sender_mail','recevier_mail', msg.as_string())
    s.quit()
    print("Mail Sended")

cap = cv2.VideoCapture(0)
i = 0
while True:
    i = i + 1
    success, img = cap.read()
    face  = model.detectMultiScale(img)
    if len(face) == 0:
        pass
    else:
        x1 = face[0][0]
        y1 = face[0][1]
        x2 = face[0][2] + x1
        y2 = face[0][3] + y1
        crop_img = img[y1:y2 , x1:x2]
        cv2.imshow('Crop Image', crop_img)
        if cv2.waitKey(100) == 13:
            break
        cv2.imwrite('images/ayaz/'+str(i)+".png",crop_img)

cv2.destroyAllWindows()


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import cv2

from implicit_seg.functional import Seg3dLossless
from implicit_seg.functional import plot_mask3D

resolutions = [
    (8+1, 20+1, 8+1),
    (16+1, 40+1, 16+1),
    (32+1, 80+1, 32+1),
    (64+1, 160+1, 64+1),
    (128+1, 320+1, 128+1),
]
align_corners = False

def query_func(tensor, points):
    """
    [Essential!] here align_corners should be same
    with how you process gt through interpolation.
    tensor: (bz, 1, H, W, D)
    points: [bz,] list of (N, 3)
    """
    bz = len(points)
    occupancys = [
        F.grid_sample(
            tensor[i].unsqueeze(0),
            points[i].view(1, 1, 1, -1, 3),
            mode="bilinear",
            align_corners=align_corners,
            padding_mode="border", # to align with F.interpolate
        )[0, 0, 0, 0].unsqueeze(0) for i in range(bz)
    ]
    return occupancys
if __name__ == "__main__":
    import tqdm
    import os

    lr = 1e-1
    niter = 100000
    MSE = nn.MSELoss()

    # gt
    query_sdfs = torch.load(
        "./data/sdf.pth").to("cuda:0").float() # [1, 1, H, W, D]
    print ("data:", query_sdfs.shape)

    if type(resolutions[-1]) is int:
        final_W, final_H, final_D = resolutions[-1], resolutions[-1], resolutions[-1]
    else:
        final_W, final_H, final_D = resolutions[-1]
    gt = F.interpolate(
        query_sdfs, (final_D, final_H, final_W), mode="trilinear", align_corners=align_corners)
    # gt = (gt > 0.0).float()
    print ("gt:", gt.shape)

    # input
    input = torch.rand_like(gt)
    input.requires_grad = True
    print("input:", input.shape)

    # infer
    engine = Seg3dLossless(
        query_func = query_func,
        b_min = [[-1.0, -1.0, -1.0]],
        b_max = [[1.0, 1.0, 1.0]],
        resolutions = resolutions,
        align_corners = align_corners,
        balance_value = 0.,
        device="cuda:0",
        visualize=False
    )

    # training
    solver = torch.optim.Adam([input], lr = lr)
    pbar = tqdm.tqdm(range(niter))

    for i in pbar:
        occupancys = engine(tensor=input)

        solver.zero_grad()
        loss = MSE(occupancys, gt)
        loss.backward()
        solver.step()

        if input.grad is not None:
            input.grad.data.zero_()

        state_msg = (f'loss: {loss.item(): .6f}')
        pbar.set_description(state_msg)

        if i> 0 and i % 5 == 0:
            plot_mask3D(occupancys.detach()[0, 0].to("cpu"), interactive=False)


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

class Solution:
    def numberOfArithmeticSlices(self, A):
        result = 0
        if len(A) < 3:
            return result

        first, step = 0, A[1] - A[0]
        for i in range(2, len(A)):
            if A[i] - A[i - 1] == step:
                result += i - first - 1
            else:
                first, step = i - 1, A[i] - A[i - 1]

        return result

if __name__ == "__main__":
    solution = Solution()

    assert 3 == solution.numberOfArithmeticSlices([1, 2, 3, 4])
    assert 2 == solution.numberOfArithmeticSlices([1, 2, 3, 5, 8, 9, 10])


import unittest
import cairis.core.BorgFactory
import os
from subprocess import call
from cairis.core.Borg import Borg

__author__ = 'Shamal Faily'

class BorgFactoryTest(unittest.TestCase):

  def setUp(self):
    call([os.environ['CAIRIS_CFG_DIR'] + "/initdb.sh"])
    cairis.core.BorgFactory.initialise()

  def testProjectSettings(self):
    b = Borg()
    self.assertEqual(b.fontName,'Times New Roman')
    self.assertEqual(b.fontSize,'7.5')
    self.assertEqual(b.apFontSize,'13')

  def tearDown(self):
    b = Borg()
    b.dbProxy.close()
    call([os.environ['CAIRIS_CFG_DIR'] + "/dropdb.sh"])

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