from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework import generics
from rest_framework import status
from rest_framework.exceptions import NotFound
from rest_framework.views import APIView
from log_app.models import Program,Log, PollSegment,Review, RespondentStat
from log_app.serializers import ProgramSerializer,ProgramRecordingSerializer

import django_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.pagination import PageNumberPagination
from rest_framework import filters
from django.http import HttpResponse
from rest_framework.response import Response
from django.shortcuts import redirect
import datetime,math

class ProgramFilter(filters.FilterSet):
	# ids = django_filters.NumberFilter(name="pk", lookup_expr='in')
	end_date__gte = django_filters.DateTimeFilter(name="end_date", lookup_expr='gte')
	end_date__gt = django_filters.DateTimeFilter(name="end_date", lookup_expr='gt')
	end_date__lt = django_filters.DateTimeFilter(name="end_date", lookup_expr='lt')
	start_date__gte = django_filters.DateTimeFilter(name="start_date", lookup_expr='gte')
	start_date__lt = django_filters.DateTimeFilter(name="start_date", lookup_expr='lt')
	project__end_date__gte = django_filters.DateTimeFilter(name="project__end_date", lookup_expr='gte')
	country__not = django_filters.NumberFilter(name="radio_station__country", exclude=True)

	class Meta:
		model = Program
		fields = ['id','radio_station','broadcast_language','end_date','start_date','radio_station__country','radio_station__country__name', 'project', 'access',
				  'end_date__lt','end_date__gte','start_date__gte','project__end_date__gte','end_date__gt','start_date__lt','media_backup_status']

class LargeResultsSetPagination(PageNumberPagination):
	page_size = 1000
	page_size_query_param = 'page_size'
	max_page_size = 10000

class ProgramGet(generics.ListCreateAPIView):

	# queryset = Program.objects.all().order_by('-end_date')
	model = Program
	serializer_class = ProgramSerializer
	filter_backends = (filters.OrderingFilter, DjangoFilterBackend,)
	ordering_fields = ('week','id','created_at','end_date','radio_station__country')
	filter_class = ProgramFilter
	pagination_class = LargeResultsSetPagination

	def get_queryset(self):
		"""
		This view should return a list of all the purchases
		for the currently authenticated user.
		"""
		pk_list = self.request.GET.get('ids')
		project_search = self.request.GET.get('project__search')
		if pk_list:
			pk_list = pk_list.split(',')
			queryset = Program.objects.filter(pk__in =pk_list).order_by('-end_date').select_related('project__id','radio_station__country','radio_station__country__name','radio_station__name',).prefetch_related('access')
		elif project_search:
			from django.db.models import Q
			queryset = Program.objects.filter(Q(project__name__icontains=project_search)|Q(project__doner__icontains=project_search))
		else:
			queryset = Program.objects.all().order_by('-end_date').select_related('project__id','radio_station__country','radio_station__country__name','radio_station__name',).prefetch_related('access')

		return queryset

	def perform_create(self, serializer):
		# Set end_date by looking at the number weeks and adding it to the start_date
		from datetime  import timedelta
		from django.utils.dateparse import parse_datetime

		weeks = timedelta(weeks = int(self.request.POST['weeks'])-1)
		end_date = parse_datetime(self.request.POST['start_date']) + weeks
		serializer.save(end_date=end_date.strftime('%Y-%m-%d'))

class ProgramEntity(generics.RetrieveUpdateAPIView):
	queryset = Program.objects.all()
	model = Program
	serializer_class = ProgramSerializer
	lookup_field = 'id'

	def perform_update(self, serializer):
		# Set end_date by looking at the number weeks and adding it to the start_date
		from datetime  import timedelta
		from django.utils.dateparse import parse_datetime

		if 'weeks' in self.request._data:
			weeks = timedelta(weeks = int(self.request._data['weeks'])-1)
			end_date = parse_datetime(self.request._data['start_date']) + weeks
			serializer.save(end_date=end_date.strftime('%Y-%m-%d'))

@api_view(['GET'])
def to_archive(request):
	from django.db.models import Sum,Case,IntegerField,When,Value
	from datetime import date
	paginator = PageNumberPagination()

	if 'page_size' in request.GET:
		paginator.page_size = request.GET['page_size']
	else:
		paginator.page_size = 4

	if 'country' in request.GET:
		programs = Program.objects.filter(end_date__lt=date.today(),radio_station__country__id=request.GET['country']).annotate(recordings=Sum(Case(When(log=None, then=Value(0)),When(log__recording_backup='', then=Value(0)),default=Value(1),output_field=IntegerField()))).filter(recordings__gt=0)
	else:
		programs = Program.objects.filter(end_date__lt=date.today()).annotate(recordings=Sum(Case(When(log=None, then=Value(0)),When(log__recording_backup='', then=Value(0)),default=Value(1),output_field=IntegerField()))).filter(recordings__gt=0)

	programs= paginator.paginate_queryset(programs,request)
	programs= ProgramRecordingSerializer(programs,many=True)

	return paginator.get_paginated_response(programs.data)

def download_media_zipped(request,id):
    # zip
	from zipfile import ZipFile
	from api_core.settings import MEDIA_ROOT

	program = Program.objects.get(id=id)

	logs = Log.objects.filter(program=program).exclude(star_audio=False,recording_backup='')

	filename = 'Uliza-log-'+program.name.encode('utf-8')
	try:
		filename = filename.encode('ascii')
		filename = filename+'.zip'
	except Exception as e:
		filename = 'Uliza-log-PID'+str(program.id)+'.zip'

	with ZipFile(MEDIA_ROOT+'/'+filename,'w',allowZip64=True) as zipper:
		try:
			for log in logs:
				zipper.write(log.recording_backup.path, log.recording_backup.name)
		except OSError: pass

	program.media_backup_status = 'zip'
	program.save()

	if 'redirect' in request.GET:
		from api_core.settings import MEDIA_URL
		return redirect('http://'+request.META['HTTP_HOST']+MEDIA_URL+filename)

	zipper = open(MEDIA_ROOT+'/'+filename,'r')
	response = HttpResponse(zipper,content_type='application/zip')
	response['Content-Disposition'] = 'attachment; filename='+filename

	return response

def delete_all_media(request,id):
	from api_core.settings import MEDIA_ROOT
	import os

	program = Program.objects.get(id=id)
	logs = Log.objects.filter(program=program).exclude(star_audio=False,recording_backup='')

	for log in logs:
		os.unlink(log.recording_backup.path)
		log.recording_backup = None
		log.save()

	if program.media_backup_status == 'zip':
		filename = 'Uliza-log-'+program.name.encode('utf-8')
		try:
			filename = filename.encode('ascii')
			filename = filename+'.zip'
		except:
			filename = 'Uliza-log-PID'+str(program.id)+'.zip'

		os.unlink(MEDIA_ROOT+'/'+filename)

		program.media_backup_status = 'removed'
		program.save()

	return HttpResponse('OK')

def weeks_diff(start,end):
 monday = (start - datetime.timedelta(days=start.weekday()))
 calc = (end - monday).days
 weeks = math.floor(calc/7.0)
 remaining_days = calc%7
 return weeks,remaining_days

def stats(request):
	from django.utils.dateparse import parse_date,parse_datetime
	from django.db.models import Sum,Avg
	start_date = parse_datetime(request.GET['start_date']+' 00:00')
	end_date = parse_date(request.GET['end_date'])

	programs = Program.objects.filter(end_date__gte = start_date,start_date__lte=end_date).exclude(project__country__exclude=True)

	if not request.GET['country'] == 'all':
		programs = programs.filter(project__country = request.GET['country'])

	total_episodes = 0
	total_hours = 0
	total_responses = 0
	average_respondents = 0
	total_polls = 0
	total_stations = {}
	total_reviews = 0
	total_better_episodes = 0
	percentage_reviews = 0
	total_number_of_programs = 0

	import csv
	response = HttpResponse(content_type='text/csv')
	response['Content-Disposition'] = 'attachment; filename="Uliza-Log-export-'+request.GET['start_date']+'-'+request.GET['end_date']+'.csv"'
	writer = csv.writer(response)
	writer.writerow(['Radio series code','Public name','Radio station name','Project name','Country','Episodes aired','Episodes reviewed','Airtime (mins)','start date','end_date'])

	weekdays = ( 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')

	for program in programs:
		number_of_episodes = 0
		start_week_number=0
		better_scores = 0
		end_week_number = program.weeks
		program.start_date = program.start_date.replace(tzinfo=None)

		if program.start_date < start_date:
			week_diff = weeks_diff(program.start_date,start_date)

			start_week_number = week_diff[0]
			if program.start_date.weekday() < start_date.weekday():
				start_week_number +=1

		if program.end_date > end_date:
			week_diff = weeks_diff(end_date,program.end_date)
			end_week_number = week_diff[0]
			end_week_number = program.weeks-end_week_number

			if end_date.weekday() < program.start_date.weekday():
				end_week_number -=1

		number_of_episodes = end_week_number - start_week_number
		postponements = Log.objects.filter(program=program,postpone=True,week__gte=start_week_number,week__lte=end_week_number)
		number_of_episodes = number_of_episodes - len(postponements)

		if program.repeat_start_time:
			duration = program.duration*2
		else:
			duration = program.duration

		if number_of_episodes > 0:
			# todo there are times where there could be duplicate reviews for an episode
			reviews = Review.objects.filter(log__week__gte=start_week_number,log__week__lte=end_week_number,log__program=program)
			if 'export' in request.GET:
				try:
					if not program.public_name:
						public_name = ''
					else:
						public_name = program.public_name
					writer.writerow([program.name.encode('utf8'),public_name.encode('utf8'),program.radio_station.name.encode('utf8'),program.project.name.encode('utf8'),program.project.country.name.encode('utf8'),int(number_of_episodes),len(reviews),program.duration,str(program.start_date),str(program.end_date)])
				except Exception as e:
					pass

			total_number_of_programs += 1
			start_week_number = int(start_week_number)
			better_scores = reviews.filter(numerical_score__gt=33)
			better_scores = len(better_scores)
			total_reviews += len(reviews)
			total_stations[program.radio_station.id] = program.radio_station.name
			total_episodes = total_episodes + number_of_episodes

			# total_hours will get into negative
			if program.repeat_start_time and program.repeat_week_day:
				if weekdays.index(program.repeat_week_day) < program.start_date.weekday() or weekdays.index(program.repeat_week_day) > end_date.weekday():
					total_hours = total_hours - duration/2

			duration = duration*number_of_episodes
			total_hours = total_hours + duration

			if not program.poll_program_id:
				polls = PollSegment.objects.filter(program=program,episode_number__gte=start_week_number,episode_number__lte=end_week_number)
				total_polls += len(polls)
				responses = polls.aggregate(Sum('number_of_responses'))
				respondents = polls.aggregate(Sum('number_of_respondents'))
				if responses['number_of_responses__sum']:
					total_responses += responses['number_of_responses__sum']

				if respondents['number_of_respondents__sum']:
					average_respondents += respondents['number_of_respondents__sum']

		total_better_episodes += better_scores

	if total_episodes > 0:
		percentage_reviews = (total_reviews/total_episodes)*100

	if total_polls > 0:
		average_respondents = math.ceil(average_respondents/total_polls)

	total_hours = total_hours/60
	total_hours = math.floor(total_hours)
	percentage_reviews = math.floor(percentage_reviews)

	if 'export' in request.GET:
		return response

	return JsonResponse({'programs':total_number_of_programs,
						'number_of_better_episodes':total_better_episodes,
						'percentage_reviews':percentage_reviews,
						'number_of_reviews':total_reviews,
						'total_stations':len(total_stations.keys()),
						'total_episodes':int(total_episodes),
						'total_hours':total_hours,
						'total_responses':total_responses,
						'average_respondents':average_respondents},
						safe=False)

def interactivity(request):
	if 'program' in request.GET and not request.GET['program'] == 'all':
		program = Program.objects.get(id=request.GET['program'])

		# if a specific program is selected as a filter and if polls is linked to another program instance
		if program.poll_program_id:
			poll_segments = PollSegment.objects.filter(program__id=program.poll_program_id).order_by('episode_number')
			respondent_stat = RespondentStat.objects.filter(program__id=program.poll_program_id)
		else:
			poll_segments = PollSegment.objects.filter(program__id=request.GET['program']).order_by('episode_number')
			respondent_stat = RespondentStat.objects.filter(program__id=request.GET['program'])
	elif 'radio_station' in request.GET and not request.GET['radio_station'] == 'all':
		from django.db.models import Q
		programs = Program.objects.filter(radio_station=request.GET['radio_station'],project=request.GET['project']).exclude(poll_program_id=None).values_list('poll_program_id',flat=True)
		poll_segments = PollSegment.objects.filter(Q(program__id__in=programs)|Q(program__project=request.GET['project'],program__radio_station=request.GET['radio_station'])).order_by('episode_number','program')
		respondent_stat = RespondentStat.objects.filter(Q(program__id__in=programs)|Q(program__project=request.GET['project'],program__radio_station=request.GET['radio_station']))
	else:
		poll_segments = PollSegment.objects.filter(program__project=request.GET['project']).order_by('episode_number','program')
		respondent_stat = RespondentStat.objects.filter(program__project=request.GET['project'])

	series = [[],[],[]]
	labels = []
	total_responses = 0
	unique_respondents = []
	episodes = 0
	init_program = 0

	episode_respondents = []

	episode_responses = 0
	episode_repeat_respondent = 0

	previous_program = poll_segments[0].program.id
	week = poll_segments[0].episode_number
	counter = 0
	programs = []

	import json
	for poll in poll_segments:

		# checks if the polling data is shared with other programs
		# keeping count of the number of episodes with unique polling

		# keeping count of the total # of the responses
		total_responses += poll.number_of_responses

		if not week == poll.episode_number:

			series[1].append(episode_responses)

			stat = respondent_stat.filter(program=previous_program,episode_number = week).last()
			counter = counter+1
			if stat:
				episode_respondents = episode_respondents+json.loads(stat.unique_respondents_list)
				episode_repeat_respondent += stat.repeat_respondents_number

				# add episode respondents to all unique respondents list
				unique_respondents = unique_respondents + episode_respondents

				episode_respondents = len(episode_respondents)+episode_repeat_respondent
				series[0].append(episode_respondents)
			else:
				series[0].append(None)

			# reset episode respondents list
			episode_respondents = []
			episode_responses = 0
			episode_repeat_respondent = 0
			previous_program = poll.program.id
			episodes = episodes+1

			labels.append(label)
		elif not poll.program.id == previous_program:
			stat = respondent_stat.filter(program=previous_program,episode_number=week).last()
			previous_program = poll.program.id
			episodes = episodes+1

			if stat:
				episode_respondents = episode_respondents+json.loads(stat.unique_respondents_list)
				episode_repeat_respondent += stat.repeat_respondents_number

		label = 'Ep'+str(poll.episode_number)
		week = poll.episode_number
		episode_responses += poll.number_of_responses

	stat = respondent_stat.filter(program=poll.program,episode_number = week).last()
	if stat:
		series[1].append(episode_responses)
		episode_respondents = episode_respondents+json.loads(stat.unique_respondents_list)

		# add episode respondents to all unique respondents list
		unique_respondents = unique_respondents + episode_respondents
		episode_repeat_respondent += stat.repeat_respondents_number
		episode_respondents = len(episode_respondents)+episode_repeat_respondent

		series[0].append(episode_respondents)
		labels.append(label)
		episodes = episodes+1
	else:
		series[0].append(None)

	unique_respondents = set(unique_respondents)
	unique_respondents = len(unique_respondents)

	questions = len(poll_segments)
	response = {'series':series,'labels':labels,'total_responses':total_responses,'questions':questions,'unique_respondents':unique_respondents,'total_episodes':episodes}

	return JsonResponse(response,safe=False)

def interactivity_export(request):
	if 'program' in request.GET and not request.GET['program'] == 'all':
		program = Program.objects.get(id=request.GET['program'])

		# if a specific program is selected as a filter and if polls is linked to another program instance
		if program.poll_program_id:
			poll_segments = PollSegment.objects.filter(program__id=program.poll_program_id).order_by('program','episode_number')
		else:
			poll_segments = PollSegment.objects.filter(program__id=request.GET['program']).order_by('program','episode_number')
	elif 'radio_station' in request.GET and not request.GET['radio_station'] == 'all':
		from django.db.models import Q
		programs = Program.objects.filter(radio_station=request.GET['radio_station'],project=request.GET['project']).exclude(poll_program_id=None).values_list('poll_program_id',flat=True)
		poll_segments = PollSegment.objects.filter(Q(program__id__in=programs)|Q(program__project=request.GET['project'],program__radio_station=request.GET['radio_station'])).order_by('program','episode_number')
	else:
		poll_segments = PollSegment.objects.filter(program__project=request.GET['project']).order_by('program','episode_number')

	data = {}
	program_id_name = {}

	for poll in poll_segments:
		program_id_name[poll.program.id] = poll.program.name + 	"("+poll.program.start_date.strftime('%b %Y')+" - "+poll.program.end_date.strftime('%b %Y')+")"

		if not poll.program.id in data:
			data[poll.program.id] = {}

		if not poll.episode_number in data[poll.program.id]:
			data[poll.program.id][poll.episode_number] = {'interactions':poll.number_of_responses,'unique_respondents':poll.number_of_respondents}
		else:
			data[poll.program.id][poll.episode_number]['interactions'] += poll.number_of_responses
			if (poll.number_of_respondents>data[poll.program.id][poll.episode_number]['unique_respondents']):
				data[poll.program.id][poll.episode_number]['unique_respondents'] = poll.number_of_respondents

	data = [data,program_id_name]

	return JsonResponse(data,safe=False)

def export_respondents(request):
	if 'program' in request.GET and not request.GET['program'] == 'all':
		program = Program.objects.get(id=request.GET['program'])

		# if a specific program is selected as a filter and if polls is linked to another program instance
		if program.poll_program_id:
			respondent_stat = RespondentStat.objects.filter(program__id=program.poll_program_id).order_by('episode_number','program')
		else:
			respondent_stat = RespondentStat.objects.filter(program__id=request.GET['program']).order_by('episode_number','program')
	elif 'radio_station' in request.GET and not request.GET['radio_station'] == 'all':
		from django.db.models import Q
		programs = Program.objects.filter(radio_station=request.GET['radio_station'],project=request.GET['project']).exclude(poll_program_id=None).values_list('poll_program_id',flat=True)
		respondent_stat = RespondentStat.objects.filter(Q(program__id__in=programs)|Q(program__project=request.GET['project'],program__radio_station=request.GET['radio_station'])).order_by('episode_number','program')
	else:
		respondent_stat = RespondentStat.objects.filter(program__project=request.GET['project']).order_by('episode_number','program')

	respondent_list = {}
	program_id_name = {}
	import json
	prev_respondent_stat = None

	for stat in respondent_stat:
		program_id_name[stat.program.id] = stat.program.name

		unique_respondents = json.loads(stat.unique_respondents_list)
		for new_respondent in unique_respondents:

			if new_respondent in respondent_list:
				respondent_list[new_respondent].append(stat.program.name+' Ep-'+str(stat.episode_number))
			else:
				respondent_list[new_respondent] = [stat.program.name+' Ep-'+str(stat.episode_number)]

	return JsonResponse(respondent_list,safe=False)


#
# @lc app=leetcode id=2530 lang=python3
#
# [2530] Maximal Score After Applying K Operations
#

# @lc code=start
class Solution:
    def maxKelements(self, nums: List[int], k: int) -> int:
        heap = [-n for n in nums]
        heapify(heap)
        ans = 0
        while k:
            n = -heappop(heap)
            ans += n
            heappush(heap, -ceil(n / 3))
            k -= 1
        return ans

# @lc code=end


def fft540(time,amp):
    """Função para calcular a FFT de um sinal. Esta função é baseada no comando FFT no Numpy.

    Arguments:
        time {[float]} -- vetor de tempo
        amp {[float]} -- vetor de amplitude

    Returns:
        [float] -- vetor de frequências
        [complex float] -- vetor de amplitudes complexas
    """
    #### fft ####
    timestep = time[1]-time[0] # intervalo de amostragem = dt
    n = len(amp)
    fs = 1/timestep # frequencia de amostragem

    #vetor de frequencias (positivas e negativas)
    freq = np.fft.fftfreq(n, d=timestep)
    #fft
    yfft = np.fft.fft(amp)/n # fft computing and normalization

    return freq, yfft


import asyncio
from consumer import *
from endpoints import Endpoints
from exchange import Exchange
from components import *
from evaluator import *

def foo(string):
    async def processor(exchange):
        assert (isinstance(exchange.get_body(), str))
        exchange.set_body(exchange.get_body() + ' ' + string)
        return exchange

    return processor

async def ppp(exchange):
    print(exchange.get_body())

def predicate(exchange):
    return True

(RouteId('myroute')
        .process(lambda exchange: exchange.set_body('bar'))
        .to(foo('wao'))
        .to(set_header('ch','boo'))
        .when([
        (exists(header('ch')), To(foo('poko')).to(foo('pai'))),
        (True, To(foo('pen')).to(foo('pee')).when([
            (True, To(foo('nyao'))),
            (False, To(foo('passo')))]))
        ])
    .to(foo('final'))
    .to(log())
    .filter(True)
    .to(foo('papaiya'))
    #.split(body, To(ppp))
) #yapf:disable

RouteId('myfoo').to(cache({
    'to': 'myroute',
    'keys': [header('pon.puu')]
})).to(direct({
    'to': 'myroute'
})).split(body(), To(ppp))

def gather_func(exchanges):
    gathered_body = exchanges[0].get_body() + " " + exchanges[1].get_body()
    exchanges[0].set_body(gathered_body)
    return exchanges[0]

RouteId('gather_a').to(foo('bon'))
(RouteId('gathering')
    .gather(
        [To(direct({'to': 'gather_a'})), To(foo('poyo')).to(foo('pin'))],
        gather_func)
    #.split(body(), Process(lambda x: print(x.body)).process(lambda x:print(x.body,x.body)))
) #yapf: disable

#expect: log exchange:body {"foo": null}
(Timer({'repeatCount': 3})
    .to(set_header('foo', {'foo': None}))
    .to(to_json(header('foo')))
    .to(log())) #yapf: disable

async def tasks_main():
    #yapf:disable
    exchange = await Endpoints().send_to('myfoo',Exchange("poko",{'foo': 'bar','pon': {'puu': 'poo'}}))
    exchange = await Endpoints().send_to('myfoo',Exchange("poko",{'foo': 'bar','pon': {'puu': 'poo'}}))
    gathering_exchange = await Endpoints().send_to('gathering', Exchange('boo'))
    #yapf:enable
    if exchange:
        print(exchange.get_body())
    if gathering_exchange:
        #expect: boo bon boo poyo
        print('gathered:', gathering_exchange.get_body())


import random

from util import argmin_random_tie

def min_conflicts_value(csp, var, current):
    """Return the value that will give var the least number of conflicts.
    If there is a tie, choose at random."""
    return argmin_random_tie(csp.domains[var], key=lambda val: csp.nconflicts(var, val, current))

def min_conflicts(csp, max_steps=100000):
    """Solve a CSP by Hill Climbing on the number of conflicts."""
    """ YOUR CODE HERE """
    from random import choice
    from .variable_order import mrv
    def random_choose(assignment):
        l=csp.variables
        if len(l)==len(assignment):
            return choice(l)
        else:
            return mrv(assignment,csp)
    assignment=dict()
    step=0
    while(len(assignment)<len(csp.variables) or not csp.goal_test(assignment)) and step<max_steps:
        var=random_choose(assignment)
        val=min_conflicts_value(csp,var,assignment)
        csp.assign(var,val,assignment)
        step+=1
    if csp.goal_test(assignment):
        return assignment
    else: return None


import tensorflow as tf
import numpy as np
from PIL import Image

def execute_notebook(notebook_path):
    import os
    os.system(f'jupyter nbconvert --to script {notebook_path}')
    script_path = notebook_path.replace('.ipynb', '.py')
    os.system(f'python {script_path}')

try:
    loaded_model = tf.keras.models.load_model("saved_model/Classification")
except:
    execute_notebook("CNN.ipynb")
    loaded_model = tf.keras.models.load_model("saved_model/Classification")

img = Image.open("auto.jpg")

# Resize and normalize the image
(img_rows, img_cols)=32,32
img = img.resize((img_rows, img_cols))
img_array = np.array(img)
img_array = img_array.astype("float32") / 255.0
img_array = np.expand_dims(img_array, axis=0)

# Make a prediction
predictions = loaded_model.predict(img_array)

# Get the predicted class
predictions = np.argmax(predictions)
classes=["airplane","automobile","bird","cat","deer","dog","frog","horse","ship","truck"]
predicted_class=classes[predictions]
print("Predicted class:", predicted_class)


a = 5
b = 0
try:
    c = a / b
    print("El resultado es:", c)
except ZeroDivisionError:
    print("Error, no se puede dividir por cero")
except:
    print("Error en la app")
print("Fin del programa")


import pandas as pd
import os
CURRENT_PATH = os.getcwd()

def get_data_using_pandas(name_dataset):

    if name_dataset == 'po2011':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/pick_order_2011.csv")
        df = df.append({'pick_order':'99','team':'Choose a team!','team_name':2011}, ignore_index=True)

    elif name_dataset == 'po2021':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/pick_order_2021.csv")
        df = df.append({'pick_order':'99','team':'Choose a team!','team_name':2021}, ignore_index=True)

    elif name_dataset == 'dataset_draft_2021':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/univ_data_2021.csv")

    elif name_dataset == 'train':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/common_dataset.csv")

    elif name_dataset == 'train_risk':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/risk_dataset.csv")

    elif name_dataset == 'team_stats_2021':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/team_stats_2021.csv")

    elif name_dataset == 'team_stats_2011':
        df = pd.read_csv(f"{CURRENT_PATH}/nba_forecast/data/team_stats_2011.csv")

    return df

def filter_data(df,type):
    #returns a dataset with only the features needed (offensive ratio prediction or defensive ratio prediction)
    off_features = ['mp', 'gs_pct', 'last_uni_age', 'pos', 'per','ts_pct','fg3a_per_fga_pct','fta_per_fga_pct',\
                    'orb_pct','ast_pct','tov_pct','usg_pct','ows','obpm']

    def_features = ['mp', 'gs_pct', 'last_uni_age', 'pos', 'stl_pct','blk_pct','dws','drb_pct','dbpm']

    athletics_features = [  'body_fat_pct', 'hand_length', 'hand_width', 'height_wo_shoes',\
                            'height_w_shoes', 'standing_reach', 'weight', 'wingspan']

    risk_features = [ 'mp','per','ts_pct','fg3a_per_fga_pct','fta_per_fga_pct',
          'orb_pct','drb_pct','ast_pct','stl_pct','blk_pct','tov_pct','usg_pct','ows','dws','obpm','dbpm','years']

    if type == 'model_off':
        #return dataset with offensive and atheltics features (discard defensive features)
        df_off = df[off_features+athletics_features].copy()
        #convert numerical features to float64 to match KNN imputer params
        to_be_converted = [ 'gs_pct','mp','last_uni_age','hand_length','hand_width',\
                            'height_w_shoes','height_wo_shoes','standing_reach','wingspan']

        for column in to_be_converted:
            df_off[column] = df_off[column].astype('float64')

        return df_off

    elif type == 'model_def':
        #return dataset with defensive and atheltics features (discard offensive features)
        df_def = df[def_features+athletics_features].copy()
        df_def = pd.get_dummies(df[def_features+athletics_features])
        return df_def

    elif type == 'model_risk':
        #return dataset with features used for risk factor prediction
        df_risk = df[risk_features].copy()
        return df_risk

if __name__ == '__main__':
    df = get_data_using_pandas('train')
    print(df)


import random
import time

def computer_move(computer_moves, player_board, computer_board):
    print("computer is thinking...")
    time.sleep(3)
    while len(computer_moves) > 0:
        computer_move = computer_moves.pop()
        if not player_board & (1 << computer_move):
            return computer_board | (1 << computer_move), computer_moves
    return computer_board, computer_moves

def player_move(computer_board, player_board, player_move):
    if not computer_board & (1 << player_move) and not player_board & (
            1 << player_move):
        return player_board | (1 << player_move), True
    else:
        return None, False

def check_win(win_conditions, computer_board, player_board):
    for win_condition in win_conditions:
        if win_condition & player_board == win_condition:
            return "player"
        elif win_condition & computer_board == win_condition:
            return "computer"
        elif computer_board & player_board == 0b111111111:
            return "tie"
    return ""

def get_player_move():
    return int(validate_and_input("""Choose your move 0,1,2
                 3,4,5
                 6,7,8\n""", ['0', '1', '2', '3', '4', '5', '6', '7', '8']))

def print_board(computer_board, player_board):
    board_string = """
 {0} | {1} | {2}
-----------
 {3} | {4} | {5}
-----------
 {6} | {7} | {8}
"""
    board_positions = []
    for element in range(0, 9):
        if computer_board & (1 << element):
            board_positions.append('o')
        elif player_board & (1 << element):
            board_positions.append('x')
        else:
            board_positions.append(' ')
    print(board_string.format(*board_positions))

def is_starting_player():
    coin_choice = validate_and_input("To decide who goes first, lets flip a coin, (h)eads or (t)ails?", ['h', 't'])
    print("flipping coin...\n")
    time.sleep(1)
    if (random.randint(0, 2) == 1 and coin_choice == 'h') or (random.randint(0, 2) == 0 and coin_choice == 't'):
        print("Good guess, you go first!\n")
        return True
    else:
        print("Better luck next time, computer goes first\n")
        return False

def sleep_input(string):
    input_str = input(string)
    time.sleep(0.5)
    return input_str

def validate_and_input(string, valid_input):
    input = '----'
    while input not in valid_input:
        input = sleep_input(string)
    return input

def get_computer_moveset():
    computer_moves = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    random.shuffle(computer_moves)
    return computer_moves

def get_constants():
    return 0, 0, [0b111000000,
                  0b000111000,
                  0b000000111,
                  0b100100100,
                  0b010010010,
                  0b001001001,
                  0b100010001,
                  0b001010100], get_computer_moveset()

def get_player_board_after_move(computer_board, player_board):
    success = False
    while not success:
        move = get_player_move()
        temp, success = player_move(computer_board, player_board, move)
    return temp

def check_and_act_on_end_conditions(player_board, computer_board, win_conditions):
    condition = check_win(win_conditions, computer_board, player_board)
    if condition == '':
        return False
    if condition == "tie":
        print("DRAW! Almost, but not quite ðŸ˜�")
    if condition == "player":
        print("Ayyy, you won! Nice one ðŸ˜Š")
    if condition == "computer":
        print("You got beaten, damn ðŸ’©")
    return True

def main():
    player_board, computer_board, win_conditions, computer_moves = get_constants()

    print("----------------\nWelcome to tic-tac-toe!\n----------------\n")
    is_player_turn = is_starting_player()
    finished = False
    while not finished:
        if is_player_turn:
            player_board = get_player_board_after_move(computer_board, player_board)
        else:
            computer_board, computer_moves = computer_move(computer_moves, player_board, computer_board)
        print_board(computer_board, player_board)
        is_player_turn = not is_player_turn
        finished = check_and_act_on_end_conditions(player_board, computer_board, win_conditions)

if __name__ == '__main__':
    main()


import numpy as np

def reader(file_name):
    lista = []

    with open(file_name, encoding='utf-8') as f:
        for line in f:
            lista += [line.split(',')]

    return lista

logs_28 = reader('LOGS-28-07-2021.txt')
logs_29 = reader('LOGS-29-07-2021.txt')
logs_30 = reader('LOGS-30-08-2020.txt')

pcr_28 = reader('PCR-28-07-2021.txt')
pcr_29 = reader('PCR-29-07-2021.txt')
pcr_30 = reader('PCR-30-08-2020.txt')

def telefonos_sospechosos(logs):
    cerciorados = np.zeros(len(logs), dtype=int)
    telefonos = []
    for i in range(len(logs)):
        j = i+1
        while(j < len(logs)):
            repite = logs[i][2]==logs[j][2] and logs[i][0]!=logs[j][0]
            if (cerciorados[j]==0 and cerciorados[i]==0 and repite):
                cerciorados[j] = 1
                cerciorados[i] = 1
                telefonos += [[logs[i][2],logs[i][0], logs[j][0]]]
                j+=1
            elif (cerciorados[j]==0 and cerciorados[i]==1 and repite):
                telefonos[-1] += [logs[j][0]]
                j+=1
            else:
                j+=1
    return telefonos

telefonos_28 = telefonos_sospechosos(logs_28)
telefonos_29 = telefonos_sospechosos(logs_29)
telefonos_30 = telefonos_sospechosos(logs_30)

#agrega los datos de la persona asociada al telefono sospechoso
def agrega_info(telefonos,datos):
    resultado = []
    for i in range(len(telefonos)):
        for j in range(len(datos)):
            if (datos[j][2]==telefonos[i][0]):
                resultado += [[datos[j][0], datos[j][3].rstrip('\n')] + telefonos[i]]
    return resultado

resultados_28 = agrega_info(telefonos_28,pcr_28)
resultados_29 = agrega_info(telefonos_29,pcr_29)
resultados_30 = agrega_info(telefonos_30,pcr_30)

print(resultados_28[0:10])
print(resultados_29[0:10])
print(resultados_30[0:10])

def writer(file_name, data):
    with open(file_name, 'w', encoding='utf-8') as f:
        for i in range(len(data)):
            line = ''
            for j in range(len(data[i])):
                line += data[i][j]+','
            line = line[:-1]
            line += '\n'
            f.write(line)

writer('RESULTADOS-28-07-21.txt', resultados_28)
writer('RESULTADOS-29-07-21.txt', resultados_29)
writer('RESULTADOS-30-08-20.txt', resultados_30)


from datetime import datetime
import os

# after 30th June IST
LATE_REGISTRATION_START_DATE = datetime.strptime(
    "2020-07-01T00:00:00+05:30", "%Y-%m-%dT%H:%M:%S%z"
)
# after 10th July IST
USER_REGISTRATIOn_END_DATE = datetime.strptime(
    "2020-07-11T00:00:00+05:30", "%Y-%m-%dT%H:%M:%S%z"
)
QUESTION_TO_ASK = 3
QUIZ_TIME_LIMIT = int(os.getenv("QUIZ_TIME_LIMIT", 90))
QUIZ_PRIZE_AMOUNT = list(
    float(val)
    for val in os.getenv("QUIZ_PRIZE_AMOUNT", "137.5 112.5 100 75 75").split()
)


# Author: FrancisDShanks
# Email: tctcdtc@gmail.com

n = int(input())
a = [[0 for i in range(n+1)] for j in range(n+1)]
a[1][1] = 1
print("1")
for i in range(2,n+1):
    for j in range(1,i+1):
        a[i][j] = a[i-1][j-1] + a[i-1][j]
        print(a[i][j],end=' ')
    print('')


import json

from django.db.models import Prefetch
from django.http import JsonResponse

import logging
from gateway.models import Router, Step, StepApi
from operator import methodcaller
import grequests

logger = logging.getLogger(__name__)

def get_request(url_list):
    res = []
    req_list = []
    for i in url_list:
        # 请求方法pop出去
        methods = i.pop("methods")
        existence = i.pop("existence")
        req_list.append(methodcaller(methods, **i)(grequests))
    res_list = grequests.map(req_list)  # 并行发送，等最后一个运行完后返回
    for i in res_list:
        res.append(get_response(json.loads(i.text), existence))
    return res

def get_response(resp, existence):
    return resp

def get_req_url_list(step_instance):
    url_list = []
    for instance in step_instance:
        # 组装步骤下的api对象
        service_instance = instance.api.server
        api_instance = instance.api
        # 请求体和响应体组装
        involve = json.loads(api_instance.involve)
        existence = json.loads(api_instance.existence)
        # 组装请求链接
        to_url = api_instance.protocol.lower() + "://" + service_instance.instances + api_instance.path
        print(to_url)
        url_list.append(dict(
            url=to_url,
            methods=api_instance.method.lower(),
            headers=involve["headers"],
            params=involve["args"],
            json=involve["data"],
            existence=existence
        ))
    return url_list

def router_page(request, path='/'):
    # 根据当前路径获取路由对象，关联查询api或者step编排
    router_instance = Router.objects.select_related("arrangement").select_related("api__server").get(path="/" + path)
    # 获取关联数据对象
    res_data = []
    if router_instance.api:
        res_data.append(get_request(router_instance))
    if router_instance.arrangement:
        # 路由对应的编排对象
        arrangement_instance = router_instance.arrangement
        # 获取当前编排下的所有步骤数据
        step_queryset = Step.objects.prefetch_related(
            Prefetch("steps", to_attr="step_api_cache")
        ).filter(arrangement=arrangement_instance).order_by("sort")
        # 请求接口
        for step_instance in step_queryset:
            url_list = get_req_url_list(step_instance.step_api_cache)
            res_data.append(
                {step_instance.id: get_request(url_list)}
            )
    return JsonResponse({"data": res_data})

import time

async def main(request):
    import asyncio
    from aiohttp import ClientSession
    import aiohttp

    urls = ['http://39.103.236.234:10003/', 'http://39.103.236.234:10003/']

    async def fetch(session, url):
        async with session.get(url) as response:
            return await response.text()

    async def get(url):
        async with aiohttp.ClientSession() as session:
            html = await fetch(session, url)
            print(html)

    tasks = [get(x) for x in urls]
    print("wwwwww")
    loop = asyncio.get_event_loop()
    print("wwwwww")
    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    return JsonResponse({"data": ""})


import discord
from discord.ext import commands
from discord import app_commands, ui
from datetime import datetime

class ReasonMessage(discord.ui.Modal):
    def __init__(self, message:discord.Message):
        self.message = message
        super().__init__(title=f'Report Message')
    reason = ui.TextInput(label='Reason', style=discord.TextStyle.short, placeholder='Please provide a reason for the report')

    async def on_submit(self, interaction:discord.Interaction):
        b=await interaction.client.server_config.find_field_value(self.message.guild.id, 'modules', 'report', 'channel')
        channel=interaction.client.get_channel(int(b))
        await interaction.response.send_message('The message has been reported to the moderators!', ephemeral=True)
        embed=discord.Embed(
            title= f'❯ Reported in channel: {self.message.channel.name}',
            description=f'[{self.message.content}]({self.message.jump_url})\nReason: {self.reason.value}',
            timestamp= datetime.now())
        embed.add_field(name='❯Reporter',value=interaction.user.mention)
        embed.add_field(name='❯Author', value=self.message.author.mention)
        await channel.send(embed=embed)

class ReasonMember(discord.ui.Modal):
    def __init__(self, member:discord.Member):
        self.member = member
        super().__init__(title=f'Report Member')
    reason = ui.TextInput(label='Reason', style=discord.TextStyle.short, placeholder='Please provide a reason for the report')

    async def on_submit(self, interaction:discord.Interaction):
        b=await interaction.client.server_config.find_field_value(self.member.guild.id, 'modules', 'report', 'channel')
        channel=interaction.client.get_channel(int(b))
        await interaction.response.send_message('The member has been reported to the moderators!', ephemeral=True)
        embed=discord.Embed(
            title= f'❯ A user has been reported',
            description='',
            timestamp= datetime.now())
        embed.add_field(name='❯Reporter',value=interaction.user.mention)
        embed.add_field(name='❯Member', value= self.member.mention)
        embed.add_field(name='❯Reason', value= self.reason)
        await channel.send(embed=embed)

class Report(commands.Cog):
    def __init__(self, bot: commands.Bot) -> None:
        self.bot = bot
        self.ctx_menu = app_commands.ContextMenu(
            name='Report Message',
            callback=self.ReportMessage_context_menu,
        )
        self.ctx_menu2 = app_commands.ContextMenu(
            name='Report Member',
            callback=self.ReportMember_context_menu,
        )
        self.bot.tree.add_command(self.ctx_menu)
        self.bot.tree.add_command(self.ctx_menu2)

    async def cog_unload(self) -> None:
        self.bot.tree.remove_command(self.ctx_menu.name, type=self.ctx_menu.type)

    async def ReportMessage_context_menu(self, interaction: discord.Interaction, message: discord.Message) -> None:
        try:
            a=await self.bot.server_config.find_field_value(message.guild.id,'modules', 'report', 'status')
            if a is True:
                await interaction.response.send_modal(ReasonMessage(message))
            else:
                await interaction.response.send_message(f'Report module is disabled!', ephemeral=True)
        except:
            await interaction.response.send_message(f'Report module has not been enabled!', ephemeral=True)

    @app_commands.checks.has_permissions(ban_members=True)
    async def ReportMember_context_menu(self, interaction: discord.Interaction, member: discord.Member) -> None:
        try:
            a=await self.bot.server_config.find_field_value(member.guild.id,'modules', 'report', 'status')
            if a is True:
                await interaction.response.send_modal(ReasonMember(member))
            else:
                await interaction.response.send_message(f'Report module is disabled!', ephemeral=True)
        except KeyError:
            await interaction.response.send_message(f'Report module has not been enabled', ephemeral=True)
async def setup(bot):
    await bot.add_cog(Report(bot))


s1 = float(input('Primeiro segmento: '))
s2 = float(input('Segundo segmento: '))
s3 = float(input('Terceiro segmento: '))

if s1 < s2 + s3 and s2 < s1 + s3 and s3 < s1 + s2:
    print('Os segmentos acima formam um triangulo: ', end='')
    if s1 == s2 ==s3:
        print('Equilátero')
    elif s1 != s2 != s3 != s1:
        print('escaleno')
    else:
        print('isóseles')
else:
    print('Os segmentos acima não formam um triangulo')


from Stack import Stack

def pop_condition(s):
    if s.size() < 4:
        return False
    if s.index(0).__contains__('return') and s.index(1).__contains__('else') and s.index(2).__contains__('return') and s.index(3).__contains__('if'):
        return True
    return False

def find_strings(line):
    instring = False
    buffer = ""
    string_arr = []
    for i in line:
        if i == '"':
            instring ^= True
            if not instring:
                string_arr.append(buffer[1::])
                buffer = ""
        if instring:
            buffer += i
    return set(string_arr)

def from_array_into_string(arr):
    line = ""
    for i in arr:
        line += i + ', '
    return line[0:len(line) - 2]

def make_operands(line):
    arr = line.split(', ')
    newline = line
    for elem in arr:
        if elem.__contains__(' or '):
            oper = elem.split('If(')[1]
            and_args = oper.split(' or ')
            newl = 'Or(' + from_array_into_string(and_args) + ')'
            newline = newline.replace(oper, newl)
    arr = newline.split(', ')
    for elem in arr:
        if elem.__contains__(' and '):
            if elem.__contains__('Or('):
                oper = elem.split('Or(')[1]
            elif elem.__contains__('If('):
                oper = elem.split('If(')[1]
            else:
                oper = elem
            and_args = oper.split(' and ')
            newl = 'And(' + from_array_into_string(and_args) + ')'
            newline = newline.replace(oper, newl)
    #return line
    return newline

def improve_line(line):
    newbuf = '\t' + line
    strings = find_strings(newbuf)
    for string in strings:
        newbuf = newbuf.replace('"' + string + '"', 'StringVal("' + string + '")')
    newbuf = make_operands(newbuf)
    return newbuf

def create_z3():
    z3_funcs = open('z3_funcs.py', 'w')
    original = open('transpep.py', 'r')
    z3_funcs.write("from z3 import *\n\n")
    s = Stack()
    for line in original:
        line = line.replace('\n', '')
        if line.__contains__('def '):
            if not s.isEmpty():
                z3_funcs.write(improve_line(s.pop()))
            z3_funcs.write('\n\n' + line + '\n')
        elif line.__contains__('elif '):
            s.push('else')
            s.push('if ' + line.split('elif ')[1].split(':')[0])
        elif line.__contains__('if '):
            s.push('if ' + line.split('if ')[1].split(':')[0])
        elif line.__contains__('else'):
            s.push('else')
        elif line.__contains__('return '):
            s.push('return ' + line.split('return ')[1])
        while pop_condition(s):
            a = s.pop()
            b = s.pop()
            c = s.pop()
            d = s.pop()
            s.push("return If(" + d[3:] + ', ' + c[7:] + ', ' + a[7:] + ')')
    z3_funcs.write(improve_line(s.pop()))
    newcur = open('newcur.py').read().split('\n')
    z3_funcs.write('\n\n' + newcur[2] + '\n')
    z3_funcs.write(newcur[3])
    z3_funcs.close()

#create_z3()


# Solved on 2022. 6. 17.
# 2669 직사각형 네개의 합집합의 면적 구하기

import sys
input = sys.stdin.readline

res = set()
for _ in range(4):
    ax, ay, bx, by = map(int, input().split())
    for i in range(ax, bx):
        for j in range(ay, by):
            res.add((i, j))
print(len(res))


import json
import random

import pickle
from nltk.stem import WordNetLemmatizer
from tensorflow.keras.models import load_model

import nltk
import numpy as np

class Recognizer():
    def __init__(self, language='fr-FR'):
        self.lemmatizer = WordNetLemmatizer()
        self.intents = json.loads(open(f"./system/data/language/{language}/fr-FR.json", encoding="utf-8").read())

        self.words = pickle.load(open(f"./system/data/language/{language}/words.pkl", "rb"))
        self.classes = pickle.load(open(f"./system/data/language/{language}/classes.pkl", "rb"))
        self.model = load_model(f'./system/data/language/{language}/model.h5')

    def clean_up_sentence(self, sentence):
        sentence_words = nltk.word_tokenize(sentence)
        sentence_words = [self.lemmatizer.lemmatize(word) for word in sentence_words]
        return sentence_words

    def bag_of_words(self, sentence):
        sentence_words = self.clean_up_sentence(sentence)
        bag = [0] * len(self.words)

        for w in sentence_words:
            for i, word in enumerate(self.words):
                if word == w:
                    bag[i] = 1

        return np.array(bag)

    def predict_class(self, sentence):
        bow = self.bag_of_words(sentence)
        res = self.model.predict(np.array([bow]))[0]
        ERROR_THRESHOLD = 0.25
        results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD]

        results.sort(key=lambda x: x[1], reverse=True)
        return_list = []

        for r in results:
            return_list.append({'intent': self.classes[r[0]], 'probability': str(r[1])})

        return return_list

    def get_result(self, intents_list, intents_json):
        tag = intents_list[0]['intent']
        list_of_intents = intents_json['intents']

        for i in list_of_intents:
            if i['tag'] == tag:
                result = random.choice(i['responses'])
                break

        return tag, result, int(float(intents_list[0]['probability']) * 1000) / 1000

    def get_result_without_neural(self, sentence):
        sentence = " ".join(self.clean_up_sentence(sentence))

        for item in self.intents['intents']:
            for pattern in item['patterns']:
                if pattern.lower() in sentence.lower():
                    sentence = sentence.lower().replace(pattern.lower(), "")
                    sentence = "" if sentence == None else sentence
                    return item['tag'], sentence

        return None, None

    def get_response(self, sentence, ignore_neural=False):
        if not ignore_neural:
            ints = self.predict_class(sentence)
            tag, res, probability = self.get_result(ints, self.intents)
            return tag, res, probability
        else:
            tag, result = self.get_result_without_neural(sentence)
            return tag, result, None


#!/usr/bin/env python

"""
Prepare json for pheniqs given barcodes info.

Usage:
python prep_pheniqs_json.py sequence.fastq.gz outfile_prefix_name_prefix rc(boolean) barcode_file

"""

import json
import sys
from Bio.Seq import Seq

seq = sys.argv[1]
outfile_prefix = sys.argv[2]
rc = sys.argv[3]
barcode_pos = sys.argv[4]
barcode_file = sys.argv[5]

if int(rc) == 1:
    outfile_prefix += "_rc"

bc_condition = {}
with open(barcode_file) as f:
    for line in f:
        if ":" in line:
            sample_name, sample_barcode = line.strip().split(":")
            if not sample_name in bc_condition:
                sample_barcode = sample_barcode.strip()
                if int(rc) == 1:
                   sample_barcode = str(Seq(sample_barcode).reverse_complement())
                bc_condition[sample_name] = sample_barcode.strip()

config = {}
config['report url'] = outfile_prefix + "_pheniqs_report.json"
config['input'] = [seq]
config['template'] = {}
config['template']['transform'] = {}
config['template']['transform']['token'] = ["0::"]
config['sample'] = {}
config['sample']['algorithm'] = 'pamld'
# config['sample']['confidence threshold'] = 0.99
# config['sample']['noise'] = 0.01
config['sample']['transform'] = {}
# config['sample']['transform']['token'] = ["0::24"]
config['sample']['transform']['token'] = [barcode_pos]
config['sample']['codec'] = {}

for bc_cond in bc_condition:
    name = bc_cond
    config['sample']['codec']['@' + name] = {}
    config['sample']['codec']['@' + name]['LB'] = name
    config['sample']['codec']['@' + name]['barcode'] = [bc_condition[bc_cond]]
    config['sample']['codec']['@' + name]['output']  = [outfile_prefix + "_" + name + ".fastq.gz"]
    config['undetermined'] = {}
    config['undetermined']["output"] = [outfile_prefix + "_undetermined.fastq.gz"]

with open(outfile_prefix + ".json", 'w') as outfile_prefix:
    json.dump(config, outfile_prefix, indent = 4)


class a ():
    classvar1 = "i am class A"
    def __init__(self):
        self.var1 = "i am inside class A's Constructor"
        self.classvar1 = "Instane of class A"
        self.special = "Special"

class b (a):
    classvar1 = "i am class B"
    def __init__(self):
        self.var1 = "i am inside class B's Constructor"
        self.classvar1 = "Instane of class B"
        super().__init__()

x = a()
y = b()
print(y.classvar1)


from monai.transforms import (  # pylint: disable=g-multiple-import
    AddChanneld,
    Compose,
    CropForegroundd,
    LoadImaged,
    MapTransform,
    Orientationd,
    RandFlipd,
    RandScaleIntensityd,
    RandShiftIntensityd,
    RandSpatialCropd,
    RandZoomd,
    ScaleIntensityRanged,
    Spacingd,
    SpatialPadd,
    ToTensord,
)
from third_party.medical_3d import dataset_utils
import numpy as np

_IN_CHANNELS = 1
_OUT_CHANNELS = 2

# NOTE: Mean image shape at the spacing below is 512, 512, 96.
_PIX_DIM = (0.8, 0.8, 2.5)
_ROI_SIZE = [96, 96, 64]
_FAST_ROI_SIZE = [32, 32, 32]

# This index marks the begining of validation images.
_VALIDATION_INDEX = 296
_END_INDEX = 450

class ConvertToMultiChannelClassesd(MapTransform):
  """Converts labels to multi-channel."""

  def __call__(self, data):
    d = dict(data)
    for key in self.keys:
      result = list()
      for class_id in range(1, _OUT_CHANNELS+1):
        result.append(d[key] == class_id)
      d[key] = np.stack(result, axis=0).astype(np.float32)
    return d

def get_transforms(roi_size, pixdim):
  """Returns training and validation transforms."""
  # The min_hu and max_hu clips the CT image intensity (HU values) to the
  # region-of-interest (pancreas organ and tumor region).
  min_hu = -96
  max_hu = 215

  # When cropping, a large margin is used around the
  # region-of-interest. The validation image is cropped to reduce the
  # memory and compute time.
  # NOTE: this value is currently chosen empirically. Ideally, one should
  # use the entire training and validation image.
  margin = 50

  # zoom_prob decides the probability of the zoom augmentation.
  # NOTE: this value is currently chosen empirically. Ideally, augmentation
  # search can be used to search for the best parameter.
  zoom_prob = 0.8

  # Operations:
  # - Load images.
  # - Make image and labels channel-first.
  # - Resample images to the desired pixel-spacing: 'pixdim'.
  # - Align images to a common orientation.
  # - Clip intensity to min-hu and max-hu and rescale to 0 and 1.
  # - Crop region around the region-of-interest but keep a large margin around.
  # - If the image is smaller than 'roi_size' then pad it else do nothing.
  # - Take random crops of size 'roi_size'.
  # - Randomly flip along axis.
  # - Randomly scale and shift intensities.
  # - Convert to tensor.
  train_transform = Compose([
      LoadImaged(keys=["image", "label"]),
      AddChanneld(keys="image"),
      ConvertToMultiChannelClassesd(keys="label"),
      Spacingd(
          keys=["image", "label"],
          pixdim=pixdim,
          mode=("bilinear", "nearest")),
      Orientationd(keys=["image", "label"], axcodes="RAS"),
      ScaleIntensityRanged(
          keys=["image"],
          a_min=min_hu,
          a_max=max_hu,
          b_min=0.0,
          b_max=1.0,
          clip=True,
      ),
      CropForegroundd(
          keys=["image", "label"], source_key="label", margin=margin),
      # NOTE: Pad atleast to the roi_size. Will do nothing if image is
      # already larger.
      SpatialPadd(keys=["image", "label"], spatial_size=roi_size),
      RandSpatialCropd(
          keys=["image", "label"], roi_size=roi_size, random_size=False),
      RandZoomd(
          keys=["image", "label"],
          prob=zoom_prob,
          min_zoom=1.0,
          max_zoom=1.5,
          mode=("trilinear", "nearest")),
      RandFlipd(keys=["image", "label"], prob=0.5, spatial_axis=0),
      RandScaleIntensityd(keys="image", factors=0.1, prob=0.5),
      RandShiftIntensityd(keys="image", offsets=0.1, prob=0.5),
      ToTensord(keys=["image", "label"]),
  ])

  # NOTE: We will ask the trainer to use sliding-window inference
  # to process larger validation image size patch-by-patch.
  # The trainer allows loading validation images of different sizes.
  #
  # Operations:
  # - Load images.
  # - Make image and labels channel-first.
  # - Resample images to the desired pixel-spacing: 'pixdim'.
  # - Align images to a common orientation.
  # - Clip intensity to min-hu and max-hu and rescale to 0 and 1.
  # - Crop region around the region-of-interest but keep a large margin around.
  # - Convert to tensor.
  val_transform = Compose([
      LoadImaged(keys=["image", "label"]),
      AddChanneld(keys="image"),
      ConvertToMultiChannelClassesd(keys="label"),
      Spacingd(
          keys=["image", "label"],
          pixdim=pixdim,
          mode=("bilinear", "nearest")),
      Orientationd(keys=["image", "label"], axcodes="RAS"),
      ScaleIntensityRanged(
          keys=["image"],
          a_min=min_hu,
          a_max=max_hu,
          b_min=0.0,
          b_max=1.0,
          clip=True,
      ),
      CropForegroundd(
          keys=["image", "label"], source_key="label", margin=margin),
      ToTensord(keys=["image", "label"]),
  ])
  return train_transform, val_transform

def fast_dataset(str_arg):
  """Returns small dataset for local testing.

  Args:
    str_arg: A string of the form 'image_pattern=<path>, label_pattern=<path>'.
  """
  train_transform, val_transform = get_transforms(
      roi_size=_FAST_ROI_SIZE, pixdim=_PIX_DIM)
  return dataset_utils.fast_dataset(
      str_arg=str_arg,
      val_roi_size=_FAST_ROI_SIZE,
      train_transform=train_transform,
      val_transform=val_transform,
      in_channels=_IN_CHANNELS,
      out_channels=_OUT_CHANNELS)

def cloud_dataset(str_arg):
  """Returns dataset for cloud training.

  Args:
    str_arg: A string of the form 'gcs_dir=<path>, image_pattern=<path>,
      label_pattern=<path>'
  """
  train_transform, val_transform = get_transforms(
      roi_size=_ROI_SIZE, pixdim=_PIX_DIM)
  return dataset_utils.cloud_dataset(
      str_arg=str_arg,
      val_roi_size=_ROI_SIZE,
      train_transform=train_transform,
      val_transform=val_transform,
      in_channels=_IN_CHANNELS,
      out_channels=_OUT_CHANNELS,
      validation_idx=_VALIDATION_INDEX,
      end_idx=_END_INDEX)


class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """

        stack = [] #creating a stack or python list
        closeToOpen = {")":"(", "]":"[", "}":"{"} #creating a hash

        for c in s: # for all the items in the string
            if c in closeToOpen: # is the closign bracket in hash keys
                if stack and stack[-1] == closeToOpen[c]: # is the opening string equals to the appended bracket
                    stack.pop() # take out the opening sting because it matched
                else:
                    return False # otherwise return false because there is no opening bracket
            else:
                stack.append(c) # Append the opening bracket
        return True if not stack else False


import socket
import sys

def checksum(data1,data2):
    #create checksum
    pass

def server(host,port):
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.bind((host,port))
    s.listen(1)
    client,addr = s.accept()
    print("[+]"+str(addr)+" connected")
    data = client.recv(1024)
    length = int(data.decode('utf-8'))
    data = client.recv(length)
    f = open('./recv','wb')
    f.write(data)
    f.close()
    client.close()

def client(host,port,filename):
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((host,port))
    f = open(filename,'rb')
    data = f.read()
    f.close()
    s.send(str(len(data)).encode())
    s.send(data)
    s.close()

if len(sys.argv) < 3:
    exit("Usage: python3 trader.py <option> <ip> <port> [filename]")
if sys.argv[1] == "send" and len(sys.argv) != 5:
    exit("Usage: python3 trader.py send <ip> <port> [filename]")
if sys.argv[1] == "recv" and len(sys.argv) != 4 or not(sys.argv[2].isdigit()):
    exit("Usage: python3 trader.py recv <port> [filename]")

option = sys.argv[1]

if option == "send":
    host = sys.argv[2]
    port = int(sys.argv[3])
    filename = sys.argv[4]
    client(host,port,filename)

elif option == "recv":
    port = int(sys.argv[2])
    server("0.0.0.0",port)

else:
    exit("Nope")


import src.plotting.graph_plotting as pg
from src.preprocessing.network_init import *
from src.preprocessing.network_monitoring import *
from src.preprocessing.network_utils import *
import src.constants as co

from src.recovery_protocols.utils import finder_recovery_path as frp, finder_recovery_path_pick as frpp
from src.recovery_protocols.RecoveryProtocol import RecoveryProtocol

class RecShortestPath(RecoveryProtocol):

    file_name = "STPATH"
    plot_name = "STP"

    mode_path_repairing = co.ProtocolRepairingPath.SHORTEST_MINUS
    mode_path_choosing_repair = co.ProtocolPickingPath.RANDOM
    mode_monitoring = co.ProtocolMonitorPlacement.NONE
    mode_monitoring_type = co.PriorKnowledge.DUNNY_IP

    plot_marker = "v"
    plot_color_curve = 0

    def __init__(self, config):
        super().__init__(config)

    def run(self):
        stats_list = []

        # read graph and print stats
        G, elements_val_id, elements_id_val = init_graph(co.PATH_TO_GRAPH, self.config.graph_path, self.config.supply_capacity, self.config)
        print_graph_info(G)

        # normalize coordinates and break components
        dim_ratio = scale_coordinates(G)

        distribution, broken_nodes, broken_edges, perc_broken_elements = destroy(G, self.config.destruction_type, self.config.destruction_precision, dim_ratio,
                                                                                self.config.destruction_width, self.config.n_destruction, self.config.graph_dataset, self.config.seed, ratio=self.config.destruction_quantity,
                                                                                config=self.config)

        # add_demand_endpoints
        if self.config.is_demand_clique:
            add_demand_clique(G, self.config)
        else:
            add_demand_pairs(G, self.config.n_edges_demand, self.config.demand_capacity, self.config)

        pg.plot(G, self.config.graph_path, distribution, self.config.destruction_precision, dim_ratio,
                self.config.destruction_show_plot, self.config.destruction_save_plot, self.config.seed, "TRU", co.PlotType.TRU, self.config.destruction_quantity)

        # hypothetical routability
        if not is_feasible(G, is_fake_fixed=True):
            print("This instance is not solvable. Check the number of demand edges, theirs and supply links capacity.\n\n\n")
            return

        # repair demand edges
        demand_node = get_demand_nodes(G)
        for dn in demand_node:
            do_repair_node(G, dn)
            # INITIAL NODES repairs are not counted in the stats

        iter = 0
        # true ruotability

        routed_flow = 0
        packet_monitor = 0
        monitors_stats = set()
        demands_sat = {d: [] for d in get_demand_edges(G, is_capacity=False)}  # d1: [0, 1, 1, 0, 10] // demands_sat[d].append(0)

        # start of the protocol
        while len(get_demand_edges(G, is_check_unsatisfied=True)) > 0:
            # go on if there are demand edges to satisfy, and still is_feasible
            # demand_edges_routed_flow_pp = defaultdict(int)  # (d_edge): flow

            print("\n\n", "#" * 40, "BEGIN ITERATION", "#" * 40)

            # check if the graph is still routbale on tot graph,
            if not is_feasible(G, is_fake_fixed=True):
                print("This instance is no more routable!")
                return stats_list

            iter += 1
            print("ITER", iter)

            # packet_monitor -- monitors paced up to iteration i
            # monitors -- monitors placed up to now (no duplicates)
            stats = {"iter": iter,
                     "node": [],
                     "edge": [],
                     "flow": 0,
                     "monitors": monitors_stats,
                     "packet_monitoring": packet_monitor,
                     "demands_sat": demands_sat}

            # -------------- 0. Monitor placement --------------
            # -------------- 1. Tomography, Pruning, Probability --------------
            monitoring = dummy_pruning(G)
            stats_packet_monitoring, demand_edges_to_repair, demand_edges_routed_flow, demand_edges_routed_flow_pp = monitoring

            routed_flow += sum(demand_edges_routed_flow)
            stats["flow"] = routed_flow

            packet_monitor += stats_packet_monitoring
            stats["packet_monitoring"] = packet_monitor

            for ke in demands_sat:  # every demand edge
                is_new_routing = sum(stats["demands_sat"][ke]) == 0 and is_demand_edge_saturated(G, ke[0], ke[1])  # already routed
                flow = self.config.demand_capacity if is_new_routing else 0
                stats["demands_sat"][ke].append(flow)

            demand_edges = get_demand_edges(G, is_check_unsatisfied=True, is_residual=True)
            print("> Residual demand edges", len(demand_edges), demand_edges)

            if len(demand_edges) > 0:

                # -------------- 2. Repairing --------------
                paths_proposed = frp.find_paths_to_repair(self.config.repairing_mode, G, demand_edges_to_repair, get_supply_max_capacity(self.config), is_oracle=self.config.is_oracle_baseline)
                path_to_fix = frpp.find_path_picker(self.config.picking_mode, G, paths_proposed, self.config.repairing_mode, self.config,
                                                    is_oracle=self.config.is_oracle_baseline)

                if path_to_fix is None:
                    stats_list.append(stats)
                    print(stats)
                    return stats_list

                # if the protocol SHORTEST_MINUS proposes a 0 capacity edge
                if get_path_residual_capacity(G, path_to_fix) == 0:
                    self.cancel_demand_edge(G, path_to_fix)

                fixed_nodes, fixed_edges = do_fix_path(G, path_to_fix)
                stats["node"] += fixed_nodes
                stats["edge"] += fixed_edges

            stats_list.append(stats)
            print(stats)
        return stats_list

    @staticmethod
    def cancel_demand_edge(G, path_to_fix):
        print("Path with capacity 0, happened", path_to_fix)
        dd1, dd2 = make_existing_edge(path_to_fix[0], path_to_fix[-1])
        G.edges[dd1, dd2, co.EdgeType.DEMAND.value][co.ElemAttr.RESIDUAL_CAPACITY.value] = 0


from nlp.Line import Line
from nltk import pos_tag, word_tokenize

def tag_line(line: Line):
    tokenized = word_tokenize(line.get_processed_string())
    tags = pos_tag(tokenized)
    if len(tags) != line.get_unshortened_size():
        raise RuntimeError('Tagger returned wrong number of tags.')

    word_shift = 0
    tag_shift = 0
    while word_shift != line.original_size:
        if line.words[word_shift].unshortened_size > 1:
            line.words[word_shift].penn_pos_tag = 'N'
            tag_shift += line.words[word_shift].unshortened_size
            word_shift += 1
        else:
            line.words[word_shift].penn_pos_tag = tags[tag_shift][1]
            tag_shift += 1
            word_shift += 1

    if word_shift != line.original_size:
        raise RuntimeError('Not all tags are set.')

    return line


import azure.cosmos.documents as documents
import azure.cosmos.cosmos_client as cosmos_client
import azure.cosmos.exceptions as exceptions
from azure.cosmos.partition_key import PartitionKey
import datetime
import logging
import os

def get_epic_order(patient, partition_key):
    """
    Formats the item to save (appends partition key)
    """
    patient['DOB'] = ''
    order1 = {
            'id' : datetime.datetime.now().strftime('%c'),
            'partitionKey' : partition_key,
            'orderid' : 'None',
            'order_date' : datetime.datetime.now().strftime('%c'),
            'patient': patient
            }
    logging.info(f"order1: {order1} End order1")
    return order1

def create_item(container, patient, partition_key):
    """
    Given a container, a patient dictionary, and a partion key, creates the
    item
    Args:
        container: instantiated from cosmoswrite
        patient: dictionary of data to save
        partition_key: string to identify the model that this inference relates
            to
    """
    epic_patient = get_epic_order(patient, partition_key)
    container.create_item(body=epic_patient)

def cosmoswrite(patient, container_id, partition_key):
    """
    Base funtion to call that enables us to write an inference packet
    to cosmos.
    Args:
        patient: a dictionary of items to write to cosmos
        container_id: cosmos container, typically unique to a cohort
        partition_key: a string indicating partition to write to. Partition key
        is unique to a task (perhaps multiple tasks per cohort)
    """
    client = cosmos_client.CosmosClient(
        os.environ['COSMOS_HOST'],
        os.environ['COSMOS_KEY']
    )

    # setup database for this sample
    try:
        db = client.create_database(id=os.environ['COSMOS_DB_ID'])
        print('Database with id \'{0}\' created'.format(os.environ['COSMOS_DB_ID']))

    except exceptions.CosmosResourceExistsError:
        db = client.get_database_client(os.environ['COSMOS_DB_ID'])
        print('Database with id \'{0}\' was found'.format(os.environ['COSMOS_DB_ID']))

    # setup container for this sample
    try:
        container = db.create_container(id=container_id,
            partition_key=PartitionKey(path='/partitionKey'))
        print('Container with id \'{0}\' created'.format(container_id))

    except exceptions.CosmosResourceExistsError:
        container = db.get_container_client(container_id)
        print('Container with id \'{0}\' was found'.format(container_id))

    create_item(container, patient, partition_key)


#!/usr/bin/env python

import openturns as ot
import otrobopt

# ot.Log.Show(ot.Log.Info)

# This is calligraphic J, the non-robust objective function
calJ = ot.SymbolicFunction(
    ['x1', 'x2'], ['15.0 * (x1^2 + x2^2) - 100.0 * exp(-5. * ((x1 + 1.6)^2+(x2 + 1.6)^2))'])

# This is calligraphic G, the non-robust inequality constraints function
calG = ot.SymbolicFunction(
    ['x1', 'x2'], ['(x1 - 0.5)^2 + x2^2 - 4.0', '(x1 + 0.5)^2 + x2^2 - 4.0'])

# This is the perturbation function
noise = ot.SymbolicFunction(
    ['x1', 'x2', 'xi1', 'xi2'], ['x1 + xi1', 'x2 + xi2'])

# This is capital J: J(x,xi) = calJ(x+xi), the parametric objective function
JFull = ot.ComposedFunction(calJ, noise)
J = ot.ParametricFunction(JFull, [2, 3], [0.0] * 2)

# This is g, the parametric constraints
gFull = ot.ComposedFunction(calG, noise)
g = ot.ParametricFunction(gFull, [2, 3], [0.0] * 2)

bounds = ot.Interval([-3.0] * 2, [3.0] * 2)
solver = ot.NLopt('LD_SLSQP')
solver.setMaximumIterationNumber(100)

for sigma_xi in [0.1, 0.2, 0.3, 0.4, 0.5]:

    thetaDist = ot.Normal([0.0] * 2, [sigma_xi] * 2, ot.IdentityMatrix(2))
    robustnessMeasure = otrobopt.MeanMeasure(J, thetaDist)
    reliabilityMeasure = otrobopt.JointChanceMeasure(
        g, thetaDist, ot.Less(), 0.9)
    problem = otrobopt.RobustOptimizationProblem(
        robustnessMeasure, reliabilityMeasure)
    problem.setBounds(bounds)

    algo = otrobopt.SequentialMonteCarloRobustAlgorithm(problem, solver)
    algo.setMaximumIterationNumber(11)
    algo.setMaximumAbsoluteError(1e-6)
    algo.setInitialSamplingSize(2)  # size of initial xsi discretization
    algo.setSamplingSizeIncrement(
        ot.PythonFunction(1, 1, lambda x: [1.0 * x[0]]))
    algo.setInitialSearch(
        1000)  # number of multi-start tries, uniform law using bounds
    algo.run()
    result = algo.getResult()
    print('x*=', result.getOptimalPoint(), 'J(x*)=',
          result.getOptimalValue(), 'iteration=', result.getIterationNumber())
    assert len(algo.getInitialStartingPoints()) == 1000
    assert len(algo.getResultCollection()) > 10


# Import the libraries
import dlib
import cv2

# Obtaining the image by opencv function and resizing it for the sake of the algorithm then turning it from RGB into grayscale
image1 = cv2.imread("C:/Users/reibo/OneDrive/Dokumenti/dokumenti za faks/year 3/smile detection/group photos/image4.jpg")
image1 = cv2.resize(image1, None, fx=0.50, fy=0.50)
image1_gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)

# The face classifier
face_detector = dlib.get_frontal_face_detector()

# Detect faces
detections = face_detector(image1, 1)
image = image1.copy()

# Draw rectangles on each face
for (i, rect) in enumerate(detections):
    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# Show the image
cv2.imshow("Image", image)


from ecmwfapi import ECMWFDataServer
import sys, os
import argparse
import datetime as dt
import configparser
import numpy as np

'''
Program that retrieves forecast fields from a single initialization time from the
TIGGE database.

From command line:

python run_AR_sens.py -init yyyymmddhh --param paramfile

where:

  -init is the initialization date in yyyymmddhh format
  -storm is TC name, where XXXXXXXNNB, where XXXXXXXX is the name, NN is the number, B is the basin (optional)
  -param is the parameter file path (optional, otherwise goes to default values in example.parm)
'''

#  Read the initialization time and storm from the command line
exp_parser = argparse.ArgumentParser()
exp_parser.add_argument('--init',  action='store', type=str, required=True)
exp_parser.add_argument('--storm', action='store', type=str)
exp_parser.add_argument('--param', action='store', type=str)

args = exp_parser.parse_args()

yyyymmddhh = args.init

#  Read the parameter file
if args.param:
   paramfile = args.param
else:
   paramfile = 'example.parm'

confin = configparser.ConfigParser()
confin.read(paramfile)

config = {}
config.update(confin['model'])
config.update(confin['locations'])

#  Modify work and output directory for specific case/time
if args.storm:
  storm = args.storm
  config['work_dir']   = '{0}/{1}.{2}'.format(config['work_dir'],yyyymmddhh,storm)
else:
  config['work_dir']   = '{0}/{1}'.format(config['work_dir'],yyyymmddhh)

#  Create appropriate directories
if not os.path.isdir(config['work_dir']):
   try:
      os.makedirs(config['work_dir'])
   except OSError as e:
      raise e

#  Set the TIGGE read command values
if not config['tigge_forecast_time']:
   raise "tigge_forecast_time is missing"

daystr = yyyymmddhh[0:4] + '-' + yyyymmddhh[4:6] + '-' + yyyymmddhh[6:8]
hhstr  = yyyymmddhh[8:10] + ":00:00"

if config['model_src'] == 'ECMWF':
  model_str = "ecmf"
  model_num = "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42/43/44/45/46/47/48/49/50"
elif config['model_src'] == 'GEFS':
  model_str = "kwbc"
  model_num = "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30"
#  model_num = "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20"

atmres = config.get('tigge_forecast_grid_space','1.0/1.0')
sfcres = "0.25/0.25"

os.chdir(config['work_dir'])

server = ECMWFDataServer()

#  Retrieve pressure level data
server.retrieve({
    'origin'    : model_str,
    'levelist'  : "200/250/300/500/700/850/925/1000",
    'levtype'   : "pl",
    'expver'    : "prod",
    'parameter' : "130/131/132/133/156",
    'number'    : model_num,
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "pf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_pl_pf.grib"
})

server.retrieve({
    'origin'    : model_str,
    'levelist'  : "200/250/300/500/700/850/925/1000",
    'levtype'   : "pl",
    'expver'    : "prod",
    'parameter' : "130/131/132/133/156",
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "cf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_pl_cf.grib"
})

'''
#  Retrieve PV level data
server.retrieve({
    'origin'    : model_str,
    'levtype'   : "pv",
    'levelist'  : "2",
    'expver'    : "prod",
    'parameter' : "3/131/132",
    'number'    : model_num,
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "pf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_pv_pf.grib"
})

server.retrieve({
    'origin'    : model_str,
    'levtype'   : "pv",
    'levelist'  : "2",
    'expver'    : "prod",
    'parameter' : "3/131/132",
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "cf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_pv_cf.grib"
})

'''

#  Retrieve surface data
server.retrieve({
    'origin'    : model_str,
    'levtype'   : "sfc",
    'expver'    : "prod",
    'parameter' : "59/136/151/167/168",
    'number'    : model_num,
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "pf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_sfc_pf.grib"
})

server.retrieve({
    'origin'    : model_str,
    'levtype'   : "sfc",
    'expver'    : "prod",
    'parameter' : "59/136/151/167/168",
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : atmres,
    'time'      : hhstr,
    'type'      : "cf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_sfc_cf.grib"
})

#  Retrieve higher-resolution surface fields
server.retrieve({
    'origin'    : model_str,
    'levtype'   : "sfc",
    'expver'    : "prod",
    'parameter' : "165/166/228",
    'number'    : model_num,
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : sfcres,
    'time'      : hhstr,
    'type'      : "pf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_hrsfc_pf.grib"
})

server.retrieve({
    'origin'    : model_str,
    'levtype'   : "sfc",
    'expver'    : "prod",
    'parameter' : "165/166/228",
    'dataset'   : "tigge",
    'step'      : config['tigge_forecast_time'],
    'grid'      : sfcres,
    'time'      : hhstr,
    'type'      : "cf",
    'date'      : daystr,
    'class'     : "ti",
    'target'    : "tigge_output_hrsfc_cf.grib"
})

ftype = ("pl", "sfc", "hrsfc")

for i in range(len(ftype)):
   os.system("wgrib2 -s tigge_output_{0}_pf.grib >& grib_{0}_pf.out".format(ftype[i]))
   os.system("wgrib2 -s tigge_output_{0}_cf.grib >& grib_{0}_cf.out".format(ftype[i]))

hlist = config['tigge_forecast_time'].split("/")

init   = dt.datetime.strptime(yyyymmddhh, '%Y%m%d%H')
init_s = init.strftime("%m%d%H%M")

#  Loop over all times, create one file per time
for t in range(len(hlist)):

  datef   = init + dt.timedelta(hours=int(hlist[t]))
  datef_s = datef.strftime("%m%d%H%M")

  if int(hlist[t]) == 0:
     timestr = ":anl:"
  else:
     timestr = ":{0} hour fcst:".format(hlist[t])
  hhh = '%0.3i' % int(hlist[t])

  if np.remainder(int(hlist[t]),24) == 0:
     pcpstr = ":0-{0} day acc fcst:".format(round(float(hlist[t]) / 24.))
  else:
     pcpstr = ":0-{0} hour acc fcst:".format(hlist[t])

  if os.path.isfile("f{0}_fields.grb".format(hhh)):
     os.remove("f{0}_fields.grb".format(hhh))

  print(hlist[t],hhh,timestr,pcpstr)

  gribout = 'E1E{0}{1}1'.format(str(init_s), str(datef_s))

  for i in range(len(ftype)):
     os.system("cat grib_{0}_cf.out | grep \"{1}\" | wgrib2 -fix_ncep -i -append tigge_output_{0}_cf.grib \
                   -grib {2} >& /dev/null".format(ftype[i],timestr,gribout))
     os.system("cat grib_{0}_pf.out | grep \"{1}\" | wgrib2 -fix_ncep -i -append tigge_output_{0}_pf.grib \
                   -grib {2} >& /dev/null".format(ftype[i],timestr,gribout))

  if int(hlist[t]) > 0:
     os.system("cat grib_hrsfc_cf.out | grep \"{0}\" | wgrib2 -fix_ncep -i -append tigge_output_hrsfc_cf.grib \
                   -grib {1} >& /dev/null".format(pcpstr,gribout))
     os.system("cat grib_hrsfc_pf.out | grep \"{0}\" | wgrib2 -fix_ncep -i -append tigge_output_hrsfc_pf.grib \
                   -grib {1} >& /dev/null".format(pcpstr,gribout))

for i in range(len(ftype)):
   os.remove("tigge_output_{0}_pf.grib".format(ftype[i]))
   os.remove("tigge_output_{0}_cf.grib".format(ftype[i]))
   os.remove("grib_{0}_pf.out".format(ftype[i]))
   os.remove("grib_{0}_cf.out".format(ftype[i]))


import PyQt5.QtWidgets as qtWidgets
import PyQt5.QtCore as qtCore
import logging
logger = logging.getLogger(__name__)

SCAN_TYPES = ['All',]

class ScanTypeSelector(qtWidgets.QDialog):
    '''
    Provide a ComboBox to allow switching scan between scan types included
    in the spec file.  An additional item is added at the top to allow selecting
    all types.  This widget was developled to work along with the
    :py:class:`.ScanBrowser`
    '''
    scanTypeChanged = qtCore.pyqtSignal(int, name='scanTypeChanged')

    def __init__(self, parent=None):
        super(ScanTypeSelector, self).__init__(parent)
        logger.debug ("Enter")

        layout = qtWidgets.QHBoxLayout()
        label =qtWidgets.QLabel("Scan Type")
        self.scanTypes = list(SCAN_TYPES)
        self.scanTypeSelection = qtWidgets.QComboBox()
        self.scanTypeSelection.insertItems(0, self.scanTypes)

        layout.addWidget(label)
        layout.addWidget(self.scanTypeSelection)
        self.scanTypeSelection.currentIndexChanged[int] \
            .connect(self.typeSelectionChanged)

        self.setLayout(layout)
        self.show()

    def loadScans(self, scanTypes):
        '''
        Load this module with a list scan types discovered in the spec these
        items, along with \'All\' will be added to the comboBox options
        '''
        self.scanTypeSelection.currentIndexChanged[int] \
            .disconnect(self.typeSelectionChanged)
        self.scanTypeSelection.clear()
        logger.debug("SCAN_TYPES %s" % SCAN_TYPES)
        self.scanTypes = list(SCAN_TYPES)
        self.scanTypes.extend(scanTypes)
        logger.debug("scanTypes %s" % scanTypes)
        logger.debug("self.scanTypes %s" % self.scanTypes)
        self.scanTypeSelection.insertItems(0, self.scanTypes)
        #self.scanTypeSelection.insertItems(1, scanTypes)
        #self.setCurrentType(0)
        self.scanTypeSelection.currentIndexChanged[int] \
            .connect(self.typeSelectionChanged)

    def getTypeNames(self):
        '''
        return a list of types from the widget.
        '''
        typeNames = []
        nameCount = self.scanTypeSelection.count()
        for index in range(nameCount):
            typeNames.append(str(self.scanTypeSelection.itemText(index)))
        return typeNames

    def getTypeIndexFromName(self, typeName):
        '''
        Return an index of for a particular type name
        '''
        names = self.getTypeNames()
        index = names.index(typeName)
        return index

    def getCurrentType(self):
        '''
        return the currently selected type
        '''
        return str(self.scanTypeSelection.currentText())

    def setCurrentType(self, newType):
        '''
        Set the current type programatically
        '''
        self.scanTypeSelection.setCurrentIndex(newType)

    @qtCore.pyqtSlot(int)
    def typeSelectionChanged(self, newType):
        '''
        Send a signal to the rest of the application that the selected type has
        changed.  Applications that want to be notified should look for the
        signal appSelectorName.scanTypeChanged.connect(appHandlerMethod)
        '''
#        self.scanTypeSelection.setCurrentIndex(newType)
        logger.debug("Enter")
        self.scanTypeChanged[int].emit(newType)


import serial
import time

arduino = serial.Serial('COM5', baudrate=9600, timeout = 1.0)
arduino.setDTR(False)
time.sleep(1)
arduino.flushInput()
arduino.setDTR(True)

while True:
	line = arduino.readline()
	line2 = line.decode('ascii', 'strict')
	print(line2)
	#print(line)
	#print(type(line2))


# import imutils
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from matplotlib import pyplot as plt
from collections import Counter

# Here, we use adaptive thresh holding
# change the function : detectSeatStatus , detectAppendSeatStatus
# function doesn't use the  v value( Hsv)
# now we use the threshold arr mean( by using np.arr_sum() )  to know seat status

def main():

    global AVAILABLE, UNAVAILABLE

    AVAILABLE = 0
    UNAVAILABLE = 1

    # read image
    # handle the case, the seat color is darker than isle
    origin_image = cv2.imread("image.png")
    fullImage_height, fullImage_width = origin_image.shape[:2]

    img = cv2.imread("image.png",0)

    # img = cv2.medianBlur(img, 5)

    # ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
    # th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, \
    #                            cv2.THRESH_BINARY, 11, 2)
    th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
                               cv2.THRESH_BINARY, 11, 2)
    # titles = ['Original Image', 'Global Thresholding (v = 127)',
    #           'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
    # images = [img, th1, th2, th3]

    #
    # for i in range(4):
    #     plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    #     plt.title(titles[i])
    #     plt.xticks([]), plt.yticks([])
    # plt.show()
    thresh = th3

    cv2.imwrite("thresh.png",thresh)

    # cv2.imshow("third",thresh)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    # find the contours(lines)
    contours, hierachy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    # img = cv2.imread("image.png")
    img_for_redraw = cv2.imread("image.png")
    # redraw outline by courturs
    # img = cv2.drawContours(img, contours, -1, (0, 0, 0), 3)

    # cv2.imshow("drawContours", img)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    # to redraw
    # get the w mode , h mode ( 최빈값)
    # for generalization
    w_list = []
    h_list = []
    sd = ShapeDetector()

    for c in contours:
        if sd.detect(c) != 'rectangle': next
        x, y, w, h = cv2.boundingRect(c)
        if w < 20 :  # too  small or too big value is not necesarry /
            continue
        if h < 20 :
            continue
        w_list.append(w)
        h_list.append(h)
    #
    # print(w_list)
    # print(len(w_list))
    # print(h_list)
    # print(len(h_list))
    w_mode = modefinder(w_list)
    # print("W mode: %f"% w_mode)
    h_mode = modefinder(h_list)
    # print("H mode : %f "% h_mode)

    # to handle the case that the shape is not closed
    # redraw
    now = 0
    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        if w < (w_mode-15) or w > w_mode + 30:
            continue
        if h < (h_mode - 5 ) or h > h_mode + 30:
            continue
        # redraw
        # img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)  # black color, line wide(굴기) 3
        img_for_redraw = cv2.rectangle(img_for_redraw, (x, y), (x + w, y + h), (0, 255, 0), 3)  # black color, line wide(굴기) 3
        now = now + 1
        # print( " w : %d   h : %d"%(w,h))

        # crop  = img[y: y + h, x: x + w]
        # cv2.imshow("crop", crop)
        # cv2.waitKey()
        # cv2.destroyWindow("crop")

    # print("cnt : %d "%now)

    # cv2.imshow("redraw",img)
    # cv2.imshow("img_for_redraw",img_for_redraw)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    #
    img_redraw = cv2.cvtColor(img_for_redraw, cv2.COLOR_BGR2GRAY)
    thresh_redraw = cv2.adaptiveThreshold(img_redraw, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
                               cv2.THRESH_BINARY, 11, 2)

    # cv2.imwrite("th3.png",thresh_redraw)
    # cv2.imshow("th3",thresh_redraw)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    contours, hierachy = cv2.findContours(thresh_redraw, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    # img = cv2.imread("image.png")
    seat_height = 0
    seat_width = 0

    # read thresh image
    threshForStatus = cv2.imread("thresh.png")

    # cv2.imshow("thresForStatus",threshForStatus)
    # cv2.waitKey()

    # to get mode ( 최빈값)
    # for generalization
    count=0
    w_list = []
    h_list = []
    sd = ShapeDetector()
    for c in contours:
        if sd.detect(c) != 'rectangle': next
        x, y, w, h = cv2.boundingRect(c)
        if w < 20  :
            continue
        if h < 20 :
            continue
        w_list.append(w)
        h_list.append(h)
    #
    # print(w_list)
    # print(len(w_list))
    # print(h_list)
    # print(len(h_list))
    w_mode = modefinder(w_list)
    # print("W mode: %f"% w_mode)
    h_mode = modefinder(h_list)
    # print("H mode : %f "% h_mode)

    xyList =[]
    seatPositions = []
    for c in contours:
        if sd.detect(c) != 'rectangle': next
        x, y, w, h = cv2.boundingRect(c)
        if w < (w_mode-10) or w > w_mode + 10:  # 5 value is the standard to filter a little small rectangle
            # crop = threshForStatus[y: y + h, x: x + w]
            # cv2.imshow("crop", crop)
            # cv2.waitKey()
            # cv2.destroyWindow("crop")
            # print("skp x : %d  y : %d , w : %d,  h: %d" %(x,y,w,h))
            continue
        if h < (h_mode -10) or h > h_mode + 10:
            # crop = threshForStatus[y: y + h, x: x + w]
            # cv2.imshow("crop", crop)
            # cv2.waitKey()
            # cv2.destroyWindow("crop")
            # print("skp x : %d  y : %d , w : %d,  h: %d" %(x,y,w,h))
            continue

        if isAgainDraw(xyList,x,y, w_mode, h_mode):
            # again
            # print("Again  x : %d  y : %d , w : %d,  h: %d" %(x,y,w,h))
            continue;
        else:
            # not again
            xyList.append([x,y])

        # print(" x : %d  y : %d , w : %d,  h: %d" %(x,y,w,h))
        # print(xyList)

        # # redraw
        img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 3)  # black color, line wide(굴기) 3

        # crop  = threshForStatus[y: y + h, x: x + w]
        # cv2.imshow("crop", crop)
        # cv2.waitKey()
        # cv2.destroyWindow("crop")

        if seat_height == 0 : seat_height = h
        if seat_width ==0 : seat_width = w

        # seatPositions.append( [ (y,x) , detectSeatStatus(threshForStatus[y: y + h, x: x + w])] ) # [ 좌표, status ]
        seatPositions.append( [ (y,x) ] ) # [ 좌표, status ]
        count= count+1
    detectAppendSeatStatus(seatPositions,fullImage_height,fullImage_width,seat_height, seat_width)

    # drawSeat(seatPositions, fullImage_height,fullImage_width,seat_height, seat_width)

    return seatPositions, fullImage_height,fullImage_width,seat_height, seat_width

def isAgainDraw( xyList,x,y, W_mode, H_mode):
    if not xyList: # empty case
        return False     # not again draw

    for element in xyList:
        x1 = element[0];
        y1 = element[1];

        if ( ( x > x1 - 10) and ( x < x1 + 10) ) and ( ( y > y1 - 10) and ( y < y1 + 10) ) :
            return True

    return False

def modefinder(numbers): #numbers는 리스트나 튜플 형태의 데이터
    c = Counter(numbers)
    mode = c.most_common(1)

    return mode[0][0]

def drawSeat(seatPosition, fullImage_height, fullImage_width, seat_height, seat_width):

    image = Image.new("RGB", (fullImage_width , fullImage_height), (0,0,0))
    draw = ImageDraw.Draw(image)

    seat_width = seat_width * 0.8
    seat_height = seat_height * 0.8

    # here seatPosition list has the status
    # seatPosition element
    #  two dimension  [ [ ] , [] , [] , ..... [] ]
    #  one dimension  [ (row, col), status ]
    status = 1;

    # to avoid overlay

    for i in range(len(seatPosition)):
        row = int(seatPosition[i][0][0])  # tuple -> int to operand with int
        col = int(seatPosition[i][0][1])

        if seatPosition[i][status] == AVAILABLE:
            draw.rectangle([(col, row), (col + seat_width, row+ seat_height)], (204, 51, 204) )  # (64, 132, 34) : green
            # image.save("drawimage.png")
            # dm = cv2.imread("drawimage.png")
            # cv2.imshow('test',dm)
            # cv2.waitKey()
            # cv2.destroyAllWindows()
        else: # unavailable
            draw.rectangle([(col, row), (col+ seat_width, row + seat_height)], (67, 65, 66) )  # (67, 65, 66) : gray
            # image.save("drawimage.png")
            # dm = cv2.imread("drawimage.png")
            # cv2.imshow('test', dm)
            # cv2.waitKey()
            # cv2.destroyAllWindows()

    filename = "convert.gif"
    image.save(filename)
    image.resize((200, 150)).save("convert_thumbnail.gif")

    return

def detectAppendSeatStatus(seatPosition, fullImage_height, fullImage_width,seat_height, seat_width):

    r =0
    c =1

    origin_image = cv2.imread("image.png")
    thresh = cv2.imread("thresh.png")

    arr_standard = 0;  # seat with icon  value is 15100 , so set the standard 15500
                            # other seat over 160000

    arr_thresh = []
    # f = open("log_arr_standard","w+") # w+  매번 새로 만듦
    for i in range(len(seatPosition)):

        # define ROI of RGB image 'img'
        # '0' mean first element of one dimension
        # that is tuple
        # roi = origin_image[seatPosition[i][0][r]:seatPosition[i][0][r]+seat_height, seatPosition[i][0][c]:seatPosition[i][0][c]+seat_width]
        roi_thresh = thresh[seatPosition[i][0][r]:seatPosition[i][0][r]+seat_height, seatPosition[i][0][c]:seatPosition[i][0][c]+seat_width]

        arr_sum = np.sum(roi_thresh, axis=1).tolist()  ## arr_histogram depending on orientation  row : 1
        arr_thresh.append(arr_sum)

    # print(arr_thresh)
    # print("max 0.9 %d"%(np.max(arr_thresh)*0.9))
    arr_standard = np.max(arr_thresh) * 0.9  # seat with icon value is lower than max * 0.95

    # f.write("max  * 0. 9  standard value %d  \n"%arr_standard  )

    # seat Position element
    #  two dimension  [ [ ] , [] , [] , ..... [] ]
    #  one dimension  [ (row, col) ]
    #  we want to append status in one dimension [ (row, col) , status ]
    #  status mean this is available or not

    cnt_seat = 0
    cnt_unavail = 0
    cnt_avail = 0
    for i in range(len(seatPosition)):
        cnt_seat += 1
        # define ROI of RGB image 'img'
        # '0' mean first element of one dimension
        # that is tuple
        # roi = origin_image[seatPosition[i][0][r]:seatPosition[i][0][r]+seat_height, seatPosition[i][0][c]:seatPosition[i][0][c]+seat_width]
        roi_thresh = thresh[seatPosition[i][0][r]:seatPosition[i][0][r]+seat_height, seatPosition[i][0][c]:seatPosition[i][0][c]+seat_width]

        arr_sum = np.sum(roi_thresh, axis=1).tolist()  ## arr_histogram depending on orientation  row : 1
        arr_mean = np.mean(arr_sum)

        # print("arr_mean %d"%arr_mean)
        # f.write("arr_mean  %d\n"%arr_mean)

        # cv2.imshow("roi",roi_thresh)
        # cv2.waitKey()
        # cv2.destroyAllWindows()

        # if arr_mean  < arr_standard, it's unavailable
        # some icon and letters down the value ( because it's black color )
        if arr_mean < arr_standard:  # seat unavailable
            seatPosition[i].append(UNAVAILABLE)      # [ (row, col), status ]
            cnt_unavail += 1
        else:
            seatPosition[i].append(AVAILABLE)
            cnt_avail += 1

    # f.close()

    # print("cnt_seat : %d , cnt_avail : %d, cnt_unavail : %d"%(cnt_seat,cnt_avail,cnt_unavail))

    return cnt_seat, cnt_avail, cnt_unavail

        # convert it into HSV
        # hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
        # h, s, v = cv2.split(hsv)
        #
        # v_mean = np.mean(v)
        #
        #
        #
        # if v_mean > v_Standard : # seat unavailable
        #     seatPosition[i].append(UNAVAILABLE)      # [ (row, col), status ]
        #     cnt_unavail += 1
        # else:
        #     seatPosition[i].append(AVAILABLE)
        #     cnt_avail += 1

def detectSeatStatus(image):

    # standard value is calculated
    # almost color v value is greater than 100

    arr_standard = 15500;  # seat with icon  value is 15100 , so set the standard 15500
                            # other seat over 160000

    arr_sum = np.sum(image, axis=1).tolist()  ## arr_histogram depending on orientation  row : 1
    arr_mean = np.mean(arr_sum)
    # print(arr_mean)

    # cv2.imshow("roi", image)
    # cv2.waitKey()
    # cv2.destroyAllWindows()

    # if arr_mean  < arr_standard, it's unavailable
    # some icon and letters down the value ( because it's black color )
    if arr_mean < arr_standard:  # seat unavailable
        return UNAVAILABLE
    else:
        return AVAILABLE

    #
    # v_Standard = 100
    # hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    # h, s, v = cv2.split(hsv)
    # v_mean = np.mean(v)
    #
    #
    # if v_mean > v_Standard:  # seat unavailable
    #     return UNAVAILABLE
    # else:
    #     return AVAILABLE

class ShapeDetector:

    def __init__(self):

        pass

    def detect(self, c):

        # initialize the shape name and approximate the contour

        shape = "unidentified"

        peri = cv2.arcLength(c, True)

        approx = cv2.approxPolyDP(c, 0.04 * peri, True)

        # if the shape is a triangle, it will have 3 vertices

        if len(approx) == 3:

            shape = "triangle"

        # if the shape has 4 vertices, it is either a square or

        # a rectangle

        elif len(approx) == 4:

            # compute the bounding box of the contour and use the

            # bounding box to compute the aspect ratio

            (x, y, w, h) = cv2.boundingRect(approx)

            ar = w / float(h)

            # a square will have an aspect ratio that is approximately
            # equal to one, otherwise, the shape is a rectangle
            shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"

        # if the shape is a pentagon, it will have 5 vertices

        elif len(approx) == 5:
            shape = "pentagon"

        # otherwise, we assume the shape is a circle
        else:
            shape = "circle"
        # return the name of the shape
        return shape
# main()