from sklearn.cluster import KMeans
import cv2
import numpy as np
import utils
import matplotlib.pyplot as plt

def skin(color):
	temp = np.uint8([[color]])
	color = cv2.cvtColor(temp,cv2.COLOR_RGB2HSV)
	color=color[0][0]
	e8 = (color[0]<=25) and (color[0]>=0)
	e9 = (color[1]<174) and (color[1]>58)
	e10 = (color[2]<=255) and (color[2]>=50)
	return (e8 and e9 and e10)

# This function is meant to give the skin color of the person by detecting face and then
# applying k-Means Clustering.
def get_skin_color(img):

	# Load the face detector.
	face_cascade =cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

	# Convert to grayscale image.
	gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

	# Detect face in the image.
	faces = face_cascade.detectMultiScale(gray, 1.3, 5)

	# If a face is detected.
	if(len(faces)>0):
		for (x,y,w,h) in faces:

			# Take out the face from the image.
			image=img[y:y+h,x:x+h]

			# Apply k-Means Clustering to the face to obtain most dominant color.
			image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
			image = image.reshape((image.shape[0] * image.shape[1], 3))
			clt = KMeans(n_clusters = 4)
			clt.fit(image)

			def centroid_histogram(clt):
				# Grab the number of different clusters and create a histogram
				# based on the number of pixels assigned to each cluster.
				numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
				(hist, _) = np.histogram(clt.labels_, bins = numLabels)

				# Normalize the histogram, such that it sums to one.
				hist = hist.astype("float")
				hist /= hist.sum()

				# Return the histogram.
				return hist

			def get_color(hist, centroids):

				# Obtain the color with maximum percentage of area covered.
				maxi=0
				COLOR=[0,0,0]

				# Loop over the percentage of each cluster and the color of
				# each cluster.
				for (percent, color) in zip(hist, centroids):
					if(percent>maxi):
						COLOR=color
						maxi=percent

				# Return the most dominant color.
				return COLOR

			# Obtain the color and convert it to HSV type
			hist = centroid_histogram(clt)
			skin_temp1 = get_color(hist, clt.cluster_centers_)
			# print(skin_temp1)
			skin_temp2 = np.uint8([[skin_temp1]])
			skin_color = cv2.cvtColor(skin_temp2,cv2.COLOR_RGB2HSV)
			skin_color=skin_color[0][0]
			# print(skin_color)

			# Return the color.
			return (True,skin_color)
	else:
		image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
		image = image.reshape((image.shape[0] * image.shape[1], 3))
		clt = KMeans(n_clusters = 3)
		clt.fit(image)

		def centroid_histogram(clt):
			# Grab the number of different clusters and create a histogram
			# based on the number of pixels assigned to each cluster.
			numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
			(hist, _) = np.histogram(clt.labels_, bins = numLabels)

			# Normalize the histogram, such that it sums to one.
			hist = hist.astype("float")
			hist /= hist.sum()

			# Return the histogram.
			return hist

		def get_color(hist, centroids):

			# Obtain a color which satisfies skin condition.
			cnt=0
			list=[]

			# Loop over the percentage of each cluster and the color of
			# each cluster to see if there is such a color.
			for (percent, color) in zip(hist, centroids):
				if(skin(color)):
					cnt=cnt+1
					list.append([color,percent])
			if(cnt==1):
				return list[0][0]
			else:
				return [0,0,0]

		# Obtain the color and convert it to HSV type
		hist = centroid_histogram(clt)
		skin_color = get_color(hist, clt.cluster_centers_)

		if(skin_color[0]==0 and skin_color[0]==0 and skin_color[0]==0):
			return (False,skin_color)
		else:
			skin_temp2 = np.uint8([[skin_color]])
			skin_color = cv2.cvtColor(skin_temp2,cv2.COLOR_RGB2HSV)
			skin_color=skin_color[0][0]
			return skin_color

# get_skin_color('1.jpg')


#Project Euler 31 https://projecteuler.net/problem=31

coins = [1, 2, 5, 10, 20, 50, 100, 200]

def coin_sums(listt, limit):
    ans = []

    def combinations(cume, i, sum):
        if sum == limit:
            ans.append(cume.copy())
            return
        elif i >= len(coins) or sum > limit:
            return

        cume.append(listt[i])
        combinations(cume, i, sum + listt[i])
        cume.pop(0)
        combinations(cume, i+1, sum)

    combinations([], 0, 0)
    return len(ans)

#print(coin_sums(coins, 200))

#dynamic programming solution

def coin_sums_dp(listt, limit):
    dp = [[0]*(limit+1) for i in range(len(listt)+1)]
    for row in range(1, len(dp)):
        for col in range(len(dp[0])):
            if row == 1 or col == 1:
                dp[row][col] = 1
            elif col < listt[row-1]:
                dp[row][col] = dp[row-1][col]
            else:
                dp[row][col] = dp[row-1][col] + dp[row][col-(listt[row-1])]
    return dp[-1][-1]

print(coin_sums_dp(coins, 200))


from flask import Flask, request, jsonify
from predictPipeline import pipePredict

# create flask app
app = Flask(__name__)

@app.post('/analyze')
def analyze():
    """Analyze the data specified through json request

    Returns:
        Response: Result of the analysis/prediction
    """
    data = request.json
    try:
        sample = data['text']
    except KeyError:
        return jsonify({'error1': 'Key Error'})

    y = pipePredict(sample)
    try:
        result = jsonify(y[0])
    except TypeError as e:
        result = jsonify({'error2': str(e)})
    return result

# run flask app
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)


import os
import shutil
import uuid
from pprint import pprint

from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.files import File
from django.core.files.base import ContentFile
from django.db import utils
from rest_framework import status
from rest_framework.exceptions import ValidationError

import settings
from accounts.models import User
from common.models import UserCell
from document.models import Document
from projects import models
from projects.models import Project
from rest_framework.response import Response
from storyboards.models import Frame
from storyboards.serializers import ChronoframeSerializer
from table.models import DefaultTableModel
from timing.models import TimingGroup, Timing
from folders.models import Folder

def get_model(model_name):
    model_app_name = ContentType.objects.get(model=model_name).app_label
    return apps.get_model(model_app_name, model_name.capitalize())

def unpack_nested_kwargs(kwargs, self_base):
    print('vvvvvvvvvvvvvvvvv')
    print(23, 'unpack_nested_kwargs')
    print(kwargs)

    _, root_name, super_name, parent_name, host_name = [None] * 5
    _pk, root_pk, super_pk, parent_pk, host_pk, base_pk = [None] * 6

    is_pk = None
    if 'pk' in kwargs:
        print(31)
        is_pk = True
        base_pk = kwargs.pop('pk')

    kw_len = len(kwargs)
    kw_keys = [None] * (5 - kw_len) + list(kwargs.keys())
    kw_vals = [None] * (5 - kw_len) + list(kwargs.values())
    _, root_name, super_name, parent_name, host_name = kw_keys
    _pk, root_pk, super_pk, parent_pk, host_pk = kw_vals

    if is_pk:
        print(42)
        kwargs['pk'] = base_pk
    ret = {
        'su': _[:-3] if _ else None,
        'su_pk': _pk,
        'root': root_name[:-3] if root_name else None,
        'root_pk': root_pk,
        'super': super_name[:-3] if super_name else None,
        'super_pk': super_pk,
        'parent': parent_name[:-3] if parent_name else None,
        'parent_pk': parent_pk,
        'host': host_name[:-3] if host_name else None,
        'host_pk': host_pk,
        'base': self_base,
        'base_pk': base_pk
    }
    pprint(ret)
    print('^^^^^^^^^^^^^^^^^^^^')
    return ret

def get_object_or_404(model, pk):
    try:
        return get_model(model).objects.get(pk=pk)
    except (ObjectDoesNotExist, utils.IntegrityError):
        raise ValidationError(
            {"error": {"msg": f"{model.capitalize()}[{pk}] not found"}})

def organize_data_row_sort_arrays(instance):
    instance_has_userfields = False
    instance_data_row_attribute = None
    for attr in dir(instance):
        if attr.endswith('frames') or attr == 'locations':
            instance_data_row_attribute = getattr(instance, attr)
        if attr == 'userfields':
            instance_has_userfields = True
    instance_data_row = list(instance_data_row_attribute.values('id'))
    instance_data_row_ids = [data_row['id'] for data_row in instance_data_row]
    if set(instance_data_row_ids) != set(instance.data_row_order):
        diff = list(set(instance_data_row_ids)
                    .difference(set(instance.data_row_order)))
        instance.data_row_order += diff

    if instance.data_row_order:
        for idx in reversed(instance.data_row_order):
            if idx not in instance_data_row_ids:
                instance.data_row_order.remove(idx)
    else:
        for ident in instance_data_row_ids:
            instance.data_row_order.append(ident)

    if instance_has_userfields:
        if Frame.objects.first():
            frame = instance_data_row_attribute.first()
            column_ids = list(frame.userfields.values('field_id'))
            for idx in reversed(instance.col_order):
                if {'field_id': idx} not in column_ids:
                    instance.col_order.remove(idx)
        else:
            instance.col_order = []

    # отключаем изменение last_modified_date
    for field in instance._meta.local_fields:
        if field.name == "last_modified_date":
            field.auto_now = False

    instance.save()

    # включаем изменение last_modified_date
    for field in instance._meta.local_fields:
        if field.name == "last_modified_date":
            field.auto_now = True

def add_userfields(user, host_obj, new_obj):
    """
    Получение существующих юзер.колонок для модели и их добавление
    ко всем участникам или добавление к строкам этого-же документа
    """
    print(139, 'common.add_userfields')
    new_obj_name = new_obj.__class__.__name__
    columns = []
    if new_obj_name in ['Frame']:
        columns = host_obj.frame_columns.all()
    for usercolumn in columns:
        usercell = UserCell.objects.create(
            host_usercolumn=usercolumn, owner=user)
        if new_obj_name == 'Frame':
            new_obj.userfields.add(usercell)

def insert_frames(user, base, instance, frames_ids: list):
    print(165, 'utils insert_frames')
    for frame_id in frames_ids:
        frame = get_object_or_404('frame', frame_id)
        frame_data = {f'host_{base}': instance.id,
                      'sbdframe_id': frame.id}
        serializer = None
        if base == 'chrono':
            serializer = ChronoframeSerializer
        print(150, 'pass context')
        serializer = serializer(data=frame_data, context={'user': user})
        print(152, serializer.__class__.__name__)
        serializer.is_valid(raise_exception=True)
        new_frame = serializer.create(serializer.validated_data)
        instance.data_row_order.append(new_frame.id)
        instance.save()
        add_userfields(user, instance, new_frame)

def check_file_size(request, user):
    """
    Проверяет превышает ли размер загружаемого файла в совокупности с
    размером уже загруженных пользователем файлов установленный лимит.
    Если лимит не превышен, считает общий размер файлов на диске.
    """
    user = User.objects.filter(pkid=user.pkid).first()
    disk_space = user.disk_space if user.disk_space else 0
    for filename, file in request.FILES.items():
        file_size = file.size
        if file_size + disk_space < settings.DISK_SIZE:
            disk_space += file_size
        else:
            return False
    return disk_space

def change_disk_space(user, disk_space):
    """
    При загрузке файла обновляет занятое место на диске у пользователя.
    """
    user = User.objects.filter(pkid=user.pkid).first()
    user.disk_space = disk_space
    user.save()

def recount_disk_space(user):
    """
    Пересчитывает при обновлении файла общий вес файлов на диске
    у пользователя.
    """
    folder = os.path.join(os.getcwd(), settings.MEDIA_ROOT, str(user.pkid))
    size = 0
    for path, dirs, files in os.walk(folder):
        for f in files:
            fp = os.path.join(path, f)
            size += os.path.getsize(fp)
    user = User.objects.filter(pkid=user.pkid).first()
    user.disk_space = size
    user.save()
    return size

def find_host_project(kw):
    """
    Ищет PKID проекта по id документа.
    """
    for key, value in kw.items():
        if value == 'project':
            pk = int(kw.get(f'{key}_pk'))
            return Project.objects.filter(pk=pk).first()

def update_host_modified_date(kw, user_email):
    """
    Обновляет время и юзера последнего изменения сториборда
    """
    for key, value in kw.items():
        if value in ["storyboard"]:
            pk = int(kw.get(f'{key}_pk'))
            instance = get_model(value).objects.filter(
                id=pk).first()
            instance.last_modified_user = user_email
            instance.save()

def count_space_per_object(user, obj, doc_type):
    """
    Получает папку, в которой лежат файлы конкретного документа и
    считает вес каждого файла.
    """
    if isinstance(obj, File):
        folder = os.path.join(os.getcwd(),
                              settings.MEDIA_ROOT,
                              str(user.pkid),
                              doc_type)
    else:
        folder = os.path.join(os.getcwd(),
                              settings.MEDIA_ROOT,
                              str(user.pkid),
                              doc_type,
                              str(obj.id))
    exist_folder = os.path.exists(folder)
    size = 0
    if not exist_folder:
        return size
    for path, dirs, files in os.walk(folder):
        for f in files:
            fp = os.path.join(path, f)
            size += os.path.getsize(fp)
    return size

def like_or_dislike_object(user, object_type):
    """
    Ставит или убирает лайк. Затем сохраняет информацию
    о наличии или отсутствии лайка в БД.
    """
    user = get_model('user').objects.filter(pk=user.pk).first()
    if object_type == 'bordomatic':
        user.like = False if user.like else True
        user.save()
        return user.like
    elif object_type == 'document':
        user.document_like = False if user.document_like else True
        user.save()
        return user.document_like

def copy_file(parent_object, related_object=None):
    """
    Функция, отвечающая за копирование объекта с файлом.
    """
    if related_object:
        file_field_instance = getattr(related_object, 'file')
        owner_pk = str(related_object.owner.pk)
    else:
        file_field_instance = getattr(parent_object, 'file')
        owner_pk = str(parent_object.owner.pk)
    if file_field_instance:
        file_path = os.path.join(os.getcwd(),
                                 settings.MEDIA_ROOT,
                                 file_field_instance.name)
        if isinstance(parent_object, models.File):
            pk = str(parent_object.pk)
            model = 'file'
        new_path = os.path.join(os.getcwd(),
                                settings.MEDIA_ROOT,
                                owner_pk,
                                model,
                                pk)
        if not os.path.isdir(new_path):
            os.mkdir(new_path)
        new_path = shutil.copy(file_path, new_path)
        return new_path

def construct_new_instance_with_file(object, new_path, project_id=None):
    """
    Создает объект класса с файлом.
    """
    instance = get_model(str(object.__class__.__name__).lower())(
            name=object.name,
            owner=object.owner,
            col_order=object.col_order,
            created_at=object.created_at,
            data_row_order=object.data_row_order,
            description=object.description,
            last_modified_date=object.last_modified_date,
            last_modified_user=object.last_modified_user,
            tag_color=object.tag_color,
            file=File(open(new_path, 'rb'), name=os.path.split(object.file.name)[-1])
        )
    if isinstance(object, models.File):
        instance.host_project = models.Project.objects.filter(pk=project_id).first()
        instance.document_logo = None
    return instance

def duplicate_object(parent_object, project_id, host=None):
    """
    Копирует инстанс класса со всеми child объектами, в том числе, связанными
    foreign keys:
        1.  Собирает объекты, связанные с родительским объектов с помощью foreign keys и m2m relations.
        2.  Копирует родительский объект
        3a. Копирует child объекты вместе с их child объектами.
        3b. Создает новые m2m relations.
    """
    related_objects_to_copy = []
    relations_to_set = {}
    # Iterate through all the fields in the parent object looking for related fields
    for field in parent_object._meta.get_fields():
        if field.one_to_many:
            # One to many fields are backward relationships where many child
            # objects are related to the parent. Enumerate them and save a list
            # so we can copy them after duplicating our parent object.
            print(f'Found a one-to-many field: {field.name}')

            # 'field' is a ManyToOneRel which is not iterable, we need to get
            # the object attribute itself.
            related_object_manager = getattr(parent_object, field.name)
            related_objects = list(related_object_manager.all())
            if related_objects:
                print(f' - {len(related_objects)} related objects to copy')
                related_objects_to_copy += related_objects

        elif field.many_to_one:
            # In testing, these relationships are preserved when the parent
            # object is copied, so they don't need to be copied separately.
            print(f'Found a many-to-one field: {field.name}')

        elif field.many_to_many:
            # Many to many fields are relationships where many parent objects
            # can be related to many child objects. Because of this the child
            # objects don't need to be copied when we copy the parent, we just
            # need to re-create the relationship to them on the copied parent.
            print(f'Found a many-to-many field: {field.name}')
            related_object_manager = getattr(parent_object, field.name)
            relations = list(related_object_manager.all())
            if relations:
                print(f' - {len(relations)} relations to set')
                relations_to_set[field.name] = relations
    # Duplicate the parent object
    if isinstance(parent_object, Timing):

        # Keep the original pk of the copied object
        old_parent_obj_pk = parent_object.pk

        parent_object.pk = None
        parent_object.name += " копия"
        parent_object.host_project = models.Project.objects.filter(pk=project_id).first()
        parent_object.order_id = uuid.uuid4()
        parent_object.doc_uuid = None

        # Copying the document logo
        copy_document_logo(parent_object, old_parent_obj_pk)

        parent_object.save()

    elif isinstance(parent_object, DefaultTableModel):
        # Keep the original pk of the copied object
        old_parent_obj_pk = parent_object.pk

        parent_object.pk = None
        parent_object.name += " копия"
        if parent_object.host_folder:
            parent_object.host_folder = Folder.objects.filter(pk=project_id).first()
        else:
            parent_object.host_document = Document.objects.filter(pk=project_id).first()
        parent_object.order_id = uuid.uuid4()
        parent_object.doc_uuid = None

        # Copying the document logo
        copy_document_logo(parent_object, old_parent_obj_pk)

        parent_object.save()

    elif isinstance(parent_object, TimingGroup):
        parent_object.pk = None
        parent_object.host_timing = host
        parent_object.save()
    elif isinstance(parent_object, models.File):
        new_path = copy_file(parent_object)
        instance = construct_new_instance_with_file(parent_object, new_path, project_id)
        instance.name += " копия"
        instance.save()
    else:
        parent_object.pk = None
        parent_object.name += " копия"
        parent_object.order_id = uuid.uuid4()
        parent_object.document_logo = None
        parent_object.save()
    print(f'Copied parent object ({str(parent_object)})')
    # Copy the one-to-many child objects and relate them to the copied parent
    for related_object in related_objects_to_copy:
        # Iterate through the fields in the related object to find the one that
        # relates to the parent model.
        for related_object_field in related_object._meta.fields:
            if related_object_field.related_model == parent_object.__class__:
                # If the related_model on this field matches the parent
                # object's class, perform the copy of the child object and set
                # this field to the parent object, creating the new
                # child -> parent relationship. if object is Location or Callsheetmember
                # duplicates it as parent obj.
                if isinstance(related_object, TimingGroup):
                    duplicate_object(related_object, project_id, host=parent_object)
                else:
                    related_object.pk = None
                    setattr(related_object, related_object_field.name, parent_object)
                    related_object.save()

                    text = str(related_object)
                    text = (text[:40] + '..') if len(text) > 40 else text
                    print(f'|- Copied child object ({text})')

    # Set the many-to-many relations on the copied parent
    for field_name, relations in relations_to_set.items():
        # Get the field by name and set the relations, creating the new
        # relationships.
        field = getattr(parent_object, field_name)
        field.set(relations)
        text_relations = []
        for relation in relations:
            text_relations.append(str(relation))
        print(f'|- Set {len(relations)} many-to-many relations on {field_name} {text_relations}')

    if isinstance(parent_object, models.File):
        return instance
    else:
        return parent_object

def copy_document_logo(copied_instance, original_instance_pk):
    """
    The function is necessary to copy the document_logo file for a new instance
    (without deleting this file from the original instance).

    Retrieves the document_logo file and its original name.
    Adds a 'copy_' to the name. The new instance will have this file with a new name, for example:
    'orig.png' -> 'copy_orig.png'

    Gets the type (model) of the original object and the original object itself.
    Saves the document_logo file to the copied instance and to the original one.
    Without such saving, the post_save signal on the ShootingPlan model
    will transfer the image from the original instance to the copied one.

    This system is implemented because when creating a new object,
    its document_logo must have a path like:
        '{owner_id}/{model}/{model instance.id}/{filename}'
    The new instance does not have an id yet and therefore all images are placed in the None folder.
        '{owner_id}/{model}/None/{filename}'
    Then the signal transfers them from there to the appropriate folder:
        '10/shootingplan/None/orig.png' -> '10/shootingplan/1/orig.png'

    Thus, if you do not save the document_logo for both copies, the original and the copied one,
    that document_logo will simply be transferred from the original instance to the copied one.
    """
    if copied_instance.document_logo:
        picture_copy = ContentFile(copied_instance.document_logo.read())
        old_picture_name = copied_instance.document_logo.name.split("/")[-1]
        new_picture_name = 'copy_' + old_picture_name

        model = type(copied_instance)
        old_parent_obj = model.objects.get(pk=original_instance_pk)
        copied_instance.document_logo.save(new_picture_name, picture_copy)
        old_parent_obj.document_logo.save(old_picture_name, picture_copy)

def check_folder_exist(request):
    for folder in ['folder', 'parent_polder']:
        if folder in request.data:
            folder = Folder.objects.filter(
                id=request.data[folder],
                deleted_id__isnull=True
            )
            if not folder:
                raise ValidationError({'folder': 'does not exist'})


import russian_wiki_module
import csv
from googletrans import Translator
import pandas as pd

# parse the dump
russian_wiki_module.parse_dump(
    'ruwiki-20201020-stub-meta-history.xml/ruwiki-20201020-stub-meta-history.xml')

# get number of revisions for an article
print(russian_wiki_module.get_number_of_revisions('Министерство внутренних дел Российской Федерации',
                                                  'ruwiki-20201020-stub-meta-history.xml/ruwiki-20201020-stub-meta-history.csv'))

# get number of unique editors for an article
print(russian_wiki_module.get_number_of_unique_editors('Министерство внутренних дел Российской Федерации',
                                                       'ruwiki-20201020-stub-meta-history.xml/ruwiki-20201020-stub-meta-history.csv'))

# get total number of bytes edited for every revision of an article
print(russian_wiki_module.get_number_of_bytes_edited('Министерство внутренних дел Российской Федерации',
                                                     'ruwiki-20201020-stub-meta-history.xml/ruwiki-20201020-stub-meta-history.csv'))

# get list of all the articles present in a category
print(russian_wiki_module.get_all_articles_in_a_category(
    'Министерство внутренних дел Российской Федерации'))

# get readability score of an article
print(russian_wiki_module.get_readability_score(
    'Министерство внутренних дел Российской Федерации'))

# get number of pageviews of an article
print(russian_wiki_module.get_number_of_pageviews(
    'Министерство внутренних дел Российской Федерации'))

# get list of  the all articles present in a category
category_list = ['Распространение COVID-19 в России', 'Хронология распространения COVID-19 в России',
                 'Гам-КОВИД-Вак', 'Распространение COVID-19 в Крыму']
# print(category_list)

# save results to csv file
parameters = ['article', 'readability']
filename = "ru_data.csv"
with open(filename, "w+", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(parameters)
    for x in category_list:
        article = x
        readability = russian_wiki_module.get_readability_score(x)
        data = [article, readability]
        writer.writerow(data)

article_list = ['Распространение COVID-19 в России',
                'Хронология распространения COVID-19 в России',
                'Гам-КОВИД-Вак',
                'Распространение COVID-19 в Крыму',
                'Единый день голосования 13 сентября 2020 года',
                'Единый день голосования 19 сентября 2021 года',
                'Президентские выборы в России (2024)'
                ]

gini_dict = russian_wiki_module.gini_coefficient_of_article_list(article_list,
                                                                 'ruwiki-20201020-stub-meta-history.xml/ruwiki-20201020-stub-meta-history.csv')

filename = "ru_ginni.csv"
with open(filename, "w+", encoding="utf-8") as f:
    writer = csv.writer(f)
    for k, v in gini_dict.items():
        writer.writerow([k, v])


import urllib

__author__ = 'Vardhman'

from urllib.parse import urlsplit,urlparse,urlunparse,quote,unquote
import hashlib
import re

# "(:)[\d]+"
REGEX_NETLOC_HTTP  = "(:80)"
REGEX_NETLOC_HTTPS = "(:443)"
REGEX_PATH = "((^[/](index|default|home)$)|(^[/](index|default|home)[\.]{1}[a-z]+)$)"

# unquote is used to convert all the octets to the correct characters
url = "http://www.google.com/new/mypage.html?a=c#mdl"
      #"%7Eabout/?page_id=758"
#--url_unq  = unquote(url)
# gets the domain name of the url
#--base_url = "{0.scheme}://{0.netloc}/".format(urlsplit(url_unq))

# the hashing done below should be used in order to store ids in the elastic search
# or for any other purpose of url matching so that it is consistent and no
# string matching anomalies are generated

# does sha224 encoding- has a larger size
#--print(hashlib.sha224(base_url.encode('utf-8')).hexdigest())#digest_size)

# does md5 encoding- has a smaller size
#--m = hashlib.md5()
#--m.update(base_url.encode('utf-8'))
#--print(m.digest())#digest_size)

# canonicalization - has to be done before hashing, not needed in case of extracting domain name
# only needed when we actually store in frontier and visit these links
# uses the url parse library, which splits the url into various sections
# these sections can now be individually treated for canonicalization and the
# url should be reformed

#--parseResult = urlparse(url_unq)
#parseResult.netloc = re.sub("(:)[\d]+","",parseResult.netloc)
#--print(base_url)
#--print(parseResult)
#--print(type(parseResult))

def getCanonicalizedUrl(parseResult,currentdomain):
    currentdomainParseResult = urlparse(currentdomain)
    scheme = str.lower(coalesc(parseResult.scheme,currentdomainParseResult.scheme))
    if scheme == "https":
        netloc = str.lower(re.sub(REGEX_NETLOC_HTTPS,"",coalesc(parseResult.netloc,currentdomainParseResult.netloc)))
    else:
        netloc = str.lower(re.sub(REGEX_NETLOC_HTTP,"",coalesc(parseResult.netloc,currentdomainParseResult.netloc)))
    path = canonicalizePath(parseResult,currentdomainParseResult)# re.sub(REGEX_PATH,"",coalesc(unquote(parseResult.path),currentdomainParseResult.path)).lstrip(".").replace("//","/")
    params= ""
    query= ""
    fragment = ""
    return (urlunparse(urllib.parse.ParseResult(scheme,netloc,path,params,query,fragment)))

def canonicalizePath(parseResult,currentdomainParseResult):
    path = re.sub(REGEX_PATH,"",coalesc(unquote(parseResult.path),currentdomainParseResult.path)).lstrip(".").replace("//","/")
    path = re.sub("([\.]+)(\/)","",path)
    return path

def coalesc(first,second):
    if first == "":
        return second
    else:
        return first

def decode_octets(stri):
    unq_url = unquote(stri)
    return  unq_url

def canonicalizeMain(url,currentUrl,encodingType):
    urlun = url #decode_octets(url)
    return getCanonicalizedUrl(urlparse(urlun),currentUrl)


from django.template import loader
import pdfkit
import os
from xhtml2pdf import pisa
from django.template.loader import get_template
from io import BytesIO
from urllib import request, response
from django.shortcuts import redirect, render
from .models import *
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_exempt
from django.contrib.admin.views.decorators import staff_member_required

from django.contrib.auth import logout
from django.contrib import messages
from django.conf import settings
from django.contrib.sites.models import Site
from django.http import HttpResponse
from django.http import HttpResponseBadRequest
from django.views.decorators.cache import cache_control
from django.conf import settings
from django.core.mail import send_mail
from django.core import mail
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from datetime import datetime

from paytm import Checksum

MERCHANT_KEY = 'f63ilt9f9!374rCZ'

# Create your views here.

def index(requests):

    return render(requests, 'landing/index.html')

def about(requests):

    return render(requests, 'about/about.html')

def contact(requests):

    return render(requests, 'contact/contact.html')

def faq(requests):

    return render(requests, 'faq/faq.html')

def terms(requests):

    return render(requests, 'terms/terms.html')

def policy(requests):

    return render(requests, 'terms/terms.html')

def blogs(requests):

    blogs = blog.objects.all()

    return render(requests, 'blog/blog.html',{'blogs':blogs})

@staff_member_required(login_url='/')
def delete_blogs(requests,id):

    blog.objects.all().filter(id=id).delete()

    return redirect("/create_blogs")

@staff_member_required(login_url='/')
def create_blogs(request):

    blogs = blog.objects.all()

    if request.method == "POST":

        heading1 = request.POST.get('heading1', None)
        description = request.POST.get('description', None)
        image = request.FILES.get('image', None)

        blog.objects.create(heading1=heading1,description=description,image=image)

        return redirect("/create_blogs")

    return render(request, 'blog/create_blogs.html',{'blogs':blogs})

@cache_control(no_cache=True, must_revalidate=True)
@login_required(login_url='/')  # redirect when user is not logged in
def form_view(request):

    username = request.user.username

    user_id = request.user.id

    num = phone_numbers.objects.filter(user_name=username)

    all_states=states.objects.all()

    pri=price.objects.all()

    if request.method == "POST":

        full_name = request.POST.get('full_name', None)
        company_name = request.POST.get('company_name', None)
        company_type = request.POST.get('company_type', None)
        company_address = request.POST.get('company_address', None)
        gst_number = request.POST.get('gst_number', None)
        p_number = request.POST.get('p_number', None)
        email = request.POST.get('email', None)
        amount_input = request.POST.get('amount', None)
        total_states = request.POST.get('total_states', None)
        state = request.POST.get('state', None)
        # aadhar_card = request.FILES.get('aadhar_card')
        # photograph = request.FILES.get('photograph', None)
        # proof_of_address = request.FILES.get('proof_of_address', None)
        # pan_card = request.FILES.get('pan_card', None)
        # aadhar_card = request.FILES.get('aadhar_card',None)
        # photograph = request.FILES.get('photograph', None)
        # proof_of_address = request.FILES.get('proof_of_address', None)
        # pan_card = request.FILES.get('pan_card', None)

        # print(state)

        # state_list = []

        # Maharashtra = request.POST.get('Maharashtra', None)
        # if Maharashtra == "Maharashtra":
        #     state_list.append('Maharashtra')

        # Gujrat = request.POST.get('Gujrat', None)
        # if Gujrat == "Gujrat":
        #     state_list.append('Gujrat')

        # Karnataka = request.POST.get('Karnataka', None)
        # if Karnataka == "Karnataka":
        #     state_list.append('Karnataka')

        # West_Bengal = request.POST.get('West_Bengal', None)
        # if West_Bengal == "West_Bengal":
        #     state_list.append('West Bengal')

        # Telangana = request.POST.get('Telangana', None)
        # if Telangana == "Telangana":
        #     state_list.append('Telangana')

        # Delhi = request.POST.get('Delhi', None)
        # if Delhi == "Delhi":
        #     state_list.append('Delhi')

        # Rajasthan = request.POST.get('Rajasthan', None)
        # if Rajasthan == "Rajasthan":
        #     state_list.append('Rajasthan')

        # Bihar = request.POST.get('Bihar', None)
        # if Bihar == "Bihar":
        #     state_list.append('Bihar')

        # AndhraPradesh = request.POST.get('AndhraPradesh', None)
        # if AndhraPradesh == "AndhraPradesh":
        #     state_list.append('Andhra Pradesh')

        # listToStr = ' '.join(map(str, state_list))

        # docs = documents.objects.create(aadhar_card=aadhar_card, photograph=photograph, proof_of_address=proof_of_address, pan_card=pan_card)

        username = request.user.username

        obj, created = phone_numbers.objects.get_or_create(user_name=username)
        obj.phone_number = request.POST.get('p_number', None)
        obj.user_name = username
        obj.save()

        # aadhar_card=aadhar_card, photograph=photograph, proof_of_address=proof_of_address, pan_card=pan_card,

        done = orders.objects.create(gst_number=gst_number,company_addess=company_address,user_id=user_id, user_name=username, full_name=full_name, company_name=company_name, company_type=company_type, p_number=p_number, email=email, total_amount=amount_input, total_states=total_states, state=state)

        return redirect("/order_page/"+str(done.id))

    else:
        return render(request, 'form/form.html', {'numbers': num,'all_states':all_states,'pri':pri})

@csrf_exempt
@login_required(login_url='/')
def order_page(request, id):

    username = request.user.username

        # orders_placed1 = orders.objects.all().filter(user_name=username, id=(list_1[i]))

    orders_placed = orders.objects.get(id=id)

    pri = price.objects.all()

    param_dict = {

        'MID': 'XJailZ92874680327655',
        'ORDER_ID': str(id),
        'TXN_AMOUNT': str(orders_placed.total_amount),
        'CUST_ID': str(request.user.id),
        'INDUSTRY_TYPE_ID': 'Retail',
        'WEBSITE': 'DEFAULT',
        'CHANNEL_ID': 'WEB',
        'CALLBACK_URL': 'https://www.thegstco.com/handlerequest/' + str(orders_placed.id) + str("/") + str(request.user.id)+str("/"),
        # 'CALLBACK_URL': 'http://127.0.0.1:8000/handlerequest/' + str(orders_placed.id) + str("/") + str(request.user.id)+str("/"),

    }

    param_dict['CHECKSUMHASH'] = Checksum.generate_checksum(param_dict, MERCHANT_KEY)

    total_amount = str(orders_placed.total_amount),

    return render(request, 'order_page/order_page.html', {'param_dict': param_dict,'pri':pri,'state_str':orders_placed.state,'total_amount':orders_placed.total_amount,'total_states':orders_placed.total_states})

    # ===========================================================================================================================================================

@csrf_exempt
def handlerequest(request, id, user_id):

    user = User.objects.get(id=user_id)

    orders_placed = orders.objects.get(id=id)

    form = request.POST
    response_dict = {}
    for i in form.keys():
        response_dict[i] = form[i]
        if i == 'CHECKSUMHASH':
            checksum = form[i]

    verify = Checksum.verify_checksum(response_dict, MERCHANT_KEY, checksum)

    if verify:
        if response_dict['RESPCODE'] == '01':

            orders.objects.filter(id=id).update(payment="paid")

            return render(request, 'order/order_successful.html', {'id': id})
        else:
            return render(request, 'order/order_successful.html', {'id': id})
    return render(request, 'order/order_unsuccessful.html', {'response': response_dict})

# for generating pdf invoice
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
import os

def fetch_resources(uri, rel):
    path = os.path.join(uri.replace(settings.STATIC_URL, ""))
    return path

def render_to_pdf(template_src, context_dict={}):
    template = get_template(template_src)
    html  = template.render(context_dict)
    result = BytesIO()
    pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)#, link_callback=fetch_resources)
    if not pdf.err:
        return HttpResponse(result.getvalue(), content_type='application/pdf')
    return None

from django.views.generic import  View

class GenerateInvoice(View):

    def get(self, request, pk, *args, **kwargs):
        try:
            order_db = orders.objects.get(id = pk, user_name = request.user.username)
            pri=price.objects.all()  #you can filter using order_id as well
        except:
            return HttpResponse("505 Not Found")
        data = {
            'order_id': order_db.id,
            'user_email': order_db.email,
            'date': str(order_db.date),
            'name': order_db.full_name,
            'order': order_db,
            'amount': order_db.total_amount,
            'state':order_db.state,
            'total_states': order_db.total_states,
            'pri':pri
        }
        pdf = render_to_pdf('invoice/invoice.html',data )
        # return HttpResponse(pdf, content_type='application/pdf')

        # force download
        if pdf:
            response = HttpResponse(pdf, content_type='application/pdf')
            filename = "Invoice_%s.pdf" %(['order_id'])
            content = "inline; filename='%s'" %(filename)
            #download = request.GET.get("download")
            #if download:
            content = "attachment; filename=%s" %(filename)
            response['Content-Disposition'] = content
            return response
        return HttpResponse("Not found")

def invoice (request,id):
        try:
            order_db = orders.objects.get(id = id, user_name = request.user.username)     #you can filter using order_id as well
        except:
            return HttpResponse("505 Not Found")
        data = {
            'order_id': order_db.id,
            'user_email': order_db.email,
            'date': str(order_db.date),
            'name': order_db.full_name,
            'order': order_db,
            'amount': order_db.total_amount,
            'state':order_db.state,
            'total_states': order_db.total_states
        }
        # pdf = render_to_pdf('invoice/invoice.html',data )
        # # return HttpResponse(pdf, content_type='application/pdf')

        # # force download
        # if pdf:
        #     response = HttpResponse(pdf, content_type='application/pdf')
        #     filename = "Invoice_%s.pdf" %(['order_id'])
        #     content = "inline; filename='%s'" %(filename)
        #     #download = request.GET.get("download")
        #     #if download:
        #     content = "attachment; filename=%s" %(filename)
        #     response['Content-Disposition'] = content
        #     return response
        # return HttpResponse("Not found")

        return render(request, 'invoice/invoice.html',data)

@login_required(login_url='/')
def upload_docments(request, id):

    username = request.user.username

    orders_placed1 = orders.objects.get(id=id, user_name=username)

    if orders_placed1.proof_of_address and orders_placed1.aadhar_card and orders_placed1.photograph and orders_placed1.pan_card :

        return redirect("/")

    if orders_placed1.proof_of_address:
        proof_of_address1=True
    else:
        proof_of_address1=False

    if orders_placed1.aadhar_card:
        aadhar_card1=True
    else:
        aadhar_card1=False

    if orders_placed1.photograph:
        photograph1=True
    else:
        photograph1=False

    if orders_placed1.pan_card:
        pan_card1=True
    else:
        pan_card1=False

    if request.method == "POST":

        orders_done = orders.objects.get(id=id, user_name=username)

        aadhar_card = request.FILES.get('aadhar_card',None)
        if aadhar_card != None:
            orders_done.aadhar_card = aadhar_card

        photograph = request.FILES.get('photograph', None)
        if photograph != None:
            orders_done.photograph = photograph

        proof_of_address = request.FILES.get('proof_of_address', None)
        if proof_of_address != None:
          orders_done.proof_of_address = proof_of_address

        pan_card = request.FILES.get('pan_card', None)
        if pan_card != None:
            orders_done.pan_card = pan_card

        orders_done.save()

        return redirect('/order')

        # orders.objects.create(aadhar_card=aadhar_card,photograph=photograph,proof_of_address=proof_of_address,pan_card=pan_card)

    return render(request, 'form/upload_docments.html',{'proof_of_address':proof_of_address1,'aadhar_card':aadhar_card1,'photograph':photograph1,'pan_card':pan_card1})

@login_required(login_url='/')  # redirect when user is not logged in
def order(requests):

    pri = price.objects.all()

    orders_placed = orders.objects.all().filter(user_name=requests.user.username, user_id=requests.user.id,payment="paid").order_by("-id")

    return render(requests, 'order/order_details.html', {'orders_placed': orders_placed,'pri':pri})

@login_required(login_url='/')  # redirect when user is not logged in
def profile(request):

    # user_id = request.user.user_id

    username = request.user.username

    numbers = phone_numbers.objects.filter(user_name=username)

    if request.method == "POST":

        phone_number = request.POST.get('phone_number', None)
        user_name = request.POST.get('user_name', None)

        obj, created = phone_numbers.objects.get_or_create(user_name=user_name)
        obj.phone_number = request.POST.get('phone_number', None)
        obj.user_name = request.POST.get('user_name', None)
        obj.save()

        # obj1,created=orders.objects.get_or_create(user_name=user_name)
        # obj1.p_number=request.POST.get('phone_number', None)
        # obj1.save()

        messages.info(request, 'Phone Number Saved successfully!')
        return render(request, 'profile/profile.html', {"numbers": numbers})

    return render(request, 'profile/profile.html', {"numbers": numbers})

@login_required(login_url='/')  # redirect when user is not logged in
@staff_member_required(login_url='/')
def admin_panel(requests):

    orders_list = orders.objects.all().filter(payment="paid").order_by("-id")

    Recieved=orders.objects.filter(payment="paid",order_status="Order Recieved").count()
    Processing=orders.objects.filter(payment="paid",order_status="Processing").count()
    Submitted=orders.objects.filter(payment="paid",order_status="Submitted For Approval").count()
    Completed=orders.objects.filter(order_status="Order Completed").count()
    total=orders.objects.filter(payment="paid").count()

    pri = price.objects.all()

    if requests.method == "POST":
        state_price = requests.POST.get('price', None)

        percentage_price = requests.POST.get('percentage_price', None)

        percentage = requests.POST.get('percentage', None)

        price.objects.all().delete()

        price.objects.create(state_price=state_price,percentage_price=percentage_price,percentage=percentage)

        return(redirect("/admin_panel"))

    return render(requests, 'admin_panel/index.html', {"orders": orders_list,'pri':pri,'Recieved':Recieved,'Processing':Processing,'Submitted':Submitted,'Completed':Completed,'total':total})

@login_required(login_url='/')  # redirect when user is not logged in
@staff_member_required(login_url='/')
def admin_panel_upaid(requests):

         orders_list = orders.objects.all().filter(payment="Unpaid").order_by("-id")

         Recieved=orders.objects.filter(payment="paid",order_status="Order Recieved").count()
         Processing=orders.objects.filter(payment="paid",order_status="Processing").count()
         Submitted=orders.objects.filter(payment="paid",order_status="Submitted For Approval").count()
         Completed=orders.objects.filter(order_status="Order Completed").count()
         total=orders.objects.filter(payment="paid").count()

         pri = price.objects.all()

         return render(requests, 'admin_panel/index_copy.html', {"orders": orders_list,'pri':pri,'Recieved':Recieved,'Processing':Processing,'Submitted':Submitted,'Completed':Completed,'total':total})

@login_required(login_url='/')
@staff_member_required(login_url='/')
def order_information(requests,id):

    order_db1 = orders.objects.get(id=id)

    order_db = orders.objects.all().filter(id=id)

    return render(requests, 'order_information/order_information.html',{'order_db':order_db})

@login_required(login_url='/')  # redirect when user is not logged in
@staff_member_required(login_url='/')
def users_database(requests):

    numbers = phone_numbers.objects.all()
    users = User.objects.all()

    return render(requests, 'admin_panel/users_database.html', {"numbers": numbers, "users": users})

@login_required(login_url='/')  # redirect when user is not logged in
@staff_member_required(login_url='/')
def change_order_status(self, pk,status):

    try:
        status = status.replace("-"," ")
    except:
        pass

    if  orders.objects.all().filter(id=pk).exists():
        orders.objects.all().filter(id=pk).update(order_status=status)
        orders_placed=orders.objects.get(id=pk)

        return redirect('/order_information/'+str(pk))

    else:
        return HttpResponseBadRequest

@login_required(login_url='/')  # redirect when user is not logged in
def logout_view(request):

    logout(request)
    return redirect('/')

@staff_member_required(login_url='/')
def all_states(request):

    states_db=states.objects.all()

    if "State_name_form" in request.POST:

        state_name = request.POST.get('state_name', None)
        state_id = request.POST.get('state_id', None)

        states.objects.create(state_name=state_name,state_id=state_id)

        return redirect('/all_states')

    if "State_price_form" in request.POST:

        state_price = request.POST.get('state_price', None)
        percentage = request.POST.get('percentage', None)

        price.objects.all().delete()

        price.objects.create(state_price=state_price,price_with_percentage=percentage)

        return redirect('/all_states')

    return render (request, 'admin_panel/state.html',{'states_db':states_db})

@staff_member_required(login_url='/')
def delete_states(request,id):

    states.objects.filter(id=id).delete()
    return redirect('/all_states')

import csv
@login_required(login_url='/')
@staff_member_required(login_url='/')
def getfile(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="Ketan More.csv"'
    orders_db = orders.objects.all()
    writer = csv.writer(response)
    for order in orders_db:
        writer.writerow([order.user_name,order.user_id,order.full_name,order.email,order.company_name,order.company_type,order.p_number,order.created_date,order.state,order.total_states,order.total_amount,order.payment])
    return response

def Maharashtra(requests):

    return render(requests, 'states/Maharashtra.html')

def Delhi(requests):

    return render(requests, 'states/Delhi.html')

def Karnataka(requests):

    return render(requests, 'states/Karnataka.html')

def Telangana(requests):

    return render(requests, 'states/Telangana.html')

def Gujarat(requests):

    return render(requests, 'states/Gujarat.html')

def Punjab(requests):

    return render(requests, 'states/Punjab.html')


# -*- coding: utf-8 -*-
###############################################################################
#    License, author and contributors information in:                         #
#    __manifest__.py file at the root folder of this module.                  #
###############################################################################

from odoo import http
from odoo.http import request
from odoo.addons.payment.controllers.portal import PaymentProcessing

import logging

_logger = logging.getLogger(__name__)

class WebsiteSale(http.Controller):

    @http.route('/shop/payment/validate', type='http', auth="public", website=True, sitemap=False)
    def payment_validate(self, transaction_id=None, sale_order_id=None, **post):
        """ Method that should be called by the server when receiving an update
        for a transaction. State at this point :

         - UDPATE ME
        """
        # Customs Additions
        sale_order_id = int(sale_order_id) if sale_order_id else None
        transaction_id = int(transaction_id) if transaction_id else None

        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        print("========================")
        print("/shop/payment/validate")
        print("post------->", post)
        print("transaction_id", transaction_id)
        print("sale_order_id", sale_order_id)
        print("order", order)
        print("========================")

        try:
            transaction_ids = order.transaction_ids()
        except Exception as e:
            transaction_ids = order.transaction_ids

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(transaction_id)
            assert tx in transaction_ids
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        if order and not order.amount_total and not tx:
            order.with_context(send_email=True).action_confirm()
            return request.redirect(order.get_portal_url())

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)
        return request.redirect('/shop/confirmation')


from logging import (
    Logger,
)

from web3.net import (
    AsyncNet,
)

from .base import (
    GethHttpWeb3,
)

class GethNetHttp(GethHttpWeb3):
    """Class for interacting with a Geth node using HTTP with the Geth JSON-RPC
    API.

    This class extends the GethHttpWeb3 class and provides additional methods
    specifically for interacting with the network using the Geth JSON-RPC API.

    The ``url`` is used to indicate the path of the HTTP service of the Geth
    node, usually in the form of ``http://host:port/``. The use of third-party
    nodes may be out of the ordinary.

    The ``logger`` is used to assign a logger of the Python logging module to
    this class. Explicitly assigning a logger can be used to control the output
    location of the logger, which is convenient for debugging.
    """
    def __init__(self, url: str, logger: Logger) -> None:
        super().__init__(url, logger)
        self.net: AsyncNet = self.w3.net
        """Asynchronous Net interface for Web3. Used to simplify the access
        path.
        """

    async def net_listening(self) -> bool:
        """Check if the Geth node is currently listening for connections.

        Returns:
            ``True`` if the node is listening, ``False`` otherwise.
        """
        return await self.net.listening

    async def net_peer_count(self) -> int:
        """Get the number of peers currently connected to the Geth node.

        Returns:
            The number of peers.
        """
        return await self.net.peer_count

    async def net_version(self) -> str:
        """Get the version number of the Geth node.

        Returns:
            str: The version as a string.
        """
        return await self.net.version


import numpy as np
import pylab
import scipy.stats as stats
import pandas as pd
import pandas
import sys
from pandas import Series,DataFrame #此两个为pandas中的数据结构，特别是DataFrame 非常实用
import glob,os
import plotly.offline as py
from plotly.graph_objs import Scatter, Layout
import pprint as pp
import calendar
import plotly.graph_objs as go
import colorlover as cl

def MSE(s1 , s2 ):
	if isinstance(s1 , pandas.core.series.Series) and isinstance(s2 , pandas.core.series.Series):
		if len(s1) == len(s2):
			return sum((s2-s1)**2)/len(s2)
		else:
			sys.exit('two series have different elements')
	else:
		sys.exit('input should be a series')

def MAE(s1 , s2 ) :
	if isinstance(s1 , pandas.core.series.Series) and isinstance(s2 , pandas.core.series.Series):
		if len(s1) == len(s2):
			return sum(abs(s2-s1))/len(s2)
		else:
			sys.exit('two series have different elements')
	else:
		sys.exit('input should be a series')

def RMSE(s1, s2):
	return MSE(s1,s2) ** (1/2)

def error_rate(list1 , list2):
	pass

def PN(TP,TN,FP,FN,):
	name_list = ['accuracy' , 'sensitive','specificity','precision' , 'recall','f1']
	r_dict = { i:0 for i in name_list}
	P = TP + FN
	N = FP + TN
	r_dict['accuracy'] = (TP +TN)/(P+N)
	r_dict['sensitive'] = TP / P
	r_dict['specificity'] = TN/N
	r_dict['precision'] = TP/(TP+FP)
	r_dict['recall'] = TP / P
	r_dict['f1'] = 2*r_dict['precision']*r_dict['recall']  / ( r_dict['precision'] + r_dict['recall'])
	return(r_dict)

def normalization(df):
	df_norm = (df - df.mean()) / (df.max() - df.min())
	return (df_norm)


"""
This module contains a collection of very standard decoding tools that are called from Matlab (XXX.m).
"""

import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

import mne
from mne.decoding import (SlidingEstimator, GeneralizingEstimator,
                        cross_val_multiscore, LinearModel, get_coef)

from sklearn.linear_model import LogisticRegression

##
def logreg_timedecoding(epochs, numcv=4, jobs=1):
    """
    Logistic regression over sensors. Returns Evoked array containing coefficients and ROC.
    Code snippets stolen from:
    https://martinos.org/mne/stable/auto_tutorials/plot_sensors_decoding.html
    """

    X = epochs.get_data()  # MEG signals: n_epochs, n_channels, n_times
    X = X.astype(float)
    y = epochs.events[:, 2]  # targets

    # setup and run the decoder

    clf = make_pipeline(StandardScaler(),  LinearModel(LogisticRegression()))

    time_decod = SlidingEstimator(clf,  scoring='roc_auc', n_jobs=jobs)#scoring='roc_auc',

    scores = cross_val_multiscore(time_decod, X, y, cv=numcv, n_jobs=jobs)

    # Mean scores across cross-validation splits
    scores = np.mean(scores, axis=0)

    #
    time_decod = SlidingEstimator(clf,scoring='roc_auc', n_jobs=jobs)
    time_decod.fit(X, y)

    coef = get_coef(time_decod,'patterns_',inverse_transform=True)

    evoked = mne.EvokedArray(coef, epochs.info, tmin=epochs.times[0])
    evoked.roc_auc=scores

    return evoked

##


"""
An extended dynamic control problem `Instance` with a model for the dynamics.

An :class:`~moptipyapps.dynamic_control.instance.Instance` is a combination of

- a set of differential equations
  (:mod:`~moptipyapps.dynamic_control.system`) that govern the change
  `D=ds/dt` of the state `s` of a dynamic system (based on its current
  state `s` and the controller output `c(s)`), i.e., `ds/dt=D(s,c(s))` and
- a blueprint `c(s, p)` of the controller `c(s)`
  (:mod:`~moptipyapps.dynamic_control.controller`).

The blueprint of the controller is basically a function that can be
parameterized, so it is actually a function `c(s, p)` and the goal of
optimization is to parameterize it in such a way that the figure of merit,
i.e., the objective value (:mod:`~moptipyapps.dynamic_control.objective`)
of the system (usually the sum of squared state values and squared controller
outputs) is minimized. Parameterization means finding good values `p` such
that the above goal is reached. In other words, we want to synthesize a
controller (by finding good values of `p`) in such a way that the state
equations drive the system into a stable state, usually ideally the origin of
the coordinate system.

Now here this :class:`~moptipyapps.dynamic_control.instance.Instance` is
extended to a :class:`~moptipyapps.dynamic_control.system_model.SystemModel`
by adding a parameterized model `M(s, c(s), q)` to the mix. The idea is to
develop the parameterization `q` of the model `M` that can replace the actual
system equations `D`. Such a model receives as input the current system state
vector `s` and the controller output `c(s)` for the state vector `s`. It will
return the differential `D` of the system state, i.e., `ds/dt`. In other
words, a properly constructed model can replace the `equations` parameter in
the ODE integrator :func:`~moptipyapps.dynamic_control.ode.run_ode`. The
input used for training is provided by
:func:`~moptipyapps.dynamic_control.ode.diff_from_ode`.

What we do here is to re-use the same function models as used in controllers
(:mod:`~moptipyapps.dynamic_control.controller`) and learn their
parameterizations from the observed data. If successful, we can  wrap
everything together into a `Callable` and plug it into the system instead of
the original equations.

The thing that :class:`SystemModel` offers is thus a blueprint of the model
`M`. Obviously, we can conceive many different such blueprints. We could have
a linear model, a quadratic model, or maybe neural network (in which case, we
need to decide about the number of layers and layer sizes). So an instance of
this surrogate model based approach has an equation system, a controller
blueprint, and a model blueprint.

An example implementation of the concept of synthesizing models for a dynamic
system in order to synthesize controllers is given as the
:mod:`~moptipyapps.dynamic_control.surrogate_cma` algorithm.
Examples for different dynamic systems controllers (which we here also use to
model the systems themselves) are given in package
:mod:`~moptipyapps.dynamic_control.controllers`.

The starting points of the work here were conversations with Prof. Dr. Bernd
NOACK and Guy Yoslan CORNEJO MACEDA of the Harbin Institute of Technology in
Shenzhen, China (哈尔滨工业大学(深圳)).
"""
from typing import Final

from moptipy.utils.logger import KeyValueLogSection
from moptipy.utils.types import type_error

from moptipyapps.dynamic_control.controller import Controller
from moptipyapps.dynamic_control.instance import Instance
from moptipyapps.dynamic_control.system import System

class SystemModel(Instance):
    """A dynamic system control `Instance` with a system model blueprint."""

    def __init__(self, system: System, controller: Controller,
                 model: Controller) -> None:
        """
        Initialize the system model.

        :param system: the system that we want to model
        :param controller: the controller that we want to use
        :param model: a system model blueprint (also in the shape of a
            controller)
        """
        if not isinstance(model, Controller):
            raise type_error(model, "model", Controller)
        super().__init__(system, controller, model.name)
        in_dims: Final[int] = system.state_dims + controller.control_dims
        if model.state_dims != in_dims:
            raise ValueError(
                f"model.state_dims={model.state_dims}, but system.state_dims"
                f"={system.state_dims} and controller.control_dims="
                f"{controller.control_dims}, so we expected {in_dims} for "
                f"controller {str(controller)!r}, system {str(system)!r}, and"
                f" model {str(model)!r}.")
        if model.control_dims != system.state_dims:
            raise ValueError(
                f"model.control_dims={model.control_dims} must be the same as"
                f" system.state_dims={system.state_dims}, but is not, for "
                f"controller {str(controller)!r}, system {str(system)!r}, and"
                f" model {str(model)!r}.")
        #: the model blueprint that can be trained to hopefully replace the
        #: :attr:`~moptipyapps.dynamic_control.instance.Instance.system` in the
        #: ODE integration / system simulation procedure
        self.model: Final[Controller] = model

    def log_parameters_to(self, logger: KeyValueLogSection) -> None:
        """
        Log all parameters of this component as key-value pairs.

        :param logger: the logger for the parameters
        """
        super().log_parameters_to(logger)
        with logger.scope("model") as scope:
            self.model.log_parameters_to(scope)


import sys

card_number = int(sys.argv[1])
color_number = int(sys.argv[2])

# card_number = 4
# color_number = 4

colors = ['255,69,0', '255,140,0', '34,139,34', '100,149,237', '30,144,255', '0,0,128', '138,43,226', '139,0,139',
		  '255,20,147', '210,105,30']

f = open('single_image_creation.tex', 'w')
f.write(chr(92) + 'documentclass[tikz,border=0pt]' + chr(123) + 'standalone}' + '\n')
f.write(chr(92) + 'definecolor' + chr(123) + 'CardColor}' + chr(123) + 'RGB}{' + colors[color_number-1] + '}' + '\n')

f.write(chr(92) + 'newlength{' + chr(92) + 'cardwidth}' + '\n')
f.write(chr(92) + 'newlength{' + chr(92) + 'cardheight}' + '\n')
f.write(chr(92) + 'setlength{' + chr(92) + 'cardwidth}{6mm}' + '\n')
f.write(chr(92) + 'setlength{' + chr(92) + 'cardheight}{10mm}' + '\n')

f.write(chr(92) + 'begin' + chr(123) + 'document}' + '\n')
f.write(chr(92) + 'begin' + chr(123) + 'tikzpicture}' + '\n')

f.write('' + chr(92) + 'path[fill=CardColor] (0mm, 0mm) rectangle (' + chr(92) + 'cardwidth, ' + chr(92) + 'cardheight);' + '\n')
f.write('' + chr(92) + 'draw (.5' + chr(92) + 'cardwidth, .5' + chr(92) + 'cardheight) node [text width=.5' + chr(92) + 'cardwidth, align=center, color = white]{' + chr(92) + 'fontsize{10}{2}' + chr(92) + 'selectfont' + str(card_number) + '};' + '\n')

f.write(chr(92) + 'end' + chr(123) + 'tikzpicture}' + '\n')
f.write(chr(92) + 'end' + chr(123) + 'document}' + '\n')

# pdflatex -no-shell-escape  images/single_image_creation.tex


import pygame as pg
from pygame.locals import *
from column import Column
from score import Score
from menu import menuEnum, pauseMenu, gameoverMenu
import random

# The main game class
class Game:

    def __init__(self, gameConfig, lvlConfig):

        # Save the config
        self.screen = pg.display.get_surface()
        self.gameConfig = gameConfig
        self.lvlConfig = lvlConfig

        # Variables
        self.game_speed = gameConfig.speed
        self.generation_frequency = lvlConfig.gen_frequency
        self.active = gameConfig.default_active

        # Columns
        self.col_group = pg.sprite.Group()
        self.input_group = pg.sprite.Group()

        # The score
        self.score = pg.sprite.GroupSingle(Score(
            lvlConfig.lvl,
            lvlConfig.columns,
            pg.font.Font(self.gameConfig.font_path, 30),
            self.gameConfig.score_rect
        ))

        # Events
        self.GENERATE = USEREVENT + 1 # Generate new equation event
        self.SPEEDUP = USEREVENT + 2  # Increase the game speed event

        self.paused = False

        self.__setGraphics()

    # Create and set columns to their correct positions
    def __setGraphics(self):
        self.columns_rect = pg.Rect(
            self.gameConfig.board_left,
            self.gameConfig.board_top,
            self.gameConfig.col_width * self.lvlConfig.columns,
            self.gameConfig.col_height + self.gameConfig.input_height
        )
        for i in range(self.lvlConfig.columns):
            col_rect = pg.Rect(
                self.gameConfig.board_left + i * self.gameConfig.col_width,
                self.gameConfig.board_top,
                self.gameConfig.col_width,
                self.gameConfig.col_height)
            self.col_group.add(Column(
                i,
                self.gameConfig,
                self.lvlConfig,
                col_rect,
                self.input_group))
        self.columns = self.col_group.sprites() # Alias
        self.active_col = self.columns[self.gameConfig.default_active]

    def reset(self):
        self.score.sprite.reset()
        for col in self.columns:
            col.reset()
        self.game_speed = self.gameConfig.speed
        self.generation_frequency = self.lvlConfig.gen_frequency

        self.active_col.deactivate()
        self.active_col = self.columns[self.gameConfig.default_active]
        self.active_col.activate()

        pg.time.set_timer(self.GENERATE, self.generation_frequency)
        pg.time.set_timer(self.SPEEDUP, self.lvlConfig.inc_frequency)

        pg.event.clear()

        self.paused = False

    def run(self):

        clock = pg.time.Clock()
        self.active_col = self.columns[self.gameConfig.default_active]
        self.active_col.activate()

        pg.time.set_timer(self.GENERATE, self.lvlConfig.gen_frequency)
        pg.time.set_timer(self.SPEEDUP, self.lvlConfig.inc_frequency)

        # Create menus
        pauseM = pauseMenu(self.screen.get_width(), self.screen.get_height())
        pauseM.disable()

        gameoverM = gameoverMenu(self.columns_rect.width, self.columns_rect.height)
        gameoverM.set_absolute_position(self.columns_rect.left, self.columns_rect.top)
        gameoverM.disable()

        self.paused = False # paused iff either pause or gameover menu is active

        self.screen.fill((0, 0, 0))
        pg.display.flip()
        while 1:
            events = pg.event.get()
            for event in events:
                if event.type == QUIT:
                    return

                # Check game-related events iff not self.paused
                if not self.paused:

                    if event.type == self.GENERATE:
                        # Generate new equation for a random column
                        self.columns[random.randrange(0, self.lvlConfig.columns)].generate_eq()

                    elif event.type == self.SPEEDUP:
                        self.game_speed *= self.gameConfig.increment
                        self.generation_frequency = self.generation_frequency // self.gameConfig.increment
                        pg.time.set_timer(self.GENERATE, int(self.generation_frequency))

                    elif event.type == KEYDOWN:

                        k = event.key
                        # Change active column to one to the left or the right
                        if k in [K_LEFT, K_RIGHT]:
                            self.active_col.deactivate()
                            if k == K_LEFT:
                                new_active = self.active_col.index - 1
                            else:
                                new_active = self.active_col.index + 1
                            new_active %= self.lvlConfig.columns
                            self.active_col = self.columns[new_active]
                            self.active_col.activate()

                        # Get input into the active column's input field
                        elif k in [K_BACKSPACE, K_MINUS] or k in range(K_0, K_9 + 1):
                            self.active_col.get_input(event.key)

                        # Check the input entered into the active field
                        # And update the score
                        elif k == K_RETURN:
                            self.active_col.check(self.game_speed, self.score)

                        # Pause the game
                        elif k == K_ESCAPE:
                            self.paused = True
                            pauseM.enable()

            # Display pause menu
            if pauseM.is_enabled():
                pauseM.draw(self.screen)
                pauseM.update(events)
                pg.display.flip()

                if pauseM.state == menuEnum.BACK_TO_MENU:
                    pauseM.disable()
                    return
                elif pauseM.state == menuEnum.RESUME:
                    pauseM.state = menuEnum.OPEN
                    pauseM.disable()
                    self.screen.fill((0, 0, 0))
                    pg.display.flip()

            # Display gameover menu
            elif gameoverM.is_enabled():
                gameoverM.draw(self.screen)
                gameoverM.update(events)
                pg.display.flip()

                if gameoverM.state == menuEnum.BACK_TO_MENU:
                    gameoverM.disable()
                    return
                elif gameoverM.state == menuEnum.RESTART:
                    gameoverM.state = menuEnum.OPEN
                    gameoverM.disable()
                    self.reset()
                    self.screen.fill((0, 0, 0))
                    pg.display.flip()

            # Else display and update the game
            else:
                self.screen.fill((0, 0, 0))

                # Draw the game elements
                self.col_group.draw(self.screen)
                self.input_group.draw(self.screen)
                self.score.draw(self.screen)

                # Check for gameover when updating columns
                # (whether an equation hits the bottom)
                self.paused = False
                for col in self.columns:
                    gameover = col.update(self.game_speed / self.gameConfig.fps)
                    if gameover:
                        gameoverM.enable()
                        self.paused = True
                        break

                # Update only parts of the screen containing
                # the game elements
                pg.display.update([self.columns_rect, self.gameConfig.score_rect])

            clock.tick(self.gameConfig.fps)


# -*- coding: utf-8 -*-
"""
# Created by Guilhermi M. Crispi at Tue Apr 27 13:18:54 2021

============================
Titulo: #Divide_images_to_patches
Descricao: #https://youtu.be/-u8PHmHxJ5Q
============================

"""
#%%
import numpy as np
from patchify import patchify, unpatchify
import cv2
import os

#%%

patch_size = 128
step = 128

image_path = "C:/Users/guilh/Desktop/h_masks/images/"
for img in os.listdir(image_path):
    #print(img)
    #Needs 8 bit, not float.
    image = cv2.imread(image_path+img,0) # só consigo utilizando o 0, imagem preto e branca salva

    image_patches = patchify(image, (patch_size, patch_size), step=step)

    m, n = image_patches.shape[0], image_patches.shape[1]

    for i in range(m):
        for j in range(n):
            print(i,j)
            patch = image_patches[i,j]
            cv2.imwrite("C:/Users/guilh/Desktop/IMG_20210331_084321_json/128_patches_images/"
                        +"_"+img+str(i)+"_"+str(j)+".png", patch)

mask_path = "C:/Users/guilh/Desktop/IMG_20210331_084321_json/mask/"
for msk in os.listdir(mask_path):
    #print(img)
    #Needs 8 bit, not float.
    mask = cv2.imread(mask_path+msk, 0)

    mask_patches = patchify(mask, (patch_size, patch_size), step=step)

    x, y = mask_patches.shape[0], mask_patches.shape[1]

    for i in range(x):
        for j in range(y):
            print(i,j)
            patch = mask_patches[i,j]
            cv2.imwrite("C:/Users/guilh/Desktop/IMG_20210331_084321_json/128_patches_masks/"
                        +"_"+msk+str(i)+"_"+str(j)+".png", patch)

#%%
reconstructed_image = unpatchify(patches, image.shape)


import pygame
import random
import sys

pygame.init()

width=800
height=800
play_width=600
play_height=600
block_size=30

top_left_x=(width-play_width)//2
top_left_y=(height-play_height)//2

dug={(-1,-1)}

imageb=pygame.image.load('Minesweeper/Image/bomb.png')
imagef=pygame.image.load('Minesweeper/Image/flag.png')
image1=pygame.image.load('Minesweeper/Image/one.png')
image2=pygame.image.load('Minesweeper/Image/two.png')
image3=pygame.image.load('Minesweeper/Image/three.png')
image4=pygame.image.load('Minesweeper/Image/four.png')
image5=pygame.image.load('Minesweeper/Image/five.png')
image6=pygame.image.load('Minesweeper/Image/six.png')
image7=pygame.image.load('Minesweeper/Image/seven.png')
image8=pygame.image.load('Minesweeper/Image/eight.png')
trophy=pygame.image.load('Minesweeper/Image/trophy.png')
skull=pygame.image.load('Minesweeper/Image/losing.png')
background=pygame.image.load('Minesweeper/Image/background.jpg')
back=pygame.image.load('Minesweeper/Image/back.jpg')
replay=pygame.image.load('Minesweeper/Image/replay.png')
replay1=pygame.image.load('Minesweeper/Image/replay1.png')
caption=pygame.image.load('Minesweeper/Image/icon.png')

icon=[None,image1,image2,image3,image4,image5,image6,image7,image8,imageb,imagef]

def print_board(screen):
    for i in range(play_width//block_size+1):
        pygame.draw.line(screen,(0,0,0),(top_left_x+i*block_size,top_left_y),\
            (top_left_x+i*block_size,top_left_y+play_height),3)
    for j in range(play_height//block_size+1):
        pygame.draw.line(screen,(0,0,0),(top_left_x,top_left_y+j*block_size),\
        (top_left_x+play_width,top_left_y+j*block_size),3)

def print_grid(screen,grid,bomb=True):
    for i in range(play_width//block_size):
        for j in range(play_height//block_size):
            pygame.draw.rect(screen,(255,255,255),(top_left_x+i*block_size,\
            top_left_y+j*block_size,block_size,block_size))
            if grid[i][j][1]!=None and grid[i][j][0]==None:
                if grid[i][j][1]==0:
                    pygame.draw.rect(screen,(105,105,105),(top_left_x+i*block_size,\
                top_left_y+j*block_size,block_size,block_size))
                else:
                    if bomb:
                        if grid[i][j][1]==9:
                            continue
                    screen.blit(icon[grid[i][j][1]],(top_left_x+i*block_size+2,\
                    top_left_y+j*block_size+4))
            if grid[i][j][0]==1:
                screen.blit(icon[10],(top_left_x+i*block_size+2,\
                    top_left_y+j*block_size+4))
    print_board(screen)

def print_text(surface,string,x,y,size,color):
    font=pygame.font.SysFont('comicsans',size)
    render=font.render(string,True,color)
    font.set_bold(True)
    surface.blit(render,(x,y))

def win_condition(grid):
    for i in range(play_width//block_size):
        for j in range(play_height//block_size):
            if grid[i][j][1]==None:
                return True
    return False

def place_mines(nums,grid):
    mines=0
    while mines<nums:
        x,y=random.randint(0,play_width//block_size-1),random.randint(0,play_height//block_size-1)
        if grid[x][y][1]!=9:
            grid[x][y][1]=9
            mines+=1

def number_mines(grid,x,y):
    if grid[x][y][1]==9:
        return 9
    number_mines=0
    for i in range(max(0,x-1),min(play_width//block_size,x+2)):
        for j in range(max(0,y-1),min(play_height//block_size,y+2)):
            if grid[i][j][1]==9:
                number_mines+=1
    return number_mines

def dig(grid,x,y):
    global dug
    dug.add((x,y))
    if number_mines(grid,x,y)!=0:
        grid[x][y][1]=number_mines(grid,x,y)
        return True
    elif number_mines(grid,x,y)==0:
        grid[x][y][1]=0
    for r in range(max(0,x-1),min(play_width//block_size,x+2)):
        for c in range(max(0,y-1),min(play_height//block_size,y+2)):
            if (r,c) in dug:
                continue
            dig(grid,r,c)

def main(screen):
    global dug
    final_grid=[[[None,None] for _ in range(play_width//block_size)]\
    for _ in range(play_height//block_size)]
    place_mines(20,final_grid)
    running=True
    screen.blit(background,(0,0))
    screen.blit(replay,(20,20))
    while running:
        x,y=pygame.mouse.get_pos()
        if 20<x<84 and 20<y<84:
            screen.blit(replay1,(20,20))
        else:
            screen.blit(replay,(20,20))
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                running=False
            if win_condition(final_grid) or running:
                if event.type==pygame.MOUSEBUTTONDOWN:
                    if 20<x<84 and 20<y<84:
                        final_grid=[[[None,None] for _ in range(play_width//block_size)]\
                        for _ in range(play_height//block_size)]
                        place_mines(20,final_grid)
                        dug={(-1,-1)}
                        running=True
                    if top_left_x<x<top_left_x+play_width and\
                        top_left_y<y<top_left_y+play_height:
                        col=(x-top_left_x)//block_size
                        row=(y-top_left_y)//block_size
                        if event.button==1:
                            if final_grid[col][row][1]==9:
                                print_grid(screen,final_grid,bomb=False)
                                running=False
                                break
                            if final_grid[col][row][0]==None:
                                dig(final_grid,col,row)
                        if event.button==3:
                            if final_grid[col][row][1] in (None,9) and final_grid[col][row][0]==None:
                                final_grid[col][row][0]=1
                            elif final_grid[col][row][0]==1:
                                final_grid[col][row][0]=None
                print_grid(screen,final_grid)
        if not running:
            dug={(-1,-1)}
            print_grid(screen,final_grid,bomb=False)
            screen.blit(skull,(width/2-256/2,height/2-256))
        if not win_condition(final_grid):
            running=False
            dug={(-1,-1)}
            print_grid(screen,final_grid,bomb=False)
            screen.blit(trophy,(width/2-256/2,height/2-256))
        pygame.display.update()

    print_text(screen,'PRESS TO PLAY',150,height//2,100,(255,0,0))
    print_text(screen,'AGAIN',300,height//2+100,100,(255,0,0))

def main_menu():
    screen=pygame.display.set_mode((width,height))
    pygame.display.set_caption('Minesweeper')
    pygame.display.set_icon(caption)
    screen.blit(back,(0,0))
    print_text(screen,'PRESS TO PLAY',150,height//2,100,(255,255,255))
    run=True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run=False
            if event.type == pygame.KEYDOWN:
                main(screen)
        pygame.display.update()

if __name__=='__main__':
    main_menu()


from typing import Counter
from collections import deque
from graph_list import Graph

def topological_sort(gph):
    stk = []
    count = gph.count
    visited = [False] * count
    for i in range(count):
        if visited[i] == False:
            topological_sort_dfs(gph, i, visited, stk)
    print("Topological Sort :: ", end=' ')
    while len(stk) != 0:
        print(stk.pop(), end=' ')

def topological_sort_dfs(gph, index, visited, stk):
    visited[index] = True
    for edge in gph.adj[index]:
        destination = edge[0]
        if visited[destination] == False:
            topological_sort_dfs(gph, destination, visited, stk)
    stk.append(index)

def path_exists(gph, source, destination):
    count = gph.count
    visited = [False] * count
    dfs_util(gph, source, visited)
    return visited[destination]

def dfs_util(gph, index, visited):
    visited[index] = True
    for edge in gph.adj[index]:
        destination = edge[0]
        if visited[destination] == False:
            dfs_util(gph, destination, visited)

def count_all_paths_dfs(gph, visited, source, dest):
    if source == dest:
        return 1
    count = 0
    visited[source] = 1
    for edge in gph.adj[source]:
        if visited[edge[0]] == 0:
            count += count_all_paths_dfs(gph, visited, edge[0], dest)
    visited[source] = 0
    return count

def print_all_paths_dfs(gph, visited, source, dest, path):
    path.append(source)
    if source == dest:
        print(path)
        return
    visited[source] = 1
    for edge in gph.adj[source]:
        if visited[edge[0]] == 0:
            print_all_paths_dfs(gph, visited, edge[0], dest, path)
    visited[source] = 0
    path.pop()

def root_vertex(gph):
    count = gph.count
    visited = [False] * count
    retVal = -1
    for i in range(count):
        if visited[i] == False:
            dfs_util(gph, i, visited)
            retVal = i
    print("Root vertex is :: ", retVal)

def transitive_closure_util(gph, source ,index, tc):
    if tc[source][index] == 1:
        return
    tc[source][index] = 1
    for edge in gph.adj[index]:
            transitive_closure_util(gph, source, edge[0], tc)

def transitive_closure(gph):
    count = gph.count
    tc = [[0 for _ in range(count)] for _ in range(count)]
    for source in range(count):
        transitive_closure_util(gph, source, source, tc)
    for row in tc:
        print(row)
    return tc

def bfs_distance(gph, source, dest):
    count = gph.count
    visited = [False] * count
    visited[source] = True
    que = deque([])
    que.append((source, 0))
    while len(que) != 0:
        node = que.popleft()
        curr = node[0]
        depth = node[1]
        for edge in gph.adj[curr]:
            if edge[0] == dest:
                return depth+1
            if visited[edge[0]] == False:
                que.append((edge[0], depth+1))
                visited[edge[0]] = True
    return -1

def bfs_level_node(gph, source):
    count = gph.count
    visited = [False] * count
    visited[source] = True
    que = deque([])
    que.append((source, 0))
    print("\nNode  - Level")
    while len(que) != 0:
        node = que.popleft()
        curr = node[0]
        depth = node[1]
        print(curr ," - ", depth)
        for edge in gph.adj[curr]:
            destination = edge[0]
            if visited[destination] == False:
                que.append((destination, depth+1))
                visited[destination] = True

def is_cycle_present_undirected_dfs(graph, index, parentIndex, visited):
    visited[index] = True
    for node in graph.adj[index]:
        dest = node[0]
        if visited[dest] == False:
            if is_cycle_present_undirected_dfs(graph, dest, index, visited) :
                return True
        elif parentIndex != dest :
            return True
    return False

def is_cycle_present_dfs(graph, index, visited, marked):
    visited[index] = True
    marked[index] = True
    for node in graph.adj[index]:
        dest = node[0]
        if marked[dest] == True:
            return True
        if visited[dest] == False:
            if is_cycle_present_dfs(graph, dest, visited, marked) :
                return True
    marked[index] = False
    return False

def transpose_graph(gph):
    count = gph.count
    g = Graph(count)
    for i in range(count):
        for edge in gph.adj[i]:
            destination = edge[0]
            g.add_direct_edge(destination, i)
    return g

def is_connected_undirected(gph):
    count = gph.count
    visited = [False] * count
    dfs_util(gph, 0, visited)
    for i in range(count):
        if visited[i] == False:
            return False
    return True

def is_strongly_connected(gph):
    count = gph.count
    visited = [False] * count
    dfs_util(gph, 0, visited)
    for i in range(count):
        if visited[i] == False:
            return False
    graph_reversed = transpose_graph(gph)
    visited = [False] * count
    dfs_util(graph_reversed, 0, visited)
    for i in range(count):
        if visited[i] == False:
            return False
    return True

def dfs_util2(gph, index, visited, stk):
    visited[index] = True
    for edge in gph.adj[index]:
        destination = edge[0]
        if visited[destination] == False:
            dfs_util2(gph, destination, visited, stk)
    stk.append(index)

def strongly_connected_component(gph):
    count = gph.count
    visited = [False] * count
    stk = []
    for i in range(count):
        if visited[i] == False:
            dfs_util2(gph, i, visited, stk)

    graph_reversed = transpose_graph(gph)
    visited = [False] * count
    while len(stk) != 0:
        index = stk.pop()
        if visited[index] == False:
            stk2 = []
            dfs_util2(graph_reversed, index, visited, stk2)
            print(stk2)

def primsMST(gph):
    previous = [-1] * gph.count
    dist = [sys.maxsize] * gph.count
    visited = [False] * gph.count
    source = 0
    dist[source] = 0
    previous[source] = -1
    pq = PriorityQueue()
    for i in range(gph.count):
        pq.add(sys.maxsize, i)
    pq.update_key(0, source)

    while pq.size() != 0:
        val = pq.pop()
        source = val[1]
        visited[source] = True

        for edge in gph.adj[source]:
            destination = edge[0]
            cost = edge[1]
            if cost < dist[destination] and visited[destination] == False:
                dist[destination] = cost
                previous[destination] = source
                pq.update_key(cost, destination)

    total_cost = 0

    for i in range(gph.count):
        if dist[i] == sys.maxsize:
            print("node id" , i , "prev" , previous[i] , "distance : Unreachable")
        else:
            print("node id" , i , "prev" , previous[i] , "distance :" , dist[i])
            total_cost += dist[i]

    print("Total MST cost: ", str(total_cost))


# -*- coding: utf-8 -*-
"""
Created on Fri Jul  5 01:24:52 2019

@author: Inki
"""

from threading import Thread
import tweepy
import time
import random
import keys
import log

auth = tweepy.OAuthHandler(keys.Consumer_Key_Following, keys.CONSUMER_SECRET_Following)
auth.set_access_token(keys.ACCESS_KEY_Following, keys.ACCESS_SECRET_Following)
api = tweepy.API(auth, wait_on_rate_limit=True)

class following(Thread):
    FILE_NAME = 'RTlast_seen_id.txt'
    log.log("dentro de following")

    def run(self):
        self.follow()

    def retrieve_last_seen_id(self, file_name):
        f_read = open(file_name, 'r')
        last_seen_id = int(f_read.read().strip())
        f_read.close()
        return last_seen_id

    def store_last_seen_id(self, last_seen_id, file_name):
        f_write = open(file_name, 'w')
        f_write.write(str(last_seen_id))
        f_write.close()
        return

#    def store_followrs()
#        with open('following.txt') as csv_file:
#            csv_reader = csv.reader(csv_file, delimiter=',')
#            line_count = 0
#            for row in csv_reader:
#                if line_count == 0:
#                    print(f'Column names are {", ".join(row)}')
#                    line_count += 1
#                else:
#                    print(f'\t{row[0]} works in the {row[1]} department, and was born in {row[2]}.')
#                    line_count += 1
#            print(f'Processed {line_count} lines.')

    def follow(self):
        while True:
            log.log("dentro de  def follow(self):")
            last_seen_id = self.retrieve_last_seen_id(self.FILE_NAME)
#            lasttweets=api.home_timeline(since_id=last_seen_id, tweet_mode='extended', count=1)
            lasttweets=api.home_timeline(tweet_mode='extended', count=3)
            log.log(lasttweets)
            for tweet in reversed(lasttweets) :
                lista=api.user_timeline(screen_name=tweet.user.screen_name, count=10)
                log.log(lista)
                count=0
                valoraciontotal=0
                for lista in lista:
                    log.log(lista.text)
                    followers=lista.user.followers_count
                    valor=(followers)/random.randint(1,500)
                    log.log("Con {0} followers, Valor {1} para seguir a {2}".format(followers, valor, lista.user.screen_name))
                    count += 1
                    valoraciontotal+=valor

                    if valor >= 2000:
                                api.create_friendship(screen_name=lista.user.screen_name)
                                log.log("Seguido a {0}".format(lista.user.screen_name))
#                                time.sleep(random.randint(5, 120))
                                last_seen_id = tweet.id
                                self.store_last_seen_id(last_seen_id, self.FILE_NAME)
                    else:
                        log.log("No seguido a {0}".format(lista.user.screen_name))
                media=valoraciontotal/count
                log.log("Media de valores {0} para {1} muestras".format(media, count))
                last_seen_id = tweet.id
                self.store_last_seen_id(last_seen_id, self.FILE_NAME)

#
#    def follow(self):
#        while True:
#            last_seen_id = self.retrieve_last_seen_id(self.FILE_NAME)
#            lasttweets=api.home_timeline(since_id=last_seen_id, tweet_mode='extended', count=1)
#            for tweet in reversed(lasttweets) :
#


text = list(map(str,input()))
count =0
for i in range(0, len(text)-1):
    temp = len(text)-1 - i
    if text[i] == text[temp]:
        count += 0
    else:
        count += 1
if count == 0:
    print('1')
else:
    print('0')


# -*- coding: UTF-8 -*-

'''
Created on 2017年2月8日

@author: Administrator
广告展示模块测试用例
'''

from appiumTest.PublicClass import clickText,swipeLeft, getScreenShot
import time
'''-----------------------------------定位弹窗框-----------------------------
1、定位弹窗：允许、不允许
2、升级提醒弹窗：取消、升级

 '''
class TanChuangChuLi():
    def tanChuang(self):
        myBoolean=True
        while myBoolean:
            try:
                if clickText("允许"):
                    continue
                elif clickText("不允许"):
                    continue
                elif clickText("取消"):
                    continue
                elif clickText("升级"):
                    continue
                else:
                    print("未弹出权限处理")
                    myBoolean=False
            except:
                print("捕获到异常")
                continue
        else:
            print("退出弹框处理")
'''----------------------------------广告展示--------------------------------
多页面滑动切换广告展示：向左滑动，向右滑动，向左向右滑动、向右向左滑动
getScreenShot()为截屏方法
        '''
class HuaDongChuli():
    def HuaDong(self):
        time.sleep(1)
        getScreenShot("进入时默认展示的广告页面")
        swipeLeft(1000)
        time.sleep(1)
        getScreenShot("第一次滑动后的广告页面")
        swipeLeft(1000)
        time.sleep(1)
        getScreenShot("第二次滑动后的广告页面")
        swipeLeft(1000)
        time.sleep(1)
        getScreenShot("第三次滑动后的广告页面")

        clickText("登 录")


import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import svm
from sklearn.datasets import load_iris
from sklearn.inspection import DecisionBoundaryDisplay
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import ConfusionMatrixDisplay, accuracy_score, confusion_matrix, classification_report

dataset = load_iris()
data = dataset.data
target = dataset.target
classifications = dataset.target_names

# Splits the data into a training set and a validation set, is later used in the classifier
dataTrain, dataTest, targetTrain, targetTest = train_test_split(data, target, random_state=0)

logRegress = LogisticRegression()
logRegress.fit(dataTrain, targetTrain)
targetPrediction = logRegress.predict(dataTest)

#print(confusion_matrix(targetTest, targetPrediction))
#print(classification_report(targetTest, targetPrediction))

# Model that is too regularized (C too low) to see the impact on the results
classifier = svm.SVC(kernel="linear", C=100).fit(dataTrain, targetTrain)
np.set_printoptions(precision=2)

# Plot non-normalized and normalized confusion matrix
titles_options = [
    ("Confusion matrix, without normalization", None),
    ("Confusion matrix, with normalization", "true"),
]

for title, normalize in titles_options:
    disp = ConfusionMatrixDisplay.from_estimator(
        classifier,
        dataTest,
        targetTest,
        display_labels=classifications,
        cmap=plt.cm.Blues,
        normalize=normalize,
    )
plt.show()

'''-----------------------------------------------------------------------------------------------------------------'''

from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics

# Testing uniform-based k neighbors from 1 to 100
for i in range(1, 100, 5):
    kNeighborsUniform = KNeighborsClassifier(n_neighbors=i, weights='uniform')
    kNeighborsUniform.fit(dataTrain, targetTrain)
    targetPredUniform = kNeighborsUniform.predict(dataTest)

    print("Accuracy in percentage for uniform, given", i, "neighbors:",
          metrics.accuracy_score(targetTest, targetPredUniform) * 100, "%")
    print(confusion_matrix(targetTest, targetPredUniform))
    print(classification_report(targetTest, targetPredUniform))

print(' ')

# testing distance-based k neighbors from 1 to 100
for i in range(1, 100, 5):
    kNeighborsDistance = KNeighborsClassifier(n_neighbors=i, weights='distance')
    kNeighborsDistance.fit(dataTrain, targetTrain)
    targetPredDistance = kNeighborsDistance.predict(dataTest)

    print("Accuracy in percentage for distance, given", i, "neighbors:",
          metrics.accuracy_score(targetTest, targetPredDistance) * 100, "%")


# while loops

total2 = 0
j = 1
while j < 5:
    total2 += j
    j += 1
# print(total2)

given_list = [5, 4, 4, 3, 1, -2, -3, -5]
total3 = 0
i = 0
while given_list[i] > 0:
    total3 += given_list[i]
    i += 1
# print(total3)

given_list = [5, 4, 4, 3, 1]
total3 = 0
i = 0
while i < len(given_list) and given_list[i] > 0:
    total3 += given_list[i]
    i += 1
# print(total3)

# for loop example
given_list2 = [5, 4, 4, 3, 1, -2, -3, -5]
total4 = 0
for element in given_list2:
    if element <= 0:
        break
    total4 += element
# print(total4)

total5 = 0
i = 0

while True:
    total5 += given_list2[i]
    i += 1
    if given_list2[i] <= 0:
        break
print(total5)

# exercise
given_list3 = [7, 5, 4, 4, 3, 1, -2, -3, -5, -7]