

"""simple docstring"""






from __future__ import annotations

import random

# Maximum size of the population.  Bigger could be faster but is more memory expensive.
_lowerCAmelCase						=		2_0_0
# Number of elements selected in every generation of evolution. The selection takes
# place from best to worst of that generation and must be smaller than N_POPULATION.
_lowerCAmelCase						=		5_0
# Probability that an element of a generation can mutate, changing one of its genes.
# This will guarantee that all genes will be used during evolution.
_lowerCAmelCase						=		0.4
# Just a seed to improve randomness required by the algorithm.
random.seed(random.randint(0, 1_0_0_0))

def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Optional[Any]  =    len([g for position, g in enumerate(_lowerCamelCase   ) if g == main_target[position]]   )
    return (item, float(_lowerCamelCase   ))

def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Tuple  =    random.randint(0 ,   len(_lowerCamelCase   ) - 1   )
    _lowerCAmelCase       :   List[str]  =    parent_a[:random_slice] + parent_a[random_slice:]
    _lowerCAmelCase       :   Optional[Any]  =    parent_a[:random_slice] + parent_a[random_slice:]
    return (child_a, child_a)

def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Union[str, Any]  =    list(_lowerCamelCase   )
    if random.uniform(0 ,   1   ) < MUTATION_PROBABILITY:
        _lowerCAmelCase       :   List[Any]  =    random.choice(_lowerCamelCase   )
    return "".join(_lowerCamelCase   )

def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase ,   _lowerCamelCase ,   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Optional[Any]  =    []
    # Generate more children proportionally to the fitness score.
    _lowerCAmelCase       :   List[str]  =    int(parent_a[1] * 100   ) + 1
    _lowerCAmelCase       :   List[Any]  =    10 if child_n >= 10 else child_n
    for _ in range(_lowerCamelCase   ):
        _lowerCAmelCase       :   Union[str, Any]  =    population_score[random.randint(0 ,   _lowerCamelCase   )][0]

        _lowerCAmelCase,					_lowerCAmelCase       :   int  =    crossover(parent_a[0] ,   _lowerCamelCase   )
        # Append new string to the population list.
        pop.append(mutate(_lowerCamelCase ,   _lowerCamelCase   )   )
        pop.append(mutate(_lowerCamelCase ,   _lowerCamelCase   )   )
    return pop

def 		lowerCamelCase__		(					_lowerCamelCase ,   _lowerCamelCase ,   _lowerCamelCase = True   ):

    '''simple docstring'''



    if N_POPULATION < N_SELECTED:
        _lowerCAmelCase       :   Tuple  =    f"""{N_POPULATION} must be bigger than {N_SELECTED}"""
        raise ValueError(_lowerCamelCase   )
    # Verify that the target contains no genes besides the ones inside genes variable.
    _lowerCAmelCase       :   Optional[int]  =    sorted({c for c in target if c not in genes}   )
    if not_in_genes_list:
        _lowerCAmelCase       :   Any  =    f"""{not_in_genes_list} is not in genes list, evolution cannot converge"""
        raise ValueError(_lowerCamelCase   )

    # Generate random starting population.
    _lowerCAmelCase       :   List[Any]  =    []
    for _ in range(_lowerCamelCase   ):
        population.append(''.join([random.choice(_lowerCamelCase   ) for i in range(len(_lowerCamelCase   )   )]   )   )

    # Just some logs to know what the algorithms is doing.
    _lowerCAmelCase,					_lowerCAmelCase       :   List[str]  =    0, 0

    # This loop will end when we find a perfect match for our target.
    while True:
        generation += 1
        total_population += len(_lowerCamelCase   )

        # Random population created. Now it's time to evaluate.

        # Adding a bit of concurrency can make everything faster,
        #
        # import concurrent.futures
        # population_score: list[tuple[str, float]] = []
        # with concurrent.futures.ThreadPoolExecutor(
        #                                   max_workers=NUM_WORKERS) as executor:
        #     futures = {executor.submit(evaluate, item) for item in population}
        #     concurrent.futures.wait(futures)
        #     population_score = [item.result() for item in futures]
        #
        # but with a simple algorithm like this, it will probably be slower.
        # We just need to call evaluate for every item inside the population.
        _lowerCAmelCase       :   Any  =    [evaluate(_lowerCamelCase ,   _lowerCamelCase   ) for item in population]

        # Check if there is a matching evolution.
        _lowerCAmelCase       :   Tuple  =    sorted(_lowerCamelCase ,   key=lambda _lowerCamelCase   : x[1] ,   reverse=_lowerCamelCase   )
        if population_score[0][0] == target:
            return (generation, total_population, population_score[0][0])

        # Print the best result every 10 generation.
        # Just to know that the algorithm is working.
        if debug and generation % 10 == 0:
            print(
                f"""\nGeneration: {generation}"""
                f"""\nTotal Population:{total_population}"""
                f"""\nBest score: {population_score[0][1]}"""
                f"""\nBest string: {population_score[0][0]}"""   )

        # Flush the old population, keeping some of the best evolutions.
        # Keeping this avoid regression of evolution.
        _lowerCAmelCase       :   Tuple  =    population[: int(N_POPULATION / 3   )]
        population.clear()
        population.extend(_lowerCamelCase   )
        # Normalize population score to be between 0 and 1.
        _lowerCAmelCase       :   int  =    [
            (item, score / len(_lowerCamelCase   )) for item, score in population_score
        ]

        # This is selection
        for i in range(_lowerCamelCase   ):
            population.extend(select(population_score[int(_lowerCamelCase   )] ,   _lowerCamelCase ,   _lowerCamelCase   )   )
            # Check if the population has already reached the maximum value and if so,
            # break the cycle.  If this check is disabled, the algorithm will take
            # forever to compute large strings, but will also calculate small strings in
            # a far fewer generations.
            if len(_lowerCamelCase   ) > N_POPULATION:
                break


if __name__ == "__main__":
 _lowerCAmelCase						=		(
     """This is a genetic algorithm to evaluate, combine, evolve, and mutate a string!"""
 )
 _lowerCAmelCase						=		list(
     """ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"""
     """nopqrstuvwxyz.,;!?+-*#@^'èéòà€ù=)(&%$£/\\"""
 )
 _lowerCAmelCase	,   _lowerCAmelCase	,   _lowerCAmelCase						=		basic(target_str, genes_list)
 print(
     F'''\nGeneration: {generation}\nTotal Population: {population}\nTarget: {target}'''
 )








"""simple docstring"""






from __future__ import annotations

import json

import requests
from bsa import BeautifulSoup
from fake_useragent import UserAgent

_lowerCAmelCase						=		{"""UserAgent""": UserAgent().random}

def 		lowerCamelCase__		(					_lowerCamelCase   ):

    '''simple docstring'''



    _lowerCAmelCase       :   Any  =    script.contents[0]
    _lowerCAmelCase       :   Union[str, Any]  =    json.loads(data[data.find('{"config"'   ) : -1]   )
    return info["entry_data"]["ProfilePage"][0]["graphql"]["user"]







class 	__UpperCamelCase    :

  def __init__(		self    ,_A      ):
      '''simple docstring'''

      _lowerCAmelCase       :   Optional[Any]  =    F"""https://www.instagram.com/{username}/"""
      _lowerCAmelCase       :   str  =    self.get_json()

  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      _lowerCAmelCase       :   str  =    requests.get(self.url    ,headers=_A      ).text
      _lowerCAmelCase       :   Optional[Any]  =    BeautifulSoup(_A    ,'html.parser'      ).find_all('script'      )
      try:
          return extract_user_profile(scripts[4]      )
      except (json.decoder.JSONDecodeError, KeyError):
          return extract_user_profile(scripts[3]      )

  def __repr__(		self      ):
      '''simple docstring'''

      return F"""{self.__class__.__name__}('{self.username}')"""

  def __str__(		self      ):
      '''simple docstring'''

      return F"""{self.fullname} ({self.username}) is {self.biography}"""

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["username"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["full_name"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["biography"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["business_email"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["external_url"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["edge_followed_by"]["count"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["edge_follow"]["count"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["edge_owner_to_timeline_media"]["count"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["profile_pic_url_hd"]

  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["is_verified"]







  @property
  def __lowerCamelCase		(		self      ):
      '''simple docstring'''

      return self.user_data["is_private"]





def 		lowerCamelCase__		(					_lowerCamelCase = "github"   ):

    '''simple docstring'''



    import os

    if os.environ.get('CI'   ):
        return  # test failing on GitHub Actions
    _lowerCAmelCase       :   Tuple  =    InstagramUser(_lowerCamelCase   )
    assert instagram_user.user_data
    assert isinstance(instagram_user.user_data ,   _lowerCamelCase   )
    assert instagram_user.username == username
    if username != "github":
        return
    assert instagram_user.fullname == "GitHub"
    assert instagram_user.biography == "Built for developers."
    assert instagram_user.number_of_posts > 150
    assert instagram_user.number_of_followers > 120000
    assert instagram_user.number_of_followings > 15
    assert instagram_user.email == "support@github.com"
    assert instagram_user.website == "https://github.com/readme"
    assert instagram_user.profile_picture_url.startswith('https://instagram.'   )
    assert instagram_user.is_verified is True
    assert instagram_user.is_private is False


if __name__ == "__main__":
 import doctest

 doctest.testmod()
 _lowerCAmelCase						=		InstagramUser("""github""")
 print(instagram_user)
 print(F'''{instagram_user.number_of_posts = }''')
 print(F'''{instagram_user.number_of_followers = }''')
 print(F'''{instagram_user.number_of_followings = }''')
 print(F'''{instagram_user.email = }''')
 print(F'''{instagram_user.website = }''')
 print(F'''{instagram_user.profile_picture_url = }''')
 print(F'''{instagram_user.is_verified = }''')
 print(F'''{instagram_user.is_private = }''')





