'''
Created on 2. feb. 2017

@author: ELP
'''
# Script makes plots for BROM output comparing
#with WOD data
# Creates separated pdf(or png) files and can
# combine them into 1 multipage pdf

import pdb #python debugger
from netCDF4 import Dataset
from netCDF4 import num2date, date2num
import numpy.ma as ma
import numpy as np
from scipy import interpolate
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
import pandas as pd
from  matplotlib.backends.backend_pdf import PdfPages
import pylab
import matplotlib.gridspec as gridspec
import datetime
from PyPDF2 import PdfFileWriter, PdfFileReader,PdfFileMerger
plt.style.use('ggplot')
import os, sys
import tkinter as tk
from tkinter.filedialog import askopenfilename

def read_netcdf_odv(ncfile):

    fh = Dataset(ncfile, mode='r')
    #depth = fh.variables['var1'][:][:]
    depthmasked = fh.variables['var1'][:][:]
    depth = depthmasked.filled(fill_value= np.nan)
    depth2 = fh.variables['var1'][:][:]
    temp = fh.variables['var2'][:][:]
    sal = fh.variables['var3'][:][:]
    o2 = fh.variables['var4'][:][:]
    po4 = fh.variables['var5'][:][:]
    si = fh.variables['var6'][:][:]
    no3 = fh.variables['var7'][:][:]
    no2 = fh.variables['var8'][:][:]
    pH = fh.variables['var9'][:][:]
    chl = fh.variables['var10'][:][:]
    alk = fh.variables['var12'][:][:]
    date_time = fh.variables['date_time'][:]
    lat = fh.variables['latitude'][:]
    long = fh.variables['longitude'][:]
    fh.close()

    dates = num2date(date_time[:],units='days since 1990-01-01',
                 calendar='proleptic_gregorian' )

    return depth,temp,sal,o2,po4,si,no3,no2,pH,chl,dates,alk,depth2

ncfile = 'data_from_Baltic_small_domain_1980.nc'
w = read_netcdf_odv(ncfile)

depth = w[0]
temp = w[1]
sal = w[2]
o2 = w[3]
po4 = w[4]
si = w[5]
no3 = w[6]
no2 = w[7]
pH = w[8]
chl = w[9]
dates = w[10]
alk = w[11]
depth2 = w[12]

#o2[o2 > 0] =  o2 * 46.6
o2_2 = o2 * 46.6 # change units from ml/l to mmol/l
pH_2 = pH - 0.11 # conversion from NBS scale to Total
alk_2 = alk * 1000 # change units from meq/l to mmol/m-3
#def read_necdf_brom(ncfile_brom):

# = 'BROM_Baltic_out_3.nc'
root = tk.Tk()
root.withdraw() #To show only the dialog without any other GUI elements
# Get the dialog and choose the file to read
ask_filename = askopenfilename(initialdir= os.getcwd(),
                           filetypes =(("NetCDF file", "*.nc"),("All Files","*.*")),
                           title = "Choose a file.")

#We get the whole path to file
# So we split it and take the the second element (only name.nc)                           )
nc_file_brom = ask_filename #os.path.split()[0]

fh1 = Dataset(nc_file_brom, mode='r')

depth_brom = fh1.variables['z'][:]
depth2_brom =  fh1.variables['z2'][:] #middle points
kz =  fh1.variables['Kz'][:,:]
o2_brom  =  fh1.variables['O2'][:,:]
sal_brom  =  fh1.variables['S'][:,:]
temp_brom = fh1.variables['T'][:,:]
pH_brom = fh1.variables['pH'][:,:]
po4_brom = fh1.variables['PO4'][:,:]
no2_brom = fh1.variables['NO2'][:,:]
no3_brom = fh1.variables['NO3'][:,:]
si_brom = fh1.variables['Si'][:,:]
alk_brom = fh1.variables['Alk'][:,:]

fh1.close()

len_depth2_brom = depth2_brom.size

for n in range(0,(len_depth2_brom-1)):
    if kz[1,n] == 0:
        y2max = depth2[n]
        ny2max = n-2
        break

def figure_pdf(var_wod,var_brom,varname):
    with PdfPages('Baltic_validation_{}.pdf'.format(varname)) as pdf:

        # As many times as you like, create a figure fig and save it:
        figure = plt.figure(figsize=( 11.69 ,8.27), dpi=100)
        gs = gridspec.GridSpec(2,2)
        gs.update(wspace=0.1,hspace = 0.2,left=0.04,
               right=0.99,bottom = 0.04, top = 0.9)
        ax00 = figure.add_subplot(gs[0])
        ax01 = figure.add_subplot(gs[1])
        ax02 = figure.add_subplot(gs[2])
        ax03 = figure.add_subplot(gs[3])
        ax00.set_title('{} from BROM all days'.format(varname))
        ax01.set_title('{} from BROM every 10 day'.format(varname))
        ax02.set_title('{} from WOD '.format(varname))
        ax03.set_title('BROM vs WOD ')
        #plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
        plt.title('{} from BROM all days'.format(varname))
        ax00.set_ylim(100,0)
        ax01.set_ylim(100,0)
        ax02.set_ylim(100,0)
        ax03.set_ylim(100,0)
        #if str(var_brom) == str(o2_brom) :
        #    ax00.set_xlim(0,550)

        for ax in (ax00,ax01,ax02,ax03):
            if str(var_brom) == str(o2_brom) :
                ax.set_xlim(-0.5,550)
            elif str(var_brom) == str(sal_brom) :
                ax.set_xlim(6,15)
            elif str(var_brom) == str(temp_brom) :
                ax.set_xlim(-0.5,24)
            elif str(var_brom)== str(pH_brom) :
                ax.set_xlim(6.5,9.5)
            elif str(var_brom) == str(po4_brom) :
                ax.set_xlim(-0.5,5)
            elif str(var_brom) == str(si_brom) :
                ax.set_xlim(-0.5,80)
            elif str(var_brom) == str(no3_brom) :
                ax.set_xlim(-0.5,12)
            else:
                pass
        for m in range(0,365,1):
            ax00.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                      linewidth = 0.2,color = 'red') #n - day

        lenght = (len(var_wod))
        for n in range(0,lenght): #field data
            ax03.plot(var_wod[n],depth[n],linewidth = 0.2, color = '#7dadbc')
            ax02.plot(var_wod[n],depth[n],linewidth = 0.5)

        for m in range(0,365,10):
            ax01.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                      linewidth = 0.2, color = 'red') #n - day
            ax03.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                      linewidth = 0.4, color = '#b62733',) #n - day

        ax03.plot(var_wod[0],depth[0],linewidth = 0.2, color = '#7dadbc',
                      alpha = 1, label= u"field")#, alpha= 0.5
        ax03.plot(var_brom[0][0:ny2max],depth_brom[0:ny2max],linewidth = 0.4,
                      color = '#b62733',label= u"modelled") #n - day
        legend = ax03.legend( shadow=False, loc='best') #bbox_to_anchor=(0.8, 0.35))
        frame = legend.get_frame()
        frame.set_facecolor('white')

        #pdf.savefig(fig)
        # When no figure is specified the current figure is saved

        #plt.show()
        pdf.savefig()
        plt.savefig('Baltic_validation_{}.png'.format(varname))
        plt.close()

        d = pdf.infodict()
        d['Title'] = 'Multipage PDF Example'
        d['Author'] = u'Elizaveta Protsenko\xe4nen'
        d['Subject'] = 'BROM model validation'
        #d['Keywords'] = 'PdfPages multipage keywords author title subject'
        #d['CreationDate'] = datetime.datetime(2009, 11, 13)
        d['ModDate'] = datetime.datetime.today()

def show_figure(var_wod,var_brom,varname):
    #print (depth2[0])
    figure = plt.figure(figsize = (10,6))
    gs = gridspec.GridSpec(2,2)
    gs.update(wspace=0.3,hspace = 0.4,left=0.04,
               right=0.99,bottom = 0.04, top = 0.9)
    ax00 = figure.add_subplot(gs[0]) # water
    ax01 = figure.add_subplot(gs[1]) # water
    ax02 = figure.add_subplot(gs[2]) # water
    ax03 = figure.add_subplot(gs[3])

    #len = ma.shape(o2)#(len(o2))
    lenght = (len(var_wod))

    #len_depth2 = len(depth2_brom)
    #def calculate_ybbl():
    for n in range(0,(len_depth2_brom-1)):
        if kz[1,n] == 0:
            y2max = depth2[n]
            ny2max = n
            break

    #ax00.set_title('Var from BROM all days')
    #plt.title('{}month{}_{}.txt'.format(boundary,month,name))
    ax00.set_title('{} from BROM all days'.format(varname))
    ax01.set_title('{} from BROM every 10 day'.format(varname))
    ax02.set_title('{} from WOD '.format(varname))
    ax03.set_title('BROM vs WOD ')
    ax00.set_ylim(100,0)
    ax01.set_ylim(100,0)
    ax02.set_ylim(100,0)
    ax03.set_ylim(100,0)

    for m in range(0,365,1):
        ax00.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                  linewidth = 0.2,color = 'red') #n - day

    #print(len(depth_roms))
    for n in range(0,lenght,1): #field data
        ax03.plot(var_wod[n],depth[n],linewidth = 0.2, color = '#7dadbc')
        ax01.plot(var_wod[n],depth[n],linewidth = 0.5)

    for m in range(0,365,10):
        ax01.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                  linewidth = 0.2, color = 'red') #n - day
        ax03.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                  linewidth = 0.4, color = '#b62733',) #n - day

    #legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    ax03.plot(var_wod[0],depth[0],linewidth = 0.2, color = '#7dadbc',
                  alpha = 1, label= u"field")#, alpha= 0.5
    ax03.plot(var_brom[0][0:ny2max],depth_brom[0:ny2max],linewidth = 0.4,
                  color = '#b62733',label= u"modelled") #n - day
    legend = ax03.legend( shadow=False,bbox_to_anchor=(0.8, 0.35))
    frame = legend.get_frame()
    frame.set_facecolor('white')
    plt.show()

def show_figure2(var_wod,var_brom, var_wod2,var_brom2,varname1,varname2):
    #print (depth2[0])
    figure = plt.figure(figsize = (6,4))
    gs = gridspec.GridSpec(1,2)
    gs.update(wspace=0.15,hspace = 0.1,left=0.1,
               right=0.99,bottom = 0.1, top = 0.9)
    ax00 = figure.add_subplot(gs[0]) # water
    #ax01 = figure.add_subplot(gs[1]) # water
    #ax02 = figure.add_subplot(gs[2]) # water
    ax03 = figure.add_subplot(gs[1])

    #len = ma.shape(o2)#(len(o2))
    lenght = (len(var_wod))

    #len_depth2 = len(depth2_brom)
    #def calculate_ybbl():
    for n in range(0,(len_depth2_brom-1)):
        if kz[1,n] == 0:
            y2max = depth2[n]
            ny2max = n
            break

    #ax00.set_title('Var from BROM all days')
    #plt.title('{}month{}_{}.txt'.format(boundary,month,name))
    '''ax00.set_title('{} from BROM all days'.format(varname))
    ax01.set_title('{} from BROM every 10 day'.format(varname))
    ax02.set_title('{} from WOD '.format(varname))
    ax03.set_title('BROM vs WOD ')'''
    ax00.set_ylim(90,0)
    ax00.set_ylabel('depth, m')

    ax03.set_ylim(90,0)
    ax00.axhspan(90,0,color='#dbf0fd',alpha = 0.7 )
    ax03.axhspan(90,0,color='#dbf0fd',alpha = 0.7 )
    ax00.set_title(varname1)
    ax03.set_title(varname2)
    for n in range(0,lenght,10): #field data
        ax00.plot(var_wod[n],depth[n],linewidth = 0.2,zorder = 1, color = '#78cccc' ) #
        ax03.plot(var_wod2[n],depth[n],linewidth = 0.5, color = '#78cccc')

    for m in range(0,365,10):
        ax00.plot(var_brom[m][0:ny2max],depth_brom[0:ny2max],
                  linewidth = 0.2, color = '#d75752',zorder = 10 )
        ax03.plot(var_brom2[m][0:ny2max],depth_brom[0:ny2max],
                  linewidth = 0.4, color = '#d75752') #n - day

    #legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
    ax03.plot(var_wod2[0],depth[0],linewidth = 0.2, color = '#78cccc',
                  alpha = 1, label= u"WOD") #, alpha= 0.5

    ax03.plot(var_brom2[0][0:ny2max],depth_brom[0:ny2max],linewidth = 0.4,
                color = '#d75752',label= u"BROM") #n - day
    ax03.legend(loc = 'best',facecolor= 'white')
    #ax00.plot(var_wod[0],depth[0],linewidth = 0.2, color = '#7dadbc',
    #              alpha = 1, label= u"field")#, alpha= 0.5
    #ax00.plot(var_brom[0][0:ny2max],depth_brom[0:ny2max],linewidth = 0.4,
    #              color = '#b62733',label= u"modelled") #n - day
    #legend = ax03.legend( shadow=False,bbox_to_anchor=(0.8, 0.35))
    #frame = legend.get_frame()
    #frame.set_facecolor('white')
    plt.show()

filenames = []
def files(varname):
    #varnames.append(varname)
    filenames.append('Baltic_validation_{}.pdf'.format(varname))

def write_pdf():

    figure_pdf(o2_2,o2_brom,'O2')
    files('O2')
    figure_pdf(sal,sal_brom,'Salinity')
    files('Salinity')
    figure_pdf(temp,temp_brom,'Temperature')
    files('Temperature')
    figure_pdf(pH_2,pH_brom,'pH') #Change the scale!!
    files('pH')
    figure_pdf(po4,po4_brom,'PO4')
    files('PO4')
    figure_pdf(si,si_brom,'Si')
    files('Si')
    figure_pdf(no3,no3_brom,'NO3')
    files('NO3')
    figure_pdf(alk_2,alk_brom,'Alk')
    files('Alk')

    merger = PdfFileMerger()
    for filename in filenames:
        merger.append(filename)
    ####    merger.append(PdfFileReader(file(filename, 'rb')))
    merger.write("merged_Baltic_validation_{}.pdf".format(nc_file_brom[:-3]))
    # [:-3] here we delete .nc in a name of output pdf file

#write_pdf()

#show_figure2(pH_2,pH_brom,'pH')
#show_figure2(si,si_brom,no3,no3_brom,r'$\rm Si\ \mu M/l $',r'$\rm NO_3\ \mu M/l $')
show_figure2(pH_2,pH_brom,alk_2,alk_brom, r'$\rm pH\ \mu M/l $',r'$\rm Alkalinity\ \mu M/l $')
#show_figure2(temp,temp_brom,sal,sal_brom, 'Temp', "Salinity")

def print_kz():
    figure = plt.figure(figsize = (10,6))
    gs = gridspec.GridSpec(1,1)
    gs.update(wspace=0.3,hspace = 0.4)
    ax00 = figure.add_subplot(gs[0]) # water
    ax00.set_ylim(100,0)
    for m in range(0,365,1):
        ax00.plot(kz[m], depth2_brom,
                  linewidth = 0.2,color = 'red')
    plt.show()

if __name__ == '__main__':
    pass


import palindromo

palabra = input("Ingrese una palabra para ver si es palindrome o no (bye para terminar): ")
si_palim = 0
no_palim = 0

while palabra != "bye":
    if palindromo.es_palindromo(palabra):
        si_palim += 1
        print(f"La palabra {palabra} es palindrome")
    else:
        no_palim += 1
        print(f"La palabra {palabra} no es palindrome")
    palabra = input("Ingrese una palabra para ver si es palindrome o no (bye para terminar): ")

print(f"La cantidad de palabras ingresadas es {si_palim + no_palim} siendo la cantidad de palabras palindromes {si_palim} y la de no palindromes {no_palim}")


class Solution:
    def maximumUniqueSubarray(self, nums: List[int]) -> int:  # 18.82% 10.72%
        d = {}
        score = 0
        result = 0
        left = 0
        for i, num in enumerate(nums):
            score += num
            while num in d:
                score -= nums[left]
                del d[nums[left]]
                left += 1
            result = max(result, score)
            d[num] = i
        return result

    def maximumUniqueSubarray_best_speed(self, nums: List[int]) -> int:
        q, rolling, rolling_sum = deque([]), set(), 0
        maximal = 0
        for num in nums:
            if num not in rolling:
                q.append(num)
                rolling.add(num)
                rolling_sum += num
            else:
                while q[0] != num:
                    popped = q.popleft()
                    rolling.discard(popped)
                    rolling_sum -= popped
                popped = q.popleft()
                q.append(num)
            if rolling_sum > maximal:
                maximal = rolling_sum
        return maximal

    def maximumUniqueSubarray_best_memory(self, nums: List[int]) -> int:
        i = 0
        j = 0
        res = 0
        sum = 0
        mySet = set()
        while i < len(nums):
            while nums[i] in mySet:
                sum = sum - nums[j]
                mySet.remove(nums[j])
                j += 1
            if nums[i] not in mySet:
                mySet.add(nums[i])
                sum += nums[i]
                res = max(res, sum)
                i += 1
        return res

1600 - 1699/1695 - Maximum Erasure Value/1695 - Maximum Erasure Value.py


from django.core import serializers
from django.http import Http404
from rest_framework import mixins
from rest_framework import status
from rest_framework import viewsets
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

from twitch_stats.models import TwitchProfile, TwitchTrackingProfile, TwitchStats
from twitch_stats.serializers import TwitchProfileSerializer, TwitchProfileRegisterSerializer, \
    TwitchAddTrackingSerializer, TwitchTrackingSerializer, TrackingSchedulerSerializer, TwitchStatsSerializer

from twitch_stats.permissions import IsOwnerOrReadOnly
from twitch_stats.settings import GOD_TOKEN

class TwitchProfileViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin,
                           mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    A simple ViewSet for viewing and editing twitch profiles.
    """
    queryset = TwitchProfile.objects.all()
    serializer_class = TwitchProfileSerializer
    permission_classes = [AllowAny, IsOwnerOrReadOnly]

    def create(self, request, **kwargs):
        serializer = TwitchProfileRegisterSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True) and request.user.is_authenticated():
            detail, is_created = TwitchProfile.objects.create_from_code(code=serializer.data['code'],
                                                                        user=request.user)
            if is_created:
                return Response({"detail": detail}, status=status.HTTP_201_CREATED)
            else:
                return Response({"detail": detail}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({"detail": "Not authorized."}, status=status.HTTP_401_UNAUTHORIZED)

    def get_object(self):
        try:
            identifier = self.kwargs['pk']
        except KeyError:
            raise Http404
        obj = TwitchProfile.objects.get_from_id_or_username_or_uuid(identifier=identifier)
        if obj:
            self.check_object_permissions(request=self.request, obj=obj)
            return obj
        else:
            raise Http404

    def get_queryset(self):
        if not self.request.user.is_anonymous and self.request.user.is_admin():
            return TwitchProfile.objects.all()
        elif not self.request.user.is_anonymous:
            try:
                return TwitchProfile.objects.filter(user=self.request.user)
            except TwitchProfile.DoesNotExist:
                return TwitchProfile.objects.none()
        else:
            return TwitchProfile.objects.none()

class TwitchTrackingProfileViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.DestroyModelMixin,
                                   mixins.CreateModelMixin, mixins.RetrieveModelMixin):
    queryset = TwitchTrackingProfile.objects.all()
    serializer_class = TwitchTrackingSerializer
    permission_classes = [AllowAny, IsOwnerOrReadOnly]

    def create(self, request, profile_pk=None, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        parent = self.get_parent()
        self.check_object_permissions(request=request, obj=parent)
        if serializer.is_valid(raise_exception=True):
            obj = TwitchTrackingProfile.objects.get_or_create(t_id=serializer.validated_data['twitch_id'])
            if obj:
                parent.tracking_users.add(obj)
                parent.save()
                return Response({'detail': 'Successfully added user to tracking list.'}, status=status.HTTP_200_OK)
            else:
                return Response({'detail': 'Error in verifying twitch user.'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'detail': 'Something went wrong.'}, status=status.HTTP_400_BAD_REQUEST)

    def destroy(self, request, *args, **kwargs):
        parent = self.get_parent()
        self.check_object_permissions(request=request, obj=parent)
        obj = self.get_object()
        parent.tracking_users.remove(obj)
        if TwitchTrackingProfile.objects.can_delete(obj=obj):
            obj.delete()
            return Response({'detail': 'Removed from tracking and deleted.'}, status=status.HTTP_200_OK)
        else:
            return Response({'detail': 'Removed from tracking.'}, status=status.HTTP_200_OK)

    def get_object(self):
        try:
            identifier = self.kwargs['pk']
        except KeyError:
            raise Http404
        parent = self.get_parent()
        obj = TwitchTrackingProfile.objects.get_from_id_or_name_with_user(identifier=identifier, user=parent)
        if obj:
            self.check_object_permissions(request=self.request, obj=parent)
            return obj
        else:
            raise Http404

    def get_parent(self):
        try:
            identifier = self.kwargs['profiles_pk']
        except KeyError:
            raise Http404
        obj = TwitchProfile.objects.get_from_id_or_username_or_uuid(identifier=identifier)
        if obj:
            return obj
        else:
            raise Http404

    def get_queryset(self):
        obj = self.get_parent()
        if obj:
            return obj.tracking_users.all()
        else:
            return TwitchTrackingProfile.objects.none()

class TwitchStatsViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
    queryset = TwitchTrackingProfile.objects.all()
    serializer_class = TwitchStatsSerializer
    permission_classes = [AllowAny]

    def get_queryset(self):
        return TwitchStats.objects.filter(channel_id=self.kwargs['pk'])

class TrackingView(APIView):
    """
    View for starting and stopping scheduled task. (temporary solution)
    """
    throttle_classes = ()
    permission_classes = (AllowAny,)
    serializer_class = TrackingSchedulerSerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        if serializer.validated_data['token'] != GOD_TOKEN:
            return Response({'detail': 'Unauthorized.'}, status=status.HTTP_401_UNAUTHORIZED)

        if serializer.validated_data['command'] == 'start':
            code = TwitchStats.objects.start_collecting(interval=serializer.validated_data['interval'])
            if code:
                return Response({'detail': 'Started collecting.'}, status=status.HTTP_200_OK)
            else:
                return Response({'detail': 'Task already running'}, status=status.HTTP_400_BAD_REQUEST)
        elif serializer.validated_data['command'] == 'stop':
            code = TwitchStats.objects.stop_collecting()
            if code:
                return Response({'detail': 'Stopped collecting.'}, status=status.HTTP_200_OK)
            else:
                return Response({'detail': 'No tasks are running.'}, status=status.HTTP_404_NOT_FOUND)
        elif serializer.validated_data['command'] == 'update':
            code = TwitchStats.objects.update_collecting(interval=serializer.validated_data['interval'])
            if code:
                return Response({'detail': 'Task updated.'}, status=status.HTTP_200_OK)
            else:
                return Response({'detail': 'Task not updated'}, status=status.HTTP_400_BAD_REQUEST)
        elif serializer.validated_data['command'] == 'info':
            result = TwitchStats.objects.info_collecting()
            if result:
                return Response(serializers.serialize('json', [result]), status=status.HTTP_200_OK)
            else:
                return Response({'detail': 'Task not running.'}, status=status.HTTP_404_NOT_FOUND)
        else:
            return Response({'detail': 'Invalid command.'}, status=status.HTTP_400_BAD_REQUEST)


# text = "hello zhang liang fuck scy"
# print(len(text))

def sum(*args)->float:
    rv = 0
    for i in args:
        rv += i
    return rv

numbers = (1, 2, 3)
print(sum(*numbers))


"""
Defines a screen for the game
"""

from abc import ABC, abstractmethod
import pygame

from src import settings

class Screen(ABC):
    """
    A screen should hold state for the game during this game loop
    It is also responsible for rendering the relevant images and data to the pygame window
    """

    finished: bool = False

    def game_loop(self, surface: pygame.Surface) -> int:
        """
        Main game loop for every screen
        """
        clock = pygame.time.Clock()
        while not self.finished:
            clock.tick(settings.FPS)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    # return an intention to quit the game entirely
                    return pygame.QUIT

            self.render(surface)
            pygame.display.update()

    @abstractmethod
    def render(self, surface: pygame.Surface):
        """
        Render to the pygame window
        """


from flask import Flask, render_template, request, redirect, url_for, flash
from flask_mail import Mail, Message
import smtplib

app = Flask(__name__)

# Настройки Flask-Mail
app.config['MAIL_SERVER'] = 'smtp.gmail.com'  # Замените на адрес SMTP-сервера
app.config['MAIL_PORT'] = 587  # Порт SMTP
app.config['MAIL_USE_TLS'] = True  # Использовать TLS (True/False)
app.config['MAIL_USE_SSL'] = False  # Использовать SSL (True/False)
app.config['MAIL_USERNAME'] = 'sulaimanovuran@gmail.com'  # Ваше имя пользователя
app.config['MAIL_PASSWORD'] = 'cbpcsgueufapmjph'  # Ваш пароль
app.config['MAIL_DEFAULT_SENDER'] = ('Заявка на получение услуг', 'sulaimanovuran@gmail.com')  # Замените на ваши данные
app.config['SECRET_KEY'] = 'kjdahfjehfuiwejhf83479ur0384943-7582930yr9hwepi'

mail = Mail(app)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/services')
def services():
    return render_template('services.html')

@app.route('/bid')
def bid():
    return render_template('bid.html')

@app.route('/send_email', methods=['POST', 'GET'])
def send_email():
    print("hello")
    company_name = request.form['name']
    email = request.form['mail']

    phone_number = request.form['phone']
    message = Message(subject=f'Заявка на получение услуг от {company_name}', recipients=['redline.marketing.kg@gmail.com'])
    message.body = f'Адрес электронной почты {email}.\nНомер телефона: {phone_number}'

    try:
        mail.send(message)  # Отправляем письмо
        flash('Заявка отправлена', category='success')
    except Exception as e:
        flash('Ошибка отправки сообщения', category='error')
    return render_template('bid.html')

if __name__ == '__main__':
    app.run(debug=True)


import speech_recognition as sr
import time

def tratar_audio(rec, audio):
    global acabou
    # tratar o meu audio
    try:
        texto = rec.recognize_google(audio, language="en-US")
        if 'encerrar gravação' in texto:
            print(texto[:-17])
        else:
            print(texto)
        arquivo = open("gravacao_longa.txt", "a")
        arquivo = open("gravacao_longa.txt", "w")
        if 'encerrar gravação' in texto:
            posicao = texto.find('encerrar gravação')
            texto = texto[:posicao]
        else:
            pass
        if "encerrar gravação" in texto:
            acabou = True
        arquivo.write(texto)
        arquivo.close()
        acabou = True
    except:
        print("Não entendi o que você falou")

acabou = False

rec = sr.Recognizer()

with sr.Microphone(device_index=1) as microfone:
    rec.adjust_for_ambient_noise(microfone)
    rec.pause_threshold = 0.8
    # rec.dynamic_energy_adjustment_ratio = 4
    print("Pode começar a falar: \n(para encerrar diga: '\033[31mENCERRAR GRAVAÇÃO\033[m')")

# thread 1
parar_ouvir = rec.listen_in_background(microfone, tratar_audio)

# thread 2
while True:
    time.sleep(0.1)
    if acabou == True:  # vou falar pra ele encerrar a gravação
        break

# thread 1
parar_ouvir(wait_for_stop=False)


from django.conf import settings
from django.db.models import Sum as DbSum
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from api_test.authentication import ajax_login_required
from api_test.ratelimit import request_ratelimit, bad_request_ratelimit, check_bad_requests

from .models import Set

@csrf_exempt
@request_ratelimit()
@bad_request_ratelimit()
def get_sum(request):
    try:
        num_a = int(request.GET.get('a'))
        num_b = int(request.GET.get('b'))
    except ValueError:
        check_bad_requests(request, settings.BAD_REQUEST_RATE_LIMIT, 'Wrong Parameters')
        return JsonResponse("a and b should be provided as Integer values.", status=400, safe=False)
    except TypeError:
        check_bad_requests(request, settings.BAD_REQUEST_RATE_LIMIT, 'Wrong Parameters')
        return JsonResponse("a and b numbers should be provided.", status=400, safe=False)

    created_set = Set.objects.create(num_a=num_a, num_b=num_b, sum=num_a + num_b)
    return JsonResponse({'result': created_set.sum})

@csrf_exempt
@ajax_login_required
@request_ratelimit()
@bad_request_ratelimit()
def get_history(request):

    sets = Set.objects.all()
    return JsonResponse([set_item.to_dict() for set_item in sets], safe=False)

@csrf_exempt
@ajax_login_required
@request_ratelimit()
@bad_request_ratelimit()
def get_total(request):

    total = Set.objects.aggregate(DbSum('sum'))
    return JsonResponse({'total': total['sum__sum']})


"""
Dans_Diffraction Examples
Load space groups and look at the information contained.
"""

import sys,os
import numpy as np
import matplotlib.pyplot as plt # Plotting

cf = os.path.dirname(__file__)
sys.path.insert(0,os.path.join(cf, '..'))
import Dans_Diffraction as dif

f = '../Dans_Diffraction/Structures/LaMnO3.mcif'
f = "../Dans_Diffraction/Structures/Sr3LiRuO6_C2'c'.mcif"
cif = dif.readcif(f)

ops = cif['_space_group_symop_magn_operation.xyz']
cen = cif['_space_group_symop_magn_centering.xyz']

print('Symmetry Operations (%d):' % len(ops))
print(ops)
print('Centring Operations (%d):' % len(cen))
print(cen)

# Combine operations with centring
allops = dif.fc.gen_symcen_ops(ops, cen)

# Convert to magnetic symmetry
magops = dif.fc.symmetry_ops2magnetic(allops)

print('\n%35s (%d) | %-40s' % ('Symmetry Operations', len(allops), 'Magnetic operations'))
for n in range(len(allops)):
    print('%40s | %-40s' % (allops[n], magops[n]))

sym, mag, tim = dif.fc.cif_symmetry(cif)
print('\ncif_symmetry')
for n in range(len(sym)):
    print('%40s | %+d | %-40s' % (sym[n], tim[n], mag[n]))


'''
New solution
'''

def longestsubstring(self,A):
    used = {}
    start = maxlength = 0

    for index,char in enumerate(A):
        if char in used and start<=used[char]:
            start = used[char]+1
        else:
            maxlength = max(maxlength,index-start+1)
        used[char] = index

    return maxlength

'''
old solution
'''

def lengthOfLongestSubstring(self, s):
        lastIndex = [-1]*256
        n = len(s)
        res = 0
        i = 0

        for j in range(0,n):
            i = max(i, lastIndex[ord(s[j])] +1)
            res = max(res,j-i+1)

            lastIndex[ord(s[j])] = j

        return res

'''
time complexity is O(n+d) i.e linear time complexity
sliding window approach has been used in this solution
'''


from common import oled_page, url, mark
import machine

def start():
    mark("sensors")
    # Convert a 16-bit number to 0 - 3.3 (Pico runs at 3.3volt)
    CONVERSION_FACTOR = 3.3 / 65535

    # Define the ADC pin number for the thermistor
    temperature_sensor = machine.ADC(4)

    # read voltage from temp sensor and convert into volts (0 - 3.3V)
    reading = temperature_sensor.read_u16() * CONVERSION_FACTOR

    # convert that to the actual temperature in Celsius:
    # 0.706V is 27 degrees C, with a slope of -1.721mV per degree.
    temperature = 27 - (reading - 0.706) / 0.001721

    oled_page("Sensors", "{temperature}C".format(temperature=temperature))
    print("""
Want to know a fun fact?

It's about {temperature} degrees Celsius where you are.

I can tell the approximate temperature from a sensor built in to me. In fact,
reading sensors is something I'm awesome at.

You can learn more at:

    {url}

When you'd like to move on:

    >>> import music
    >>> music.start()
""".format(url=url("sensors"), temperature=temperature))


#!/usr/bin/env python3
import os, sys, json, socket, time

ghost = "localhost"
gport = 2003
tz = 'Europe/Amsterdam'

def application(environ, start_response):
    global ghost, gport, tz

    status = '200 OK'
    output = 'Thanks'

    os.environ['TZ'] = tz
    time.tzset()

    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', '0'))
    except ValueError:
        request_body_size = 0
    if request_body_size != 0:
        request_body= environ['wsgi.input'].read(request_body_size)
        data = json.loads(request_body)

        lines = []
        for d in data:
            gtime = int(d['time'])
            host = d['host'].replace('.','_')

            if d['plugin_instance']:
                pluginstring = d['plugin'] + "." + d['plugin_instance']
            else:
                pluginstring = d['plugin']
            if d['type_instance']:
                if d['type'] == d['plugin']:
                    typestring = d['type_instance']
                else:
                    typestring = d['type'] + "-" + d['type_instance']
            else:
                typestring = d['type']
            superstring = graphiteFriendly(pluginstring + "." + typestring)

            for i, value in enumerate(d['values']):
                metric = "collectd." + host + "." + superstring
                if len(d['values']) > 1:
                    metric = metric + "-" + d['dsnames'][i]
                line = "{0} {1} {2}".format(metric, value, gtime)
                lines.append(line)

        if len(lines) > 0:
            lines.append('')

            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.connect((ghost, gport))
                connected = True
            except:
                connected = False
                status = '503 Service Unavailable'
                output = 'Failed: no connection to carbon'

            if connected:
                try:
                    sock.sendall(str('\n').join(lines).encode('utf-8'))
                except socket.error as e:
                    status = '503 Service Unavailable'
                    connected = False
                    if isinstance(e.args, tuple):
                        output = 'Failed: socket error %d' % e[0]
                    else:
                        output = 'Failed: socket error'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output.encode('utf-8')]

def graphiteFriendly(s):
    t = dict((ord(char), '_') for char in ' ,')
    t.update(dict((ord(char), None) for char in '+()"'))
    return s.translate(t)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    srv = make_server('localhost', 9292, application)
    srv.serve_forever()


import ordinaryBackup
import supervisorTest
import computer

wincount = 0
games = 20
result = []

for i in range(games):
    win = supervisorTest.supervisor(
        "ordinaryBackup", "improvedBackup1", 0.5, False)
    print(win)
    if win == "p2":
        wincount += 1
    result.append(win == "p2")

print("ordinaryBackup won " + str(wincount) +
      " times" + " out of " + str(games) + " games")
print("ordinaryBackup won " + str(wincount/games*100) + "% of the time")
print(result)


from __future__ import annotations

import numpy as np

from keras.layers import (
    Dense,
    Dropout,
    Reshape,
    Flatten,
    InputLayer,
    Conv1D,
    GlobalMaxPooling1D,
)
from keras.losses import KLDivergence
from keras.models import Sequential, load_model
from keras.models import Model
from keras import metrics
import tensorflow.keras.optimizers as optimizers
import tensorflow as tf
from tensorflow.python.keras.backend import (
    binary_crossentropy,
    conv1d,
    categorical_crossentropy,
)
from tensorflow.python.keras.layers.core import Activation
from tensorflow.python.keras.layers.pooling import MaxPool1D
from tensorflow.python.keras.losses import BinaryCrossentropy

from tcn import TCN

# "learning_rate": 0.001,  # Learning rate the neural net
# activation functions: linear, sigmoid, tanh, or relu, need to be at least same lenght as hidden layers.
# "anet_optimizer": "Adam",  # Adam, SGD, Adagrad, RMSprop

class CNN:
    def __init__(self) -> None:
        return None

    def initialize(self, parameters, input_length):
        if parameters["starting_cnn"] != "":
            self.load_model(parameters["starting_cnn"])
            return self

        self.model = Sequential()

        self.model.add(
            InputLayer(input_shape=(parameters["training_length"] * 24, input_length))
        )  # need to add input shape here

        # adding the TCN layer here
        if parameters["model_used"] == "TCN":
            self.model.add(
                TCN(
                nb_filters=parameters["TCN_nb_filters"],
                kernel_size=parameters["TCN_kernel_size"],
                nb_stacks=parameters["TCN_nb_stacks"],
                dilations=parameters["TCN_dilations"],
                padding=parameters["TCN_padding"],
                dropout_rate=parameters["TCN_dropout_rate"],
                activation=parameters["TCN_activiation"],
                )
            )
        else: # DNN
            self.model.add(Flatten())

        if len(parameters["hidden_layers"]) < len(parameters["activation_functions"]):
            print("NEED TO HAVE ACTIVATION FUNCTIONS EQUAL TO NUMBER OF HIDDEN LAYERS DUMBASS!")

        # adding dense layers
        for index, layer in enumerate(parameters["hidden_layers"]):
            self.model.add(
                Dense(layer, activation=parameters["activation_functions"][index])
            )

        # Will need to map to 24 * prediction_horizon floats in last layer
        self.model.add(Dense(24 * parameters["prediction_horizon"], activation=parameters["last_layer_activation"]))

        selected_optimizer = getattr(optimizers, parameters["optimizer"])(
            learning_rate=parameters["learning_rate"]
        )

        self.model.compile(
            loss=parameters["loss"],
            optimizer=selected_optimizer,
            metrics=parameters["metrics"],
        )

        self.model.summary()

        return self

    def predict(self, input):
        return self.model.predict(input)

    def fit(
        self, features, targets, batch_size, epochs, validation_split, shuffle, verbose
    ):

        ret = self.model.fit(
            x=features,
            y=targets,
            batch_size=batch_size,
            epochs=epochs,
            validation_split=validation_split,
            shuffle=shuffle,
            verbose=verbose,
        )

        # loss = ret.history.get("loss", [None])
        # mae = ret.history.get("MAE", [None])

        return ret

    def save_model(self, path):
        self.model.save(path)

    #def load_model(self, path):
    #    self.model = load_model(path)

# history = self.model.fit(x=features, y=targets, batch_size = how many to fit at a time, epochs = 5, validation_split = 0.1,shuffle = True) # how to train
# self.model( [input] ) -> output


import numpy as np
import torch
from model import PNet
from model import VNet
import copy
import random
import time
import transforms as ts
from R18 import R18

def Q_a_P(q_vec):
    res = np.zeros(52)
    max_pos = 0
    max_Q = -10000000
    return res

def print_Q(player, q_vec):
    print(player, 'Q: [', end='')
    for i in range(52):
        if q_vec[i]>-1000:
            print(pos_to_card(i), '%.3g'%q_vec[i],' ', end='')
    print(']')
def print_P(player, p_vec):
    print(player, 'P: [', end='')
    for i in range(52):
        if p_vec[i]> 0.0001:
            print(pos_to_card(i), '%.3g'%p_vec[i],' ', end='')
    print(']')

class Node:
    def __init__(self):
        self.father = None
        # record the history before playing in this node
        self.history = None
        self.position = None
        self.trun_number = 0
        # private information needed for selecting actions
        self.initial_cards = None
        self.sons = []
        self.V = 0
        self.Q = np.zeros(52)-1000000
        self.N = 0
        self.last_in_the_tree = False

        self.expert_recommendation = None
        # self.legal_actions = None
        self.action_probability = None

    def ajouter_fil(self, son):
        self.sons.append(son)

    def inscrire_histoire(self, histoire):
        self.history = histoire

    def compter_V(self, histoire, position, initial_cards, robot):
        input_vec = a_standard_input(histoire, position, initial_cards)
        out = robot(input_vec)[0][52]
        return input_vec, out

    def chercher_ce_fil(self, son):
        if len(self.sons) == 0:
            return None
        for i in self.sons:
            #print("i history:", i.history, "son history:", son.history)
            if i.history == son.history:
                #print(i.history)
                return i
        return None

    def __del__(self):
        for i in range(len(self.sons)):
            j = self.sons.pop()
            del j

    def delete_sub_tree(self):
        for i in range(len(self.sons)):
            j = self.sons.pop()
            del j

class MCTS:
    def __init__(self):
        self.name = "tree_searcher"
        self.searching_stack = []
        self.history = []
        self.dependence_on_tree_search = 0.5
        self.epsilon = 0.1
        self.epsilon1 = 0.05
        self.who_wins_each_turn = []
        self.cards_played = [[], [], [], []]
        self.cards_played_original = [[], [], [], []]
        self.who_wins_each_turn_original = []
        # self.empty_color = np.zeros((4, 4))
        self.m = 20
        self.number_of_posterior_samples = 18 #10
        self.number_of_tree_search = 30
        self.tau = 0.5
        self.weight_vec = np.array([0.25, -0.25, 0.25, -0.25])

        self.simplified_robot = R18()
        self.imaginary_robot_list = None

        #self.robot1 = misss(pnet) #IfPlayer()
    def print_history(self, his):
        n = len(his) // 8
        for i in range(n):
            print(i, "th round:", his[i * 8], ":", pos_to_card(his[i * 8 + 1]),
                  his[i * 8 + 2], ":", pos_to_card(his[i * 8 + 3]),
                  his[i * 8 + 4], ":", pos_to_card(his[i * 8 + 5]),
                  his[i * 8 + 6], ":", pos_to_card(his[i * 8 + 7]))
        if n <= 0:
            n = 0
        print(n, "th round:")
        for i in range(8 * n, len(his), 2):
            if i + 1 < len(his):
                print(his[i], ":", pos_to_card(his[i + 1]))

    def whats_next_position(self, this_play_order, this_cards, card):
        if len(this_cards) + 1 < 4:
            return this_play_order[len(this_cards) + 1]
        else:
            all_cards = copy.deepcopy(this_cards)
            all_cards.append(pos_to_card(card))
            #print("lac:", all_cards)
            winner = self.judge_winner(all_cards)
            return winner

    def etendre_et_estimer_Q_pour_la_premier_fois(self, node, history_i, all_inic, position, this_play_order,
                                                  this_cards, prophet, color):
        history = copy.deepcopy(history_i)
        played_vec = np.zeros(52)
        for i in range(0, len(history), 2):
            if history[i] == position:
                played_vec[history[i + 1]] = 1
        legal_choices = trouver_les_choix_feasibles(all_inic[position], played_vec, color)
        pos_lst = np.where(legal_choices == 1)[0]
        history.append(position)
        if len(pos_lst) ==0:
            print("len",len(pos_lst),"ctt", pos_lst)
            print("no more available")
            print("legal choices are:", legal_choices)
            print("initial cards in position ", position, "is:", all_inic[position])
            print("what has been played: ", played_vec)
            self.print_history(history)
        for pos in pos_lst:
            history.append(pos)
            #print("tc", this_cards)
            next_pos = self.whats_next_position(this_play_order, this_cards, pos)
            new_son = Node()
            new_son.position = next_pos
            in_v, new_son.V = new_son.compter_V(history, next_pos, all_inic[next_pos], prophet)
            if node.position % 2==new_son.position %2:
                node.Q[pos] = new_son.V
            else:
                node.Q[pos] = -new_son.V

            new_son.history = copy.deepcopy(history)
            new_son.father = node
            if len(history_i) + 2 >= 104:
                new_son.last_in_the_tree = True
            node.ajouter_fil(new_son)
            history.pop()

    def baysian_inference(self, my_initial_cards, my_position, one_sample, certain_history, device):
        # one sample is arranged in relative history
        log_p = 0
        initial_cards = [[], [], [], []]
        initial_cards[my_position] = my_initial_cards
        for i in range(1, 4):
            initial_cards[(my_position + i) % 4] = one_sample[(i - 1 + 4) % 4] + self.cards_played[
                (my_position + i) % 4]
            if len(initial_cards[(my_position + i) % 4] )!=13:
                print("hidden cards:", one_sample[(i - 1 + 4) % 4])
                print("relative position:", i)
                print("played cards:", self.cards_played[
                (my_position + i) % 4])
                raise Exception("error in prior sampling: card number don't add up to 13")

        for i in range(0, len(certain_history), 2):
            the_player = certain_history[i]
            sub_history = certain_history[0:i]
            std_state_input = ts.a_standard_input(sub_history, certain_history[i], initial_cards[the_player])
            if i % 8 > 0:
                card_pos = certain_history[(i // 8) * 8 + 1]
                color = ts.pos_to_color(card_pos)#DECODING_DICT1[card_pos // 13]

            else:
                color = 'A'

            device1 = torch.device('cuda')
            #TO DO: improve here
            #net_out = robot.play_one_card(std_state_input, initial_cards[the_player],
            #                              self.cards_played[the_player][0:(i // 8)], color, device1)

            #print('net out:', net_out)
            #log_p += np.log(0.00001 + net_out[certain_history[i + 1]])
            log_p +=1
        return log_p, initial_cards

    def compter_likelihood(self, my_initial_cards, my_position, sample_pool, certain_history, device):
        res = []
        initial_pool = []
        for i in range(len(sample_pool)):
            res_i, initial_i = self.baysian_inference(my_initial_cards, my_position, sample_pool[i],
                                                      certain_history, device)
            res.append(res_i)
            initial_pool.append(initial_i)
        return res, initial_pool

    def chercher_et_choisir(self, info):
        '''
        info contains
        "absolute_history"
        "my_initial_cards"
        "my_position"
        "cards_played_in_absolute_order"
        "cards_played_in_this_term"
        "play_order_in_this_turn"
        "who_already_won_each_turn"
        "color_of_this_turn"
        "device"
        '''
        history_real = copy.deepcopy(info["absolute_history"])
        ini_card = copy.deepcopy(info["my_initial_cards"])
        my_position = info["my_position"]
        cards_already_played = copy.deepcopy(info["cards_played_in_absolute_order"])
        this_turn_till_me= copy.deepcopy(info["cards_played_in_this_term"])
        first_play_order = copy.deepcopy(info["play_order_in_this_turn"])
        who_wins_each_turn = copy.deepcopy(info["who_already_won_each_turn"])
        couleur = info["color_of_this_turn"]
        device = info["device"]

        root_node = Node()
        root_node.history = copy.deepcopy(history_real)
        root_node.initial_cards = copy.deepcopy(ini_card)
        root_node.position = copy.deepcopy(my_position)

        self.history = copy.deepcopy(history_real)
        self.cards_played = copy.deepcopy(cards_already_played)
        self.cards_played_original = copy.deepcopy(cards_already_played)
        self.who_wins_each_turn_original = copy.deepcopy(who_wins_each_turn)
        self.who_wins_each_turn = copy.deepcopy(who_wins_each_turn)

        legal_choices = ts.trouver_les_choix_feasibles(ini_card,cards_already_played[my_position],
                                                         couleur)
        all_cards = ['S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9', 'S10', 'SJ', 'SQ', 'SK', 'SA',
                     'H2', 'H3', 'H4', 'H5', 'H6', 'H7', 'H8', 'H9', 'H10', 'HJ', 'HQ', 'HK', 'HA',
                     'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'D10', 'DJ', 'DQ', 'DK', 'DA',
                     'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'C8', 'C9', 'C10', 'CJ', 'CQ', 'CK', 'CA']
        time_begin = time.time()
        for i in ini_card:
            all_cards.remove(i)
        for i in range(0, len(self.history), 2):
            if self.history[i] != root_node.position:
                pos = self.history[i + 1]
                all_cards.remove(ts.pos_to_card(pos))

        # find out if some player lacks certain color from history
        empty_couleur = np.zeros((4, 4), dtype=int)
        L = len(self.history) // 8
        if len(self.history) % 8 == 0:
            L -= 1
        for i in range(L):
            color = self.history[i * 8 + 1] // 13
            for j in range(1, 4):
                if i * 8 + 1 + 2 + j < len(self.history):
                    the_color = self.history[i * 8 + 1 + 2 * j] // 13
                    if the_color != color:
                        empty_couleur[(self.history[i * 8 + 2 * j] - my_position + 4) % 4][color] = 1

        # calculate number of cards in each player's hand
        turns_left = np.zeros(4)
        for i in range(4):
            turns_left[i] = 13 - len(self.history) // 8
        the_number = len(self.history) // 8
        for i in range(0, len(self.history) % 8, 2):
            turns_left[(self.history[the_number * 8 + i] - my_position + 4) % 4] -= 1

        # prior uniform sampling
        sample_pool = ts.group_de_echantillon(self.m, empty_couleur, all_cards, turns_left)

        # baysien calculation
        try:
            log_likelihood, initial_pool = self.compter_likelihood( root_node.initial_cards, my_position, sample_pool,
                                                               self.history, device)
        except:
            print("error in baysien calculation")
            print("turns left", turns_left)
            raise("Error in prior sampling")

        # initial pool is in absolute order
        # find the largest
        nops = self.number_of_posterior_samples
        if nops > len(log_likelihood):
            nops = len(log_likelihood)
        mle_pos = np.array(log_likelihood).argsort()[-nops:]

        maxed_probs = np.zeros(len(mle_pos))
        v = np.zeros((len(mle_pos), 52))

        # calculate each possible private information set
        for i in range(len(mle_pos)):
            # under each private information, conduct m Monte Carlo tree searches
            #print("projection {} in {}".format(i, len(mle_pos)))
            #print(initial_pool[mle_pos[i]])
            v_vec_i =self.naive_cherche(root_node, initial_pool[mle_pos[i]], this_turn_till_me, first_play_order,
                                       device)

            v[i] = v_vec_i
            maxed_probs[i] = np.exp(log_likelihood[mle_pos[i]])

        # average max approximation: average the best policy under different private information
        final_v = np.zeros(52)
        maxed_probs = maxed_probs / maxed_probs.sum()

        for i in range(len(mle_pos)):
            #final_v = final_v +  v[i]/(len(mle_pos))
            final_v = final_v + v[i]*maxed_probs[i]

        maxpos=0
        max_V=-100000000

        for i in range(52):
            if final_v[i]>max_V:
                maxpos = i
                max_V = final_v[i]
        if legal_choices.sum()>1:
            final_target = legal_choices*self.epsilon/(legal_choices.sum()-1)
            final_target[maxpos] = 1-self.epsilon
        else:
            final_target = np.zeros(52)
            final_target[maxpos] = 1
        time_end  = time.time()
        #print('ft', final_target, legal_choices.sum())
        if final_target.sum()>1.01:
            print(final_v)
            print(final_target.sum())
            print(final_target)
            raise Exception('Error: target policy problem')
        sample_output = np.random.multinomial(1, final_target, size=1)
        #print("After running",len(mle_pos),
        #      "projections, robot", my_position, "made a choice: ", ts.vec_to_card(sample_output[0]),'final v is:',final_v[np.where(sample_output[0] == 1)[0][0]],
        #      "Ça coûte", time_end-time_begin, "seconds")

        #print('v is:', v[0][np.where(sample_output[0] == 1)[0][0]])
        #print('final v',final_v)
        #print('which one:', np.where(sample_output[0] == 1)[0][0])
        res = {"target_policy": final_target,
        "input_vec": ts.a_standard_input(root_node.history, my_position, ini_card),
        "v_input_vec": ts.a_standard_input_v(root_node.history, my_position, ini_card),
        "legal_choice_vec": legal_choices,
        "value": final_v[np.where(sample_output[0] == 1)[0][0]],
        "card_played":ts.vec_to_card(sample_output[0])
               }
        return res
        #return vec_to_card(sample_output[0]), a_standard_input(root_node.history, my_position, ini_card), \
        #       final_target, legal_choices, a_standard_input_v(root_node.history, my_position, ini_card), final_v[np.where(sample_output[0] == 1)[0][0]]

    def naive_cherche(self, root_node, hidden_information, this_turn_till_me, first_play_order,
                         device):
        #print("searching started")
        # search for 2 rounds, and returns the final Q's
        self.searching_stack.append(root_node)
        self.play_order = copy.deepcopy(first_play_order)
        root_pos = root_node.position

        color_of_this_turn = 'A'
        if len(this_turn_till_me) > 0:
            color_of_this_turn = this_turn_till_me[0][0]
        card_played_in_this = copy.deepcopy(this_turn_till_me)

        history = copy.deepcopy(root_node.history)
        played_vec = np.zeros(52)
        for i in range(0, len(history), 2):
            if history[i] == root_pos:
                played_vec[history[i + 1]] = 1
        legal_choices = ts.trouver_les_choix_feasibles(hidden_information[root_pos], played_vec, color_of_this_turn)

        pos_lst = np.where(legal_choices == 1)[0]

        v_vec = np.zeros(52)-1000000
        for i in range(len(pos_lst)):
            self.cards_played = copy.deepcopy(self.cards_played_original)
            history = copy.deepcopy(root_node.history)
            card_played_in_this = copy.deepcopy(this_turn_till_me)

            #print("searching for choice {}".format(i))
            card_played_in_this.append(ts.pos_to_card(pos_lst[i]))
            history.append(root_pos)
            history.append(pos_lst[i])
            lth = len(card_played_in_this)
            if lth > 0:
                color_of_this_turn = card_played_in_this[0][0]
            #print("first round search started")
            for j in range(lth,4):
                #print("Player {} is going to play".format(j))
                #print(history)
                info = {"absolute_history": history,
                        "my_initial_cards": hidden_information[self.play_order[j]],
                        "my_position": self.play_order[j],
                        "cards_played_in_absolute_order": self.cards_played_original,
                        "cards_played_in_this_term": card_played_in_this,
                        "play_order_in_this_turn": self.play_order,
                        "who_already_won_each_turn": "rien",
                        "color_of_this_turn": color_of_this_turn,
                        "device": device}
                #card_from_if, _ = self.robot1.play_one_card([[], this_turn_till_me], self.play_order[j], history, hidden_information[self.play_order[j]],
                #                              self.cards_played_original[self.play_order[j]], color_of_this_turn, True)
                result = self.imaginary_robot_list[self.play_order[j]].play_one_card(info)
                #print("Player {} finished her play".format(j))
                card_from_if = result["card_played"]
                card_played_in_this.append(card_from_if)
                self.cards_played[self.play_order[j]].append(card_from_if)

                history.append(self.play_order[j])
                history.append(ts.card_to_vecpos(card_from_if))
            #print("first round search ended")
            sc = ts.calc_partial_score(history)-ts.calc_partial_score(history[0:(len(history)-8)])
            r_t = sc[root_pos]

            winner_order = ts.judge_winner(card_played_in_this)
            winner = self.play_order[winner_order]
            next_play_order = [winner, (winner+1)%4, (winner+2)%4,(winner+3)%4]
            #input_vec = a_standard_input_v(history, self.play_order[winner], hidden_information[self.play_order[winner]])
            len_his_ori = len(history)
            color_of_this_turn = 'A'
            #print("intermediate calculation finished")
            if len_his_ori<=48*2:
                #print("second round search started")
                value_vec = np.zeros(4)
                for next_rounds in range(4):
                    #value_vec[next_rounds] = prophet.vnet(input_vec)
                    info = {"absolute_history": history,
                            "my_initial_cards": hidden_information[next_play_order[next_rounds]],
                            "my_position": next_play_order[next_rounds],
                            "cards_played_in_absolute_order": self.cards_played,
                            "cards_played_in_this_term": card_played_in_this,
                            "play_order_in_this_turn": next_play_order,
                            "who_already_won_each_turn": "rien",
                            "color_of_this_turn": color_of_this_turn,
                            "device": device}
                    returned = self.simplified_robot.play_one_card(info)
                    card_from_if = returned["card_played"]
                    value_vec[next_rounds] = returned["value"]

                    if next_rounds == 0:
                        color_of_this_turn = card_from_if[0]
                    card_played_in_this.append(card_from_if)
                    history.append(self.play_order[next_rounds])
                    history.append(ts.card_to_vecpos(card_from_if))
                    #input_vec = ts.a_standard_input_v(history, next_play_order[next_rounds], hidden_information[next_play_order[next_rounds]])
                v_tp1 = sum(value_vec*self.weight_vec)
            else:
                v_tp1 = 0#self.robot1.pret(input_vec)[52]
            #print("second round search ended")
            if len_his_ori == 52*2:
                v_tp1 = 0

            #if i%10 ==0:
            #    print('rt=',r_t)
            if self.play_order[winner]%2==root_pos%2:
                v_vec[pos_lst[i]] = r_t + 0.95*v_tp1
            else:
                v_vec[pos_lst[i]] = r_t - 0.95*v_tp1
        #print("naive search ends")
        return v_vec

'''
    def calc_score(self):
        #print("wwet:",self.who_wins_each_turn)
        score = np.zeros(4)
        has_score_flag = [False, False, False, False]
        c10_flag = [False, False, False, False]
        heart_count = np.zeros(4)
        # calc points
        for people in range(4):
            for turn in range(13):
                if self.who_wins_each_turn[turn] == people:
                    for players in range(4):
                        pos = self.history[turn * 8 + players * 2 + 1]
                        i = DECODING_DICT1[pos // 13] + DECODING_DICT2[pos % 13]
                        # print(i)
                        if i in SCORE_DICT.keys():
                            if i == "C10":
                                c10_flag[people] = True
                            else:
                                score[people] += SCORE_DICT[i]
                                has_score_flag[people] = True
                            if i.startswith('H') or i.startswith('J'):
                                heart_count[people] += 1
            # check whole Hearts
            if heart_count[people] == 13:
                score[people] += 400
            # settle transformer
            if c10_flag[people] == True:
                if has_score_flag[people] == False:
                    score[people] += 50
                else:
                    score[people] *= 2
        if TRAINING:
            score[0] = score[0] + score[2]
            score[1] = score[1] + score[3]
            a = score[0]
            b = score[1]
            score[0] = a-b
            score[1] = b-a
            score[2] = score[0]
            score[3] = score[1]
        return score
'''