import time
import json
from azure.mgmt.resource import ResourceManagementClient
from devtools_testutils import AzureMgmtTestCase
from azure.mgmt.netapp.models import CapacityPool, CapacityPoolPatch
from test_account import create_account, delete_account
from setup import *
import azure.mgmt.netapp.models

pools = [TEST_POOL_1, TEST_POOL_2]

def create_pool(client, rg=TEST_RG, acc_name=TEST_ACC_1, pool_name=TEST_POOL_1, location=LOCATION, pool_only=False):
    if not pool_only:
        create_account(client, rg, acc_name)

    pool_body = CapacityPool(service_level=SERVICE_LEVEL, size=DEFAULT_SIZE, location=location)
    pool = client.pools.create_or_update(
        pool_body,
        rg,
        acc_name,
        pool_name,
        {'location': location}
    ).result()

    return pool

def wait_for_no_pool(client, rg, acc_name, pool_name, live=False):
    # a workaround for the async nature of certain ARM processes
    co=0
    while co<5:
        co += 1
        if live:
            time.sleep(10)
        try:
            pool = client.pools.get(rg, acc_name, pool_name)
        except:
            # not found is an exception case (status code 200 expected)
            # and is actually what we are waiting for
            break

def delete_pool(client, rg, acc_name, pool_name, live=False):
    # nest resources seem to hang around for a little while even
    # when apparently deleted, therefore give it a chance
    co=0
    while co<5:
        co += 1
        if live:
            time.sleep(10)
        try:
            client.pools.delete(rg, acc_name, pool_name).wait()
        except:
            # Want to catch specifically "Can not delete resource before nested resources are deleted."
            # but should be safe to generalise
            break
    wait_for_no_pool(client, rg, acc_name, pool_name, live)

class NetAppAccountTestCase(AzureMgmtTestCase):
    def setUp(self):
        super(NetAppAccountTestCase, self).setUp()
        self.client = self.create_mgmt_client(azure.mgmt.netapp.AzureNetAppFilesManagementClient)

    def test_create_delete_pool(self):
        pool = create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, LOCATION)
        self.assertEqual(pool.size, DEFAULT_SIZE)
        self.assertEqual(pool.name, TEST_ACC_1 + '/' + TEST_POOL_1)

        pool_list = self.client.pools.list(TEST_RG, TEST_ACC_1)
        self.assertEqual(len(list(pool_list)), 1)

        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_1).wait()
        pool_list = self.client.pools.list(TEST_RG, TEST_ACC_1)
        self.assertEqual(len(list(pool_list)), 0)

        wait_for_no_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, live=self.is_live)
        delete_account(self.client, TEST_RG, TEST_ACC_1, live=self.is_live)

    def test_list_pools(self):
        pool = create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, LOCATION)
        pool = create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_2, LOCATION, pool_only=True)

        pool_list = self.client.pools.list(TEST_RG, TEST_ACC_1)
        self.assertEqual(len(list(pool_list)), 2)
        idx = 0
        for pool in pool_list:
            self.assertEqual(pool.name, pools[idx])
            idx += 1

        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_1).wait()
        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_2).wait()
        for pool in pools:
            wait_for_no_pool(self.client, TEST_RG, TEST_ACC_1, pools[idx], live=self.is_live)
        delete_account(self.client, TEST_RG, TEST_ACC_1, live=self.is_live)

    def test_get_pool_by_name(self):
        pool = create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, LOCATION)

        pool = self.client.pools.get(TEST_RG, TEST_ACC_1, TEST_POOL_1)
        self.assertEqual(pool.name, TEST_ACC_1 + '/' + TEST_POOL_1)

        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_1).wait()
        wait_for_no_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, live=self.is_live)
        delete_account(self.client, TEST_RG, TEST_ACC_1, live=self.is_live)

    def test_update_pool(self):
        pool = create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1)
        self.assertEqual(pool.service_level, "Premium")

        pool_body = CapacityPool(service_level="Standard", size=DEFAULT_SIZE, location=LOCATION)
        pool = self.client.pools.create_or_update(
            pool_body,
            TEST_RG,
            TEST_ACC_1,
            TEST_POOL_1,
            {'location': LOCATION}
        ).result()
        self.assertEqual(pool.service_level, "Standard")

        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_1).wait()
        wait_for_no_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, live=self.is_live)
        delete_account(self.client, TEST_RG, TEST_ACC_1, live=self.is_live)

    def test_patch_pool(self):
        create_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1)

        tag = {'Tag2': 'Value1'}
        capacity_pool_patch = CapacityPoolPatch(service_level="Standard", tags=tag)

        pool = self.client.pools.update(capacity_pool_patch, TEST_RG, TEST_ACC_1, TEST_POOL_1)
        self.assertEqual(pool.service_level, "Standard")
        self.assertTrue(pool.tags['Tag2'] == 'Value1')

        self.client.pools.delete(TEST_RG, TEST_ACC_1, TEST_POOL_1).wait()
        wait_for_no_pool(self.client, TEST_RG, TEST_ACC_1, TEST_POOL_1, live=self.is_live)
        delete_account(self.client, TEST_RG, TEST_ACC_1, live=self.is_live)


import os
import mimetypes
from uuid import uuid4
import logging

import pandas as pd
from django.core.paginator import Paginator
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.conf import settings
from django.http.response import HttpResponseRedirect
from django.http.response import HttpResponse
from django.views.generic import CreateView
from django.views.generic import DetailView
from django.views.generic import UpdateView
from django.views.generic import View
from django.shortcuts import reverse
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from django.utils.timezone import datetime
from django.utils import timezone
from celery.schedules import timedelta

from apps.users.mixins import IsResetPasswordMixin

from apps.subscribe_pages.mixins import IsSubscribePageActive
from apps.subscribe_pages.mixins import IsSubscribePageOwner
from apps.subscribe_pages.mixins import AjaxMixin
from apps.subscribe_pages.mixins import DeleteAjaxMixin
from apps.subscribe_pages.views import SubscribePageListMixin
from apps.subscribe_pages.models import BGColor
from apps.subscribe_pages.models import Domain

from .models import TelegramSubscribePage
from .models import TelegramGroupOfSubscribePage
from .models import TelegramStatistic
from .models import TelegramSubscriber

from . import forms

logger_page = logging.getLogger('page')

class TGSubscribePageOpenView(IsSubscribePageActive, DetailView):
    model = TelegramSubscribePage
    queryset = TelegramSubscribePage.objects.filter(created=True)
    template_name = 'subscribe_pages/tg-page-open.html'
    context_object_name = 'page'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['bg_color'] = self.object.bg_color
        context['page_photo'] = self.object.get_page_photo_url()
        context['instagram_avatar'] = self.object.get_instagram_avatar_url()
        return context

    def get(self, request, *args, **kwargs):
        if not self.object:
            self.object = self.get_object()
        try:
            subscriber = TelegramSubscriber.get_or_create_by_user_ip(
                request)

            statistic, statistic_created = TelegramStatistic.objects.get_or_create(
                        telegram_subscribe_page=self.object, day=datetime.today())

            if not subscriber.is_visited_page_by_slug(self.object.slug):  # Если он не был на этой странице то
                try:
                    # получаем/создаём статистику сегодняшнего дня
                    statistic, statistic_created = TelegramStatistic.objects.get_or_create(
                        telegram_subscribe_page=self.object, day=datetime.today())

                except TelegramStatistic.MultipleObjectsReturned:
                    statistics = TelegramStatistic.objects.filter(
                        telegram_subscribe_page=self.object, day=datetime.today())
                    statistic = statistics[0]
                    for statistic_ in statistics[1:]:
                        statistic.views += statistic_.views
                        statistic_.delete()

                statistic.views += 1
                statistic.save(update_fields=['views'])
                subscriber.views.add(self.object)  # добавляем страницу в просмотренные
        except Exception as e:
            logger_page.warning(
                f'\n{timezone.now().strftime("%Y-%m-%d %H:%M:%S")}: '
                f'error: {e}, '
                f'slug: {self.object.slug}, '
                f'ip: {request.META}')

        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

class TGSubscribePageDetailView(LoginRequiredMixin, IsResetPasswordMixin,
                              IsSubscribePageOwner, UpdateView):
    model = TelegramSubscribePage
    form_class = forms.TGSubscribePageUpdateForm
    template_name = 'subscribe_pages/tg-page-detail.html'
    success_url = reverse_lazy('tg-page-list')

    def get_queryset(self):
        if self.request.user.is_staff:
            queryset = self.model.objects.all()
        else:
            queryset = self.model.objects.filter(user=self.request.user)
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        if not self.object:
            self.object = self.get_object()

        context['domain'] = self.object.domain
        context['domains'] = Domain.objects.filter(
            user=self.request.user)

        context['bg_color'] = self.object.bg_color
        context['bg_colors'] = BGColor.objects.filter(is_active=True)

        context['page_photo'] = f'https://{self.object.get_page_photo_url()}'
        context['instagram_avatar'] = self.object.get_instagram_avatar_url()
        context['instagram_username'] = self.object.instagram_username
        context['follower_count'] = 1000

        return context

    def form_valid(self, form):
        self.object = form.save()
        return super().form_valid(form)

class TGAddToFolderView(LoginRequiredMixin, AjaxMixin, View):
    def post(self, request, *args, **kwargs):
        response = self.get_ajax_response()
        data = request.POST
        page = TelegramSubscribePage.objects.get(
            slug=data['slug'], user=request.user
        )
        group = TelegramGroupOfSubscribePage.objects.get(
            user=request.user, id=int(data['group_id'])
        )
        page.group = group
        page.save()
        response['status'] = 'SUCCESS'
        response['url'] = '/tg-subscribe-pages/%s/' % group.name

        return self.ajax_response(response)

class TGSubscribePageDeleteView(LoginRequiredMixin, IsResetPasswordMixin,
                              DeleteAjaxMixin):
    model = TelegramSubscribePage
    id_field_name = 'pageID'
    is_owner = True

class TGFolderCreateView(LoginRequiredMixin, IsResetPasswordMixin, CreateView):
    model = TelegramGroupOfSubscribePage
    form_class = forms.TGGroupCreateForm
    template_name = 'subscribe_pages/tg-page-list.html'
    http_method_names = ['post']

    def get_success_url(self):
        return reverse_lazy('tg-page-list',
                            args=(self.object.name,))

    def form_invalid(self, form):
        messages.error(
            self.request, 'Название папки содержит запрещенные символы'
        )
        return HttpResponseRedirect(reverse_lazy('tg-page-list'))

    def post(self, request, *args, **kwargs):
        self.object = None
        form = self.get_form()
        if form.is_valid():
            f = form.save(commit=False)
            f.user = request.user
            return self.form_valid(form)
        return self.form_invalid(form)

class TGFolderDeleteAjaxView(LoginRequiredMixin, IsResetPasswordMixin, DeleteAjaxMixin):
    model = TelegramGroupOfSubscribePage
    id_field_name = 'folderID'
    is_owner = True

    def delete(self, request, *args, **kwargs):
        response = self.get_ajax_response()
        data = request.POST
        object_id = int(data.get(self.id_field_name, 0))

        self.object = self.get_object(object_id)
        if self.object:
            for subscribe_page in self.object.tg_subscribe_pages.all():
                subscribe_page.set_default_group()
            if self.object.can_delete:
                self.object.delete()
                response['status'] = 'SUCCESS'
            else:
                response['status'] = 'ERROR'
                response['reason'] = 'FOLDER_CAN_NOT_BE_DELETED'
        else:
            response['status'] = 'ERROR'
            response['reason'] = 'OBJECT_NOT_FOUND'
        return self.ajax_response(response)

class TGFolderRenameView(LoginRequiredMixin, IsResetPasswordMixin, UpdateView):
    model = TelegramGroupOfSubscribePage
    form_class = forms.TGGroupRenameForm
    template_name = 'subscribe_pages/tg-page-list.html'
    http_method_names = ['get', 'post']

    def get_object(self, object_id: int):
        query_kwargs = {'id': int(object_id), 'user': self.request.user}

        try:
            obj = self.model.objects.get(**query_kwargs)
        except self.model.DoesNotExist:
            obj = None
        return obj

    def get(self, request, *args, **kwargs):
        return HttpResponseRedirect(reverse_lazy('tg-page-list'))

    def post(self, request, *args, **kwargs):
        data = request.POST

        object_id = int(data.get('id', 0))
        self.object = self.get_object(object_id)
        object_name = data.get('name', self.object.name)

        if not self.object.can_delete:
            messages.error(self.request, 'Эту папку переименовать нельзя!')
            return HttpResponseRedirect(
                reverse_lazy('tg-page-list', args=(object_name,)))

        if self.object:
            self.object.name = object_name
            self.object.save(update_fields=['name'])
        else:
            messages.error(self.request, 'Папка не найдена!')
        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        return self.request.path

class TGSubscribePageListView(SubscribePageListMixin):
    model = TelegramGroupOfSubscribePage
    form_class = forms.AddToTelegramFolderForm
    template_name = 'subscribe_pages/tg-page-list.html'

    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()

        group_name = kwargs.get('name', 'Неотсортированные')
        group = self.get_group(group_name)
        if group_name == 'Неотсортированные' and not group:
            group = self.model.objects.create(
                user=request.user,
                name='Неотсортированные',
                can_delete=False
            )
        if group_name == 'Неотсортированные' \
                and not group.tg_subscribe_pages.all() \
                and request.user.tg_group_of_pages.count() > 1:

            for page in request.user.tg_subscribe_pages.all():
                page.group = group
                page.save(update_fields=['group'])

        if not group:
            return HttpResponseRedirect(
                reverse_lazy('tg-page-list'))

        context = self.get_context_data(group=group)

        return self.render_to_response(context)

    def get_context_data(self, *, object_list=None, **kwargs):
        group = kwargs.get('group')
        print(group.tg_subscribe_pages)

        count_of_groups = str(self.object_list.count())
        count_of_pages = str(group.tg_subscribe_pages.count())

        context = super().get_context_data(object_list=object_list, **kwargs)

        context['groups_count'] = count_of_groups + (
            ' папка' if count_of_groups == '1' else ' папок')
        context['pages_count'] = count_of_pages + (
            ' страница' if count_of_pages == '1' else ' страниц')
        context['selected_folder_name'] = group.name
        context['TELEPORT_TG_BOT_URL'] = settings.TELEPORT_TG_BOT_URL
        context['subscribe_pages'] = group.tg_subscribe_pages.all().order_by(
            '-id')
        context['form'] = self.get_form()

        return context

class TGSubscribePageDuplicateView(LoginRequiredMixin, IsResetPasswordMixin,
                                 IsSubscribePageOwner, CreateView):
    model = TelegramSubscribePage
    queryset = TelegramSubscribePage.objects.filter(created=True)
    form_class = forms.TGSubscribePageDuplicateForm
    template_name = 'subscribe_pages/tg-page-duplicate.html'

    def get_queryset(self):
        return self.model.objects.filter(user=self.request.user)

    def get_success_url(self):
        self.success_url = reverse('tg-page-detail',
                                   args=[self.object.slug])
        return str(self.success_url)

    def form_valid(self, form):
        self.object = form.save()
        return super().form_valid(form)

    def get(self, request, *args, **kwargs):
        page = get_object_or_404(TelegramSubscribePage,
                                 user=request.user, slug=kwargs.get('slug'))
        self.object = page
        self.object.slug = TelegramSubscribePage.slug_generate(
            request.user)
        return self.render_to_response(self.get_context_data())

    def get_context_data(self, **kwargs):
        """Insert the form into the context dict."""
        context = super().get_context_data(**kwargs)
        if self.object:
            context['domain'] = self.object.domain

        context['instagram_avatar'] = self.object.get_instagram_avatar_url()
        context['domains'] = Domain.objects.filter(
            user=self.request.user)
        return context

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        self.object = self.get_object()

        if form.is_valid(request.user):
            page_name = form.cleaned_data['page_name'].lower()

            self.object = get_object_or_404(TelegramSubscribePage,
                                            user=request.user,
                                            slug=kwargs.get('slug'))

            # SubscribePage create
            f = form.save(commit=False)
            f.user = request.user
            f.slug = f.slug.lower()

            # copy
            f.page_name = page_name
            f.page_hash = TelegramSubscribePage.generate_page_hash(f.slug)
            f.page_photo = self.object.page_photo
            f.bg_color = self.object.bg_color
            f.description = self.object.description

            f.facebook_pixel = self.object.facebook_pixel
            f.tiktok_pixel = self.object.tiktok_pixel
            f.yandex_pixel = self.object.yandex_pixel

            if not f.instagram_avatar:
                f.instagram_avatar = self.object.instagram_avatar

            f.timer_text = self.object.timer_text
            f.is_timer_active = self.object.is_timer_active
            f.timer_time = self.object.timer_time

            f.presubscribe_text = self.object.presubscribe_text
            f.message_after_getting_present = self.object.message_after_getting_present

            f.show_subscribers = self.object.show_subscribers

            f.popup_title = self.object.popup_title
            f.popup_button_text = self.object.popup_button_text
            f.button_text = self.object.button_text
            f.button_url = self.object.button_url

            f.created = self.object.created

            return self.form_valid(form)
        else:
            return self.form_invalid(form)

class TGStatisticSubscribePageDownloadSubscribers(LoginRequiredMixin, IsResetPasswordMixin, IsSubscribePageOwner, IsSubscribePageActive, DetailView):
    model = TelegramSubscribePage
    template_name = 'subscribe_pages/tg-page-statistic.html'

    def get(self, request, *args, **kwargs):
        self.object: TelegramSubscribePage = self.get_object()
        TelegramSubscribePage.objects.filter()
        subscribers = {
            'username': [],
            'subscribed': []
        }

        for subscriber in self.object.subscribed_tg_users.all():
            if subscriber.username:
                subscribers['username'].append(subscriber.username)
                subscribers['subscribed'].append(
                    '+' if self.object in subscriber.subscribe_to.all() else '-'
                )

        excel_file_path = f'media/excels/{request.user.id}'
        if not os.path.exists(excel_file_path):
            os.makedirs(excel_file_path, exist_ok=True)
        excel_file_name = excel_file_path + f'{uuid4()}.xlsx'

        df = pd.DataFrame(subscribers)
        df.to_excel(excel_file_name, )

        with open(excel_file_name, 'rb') as f:
            response = HttpResponse(f.read())

        file_type = mimetypes.guess_type(
            excel_file_name) or 'application/octet-stream'
        response['Content-Type'] = file_type
        response['Content-Length'] = str(os.stat(excel_file_name).st_size)
        response[
            'Content-Disposition'] = "attachment; filename=subscribers.xlsx"
        os.remove(excel_file_name)
        return response

class TGStatisticAjaxView(LoginRequiredMixin, IsResetPasswordMixin, IsSubscribePageOwner, IsSubscribePageActive, DetailView, AjaxMixin):
    model = TelegramSubscribePage
    queryset = TelegramSubscribePage.objects.filter(created=True)
    http_method_names = ['get']

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        response = self.get_ajax_response(views=0, subscribers=0, ctr=0)

        start_date = request.GET.get(
            'start_date',
            datetime.today() - timedelta(days=7)
        )
        end_date = request.GET.get(
            'end_date',
            datetime.today()
        )

        telegram_page_statistic_list = TelegramStatistic.objects.filter(
            telegram_subscribe_page=self.object,
            day__range=[start_date, end_date]).order_by('day')
        for page_statistic in telegram_page_statistic_list:
            response[str(page_statistic.day)] = [
                page_statistic.views,
                page_statistic.subscribers,
                page_statistic.ctr
            ]
            response['views'] += page_statistic.views
            response['subscribers'] += page_statistic.subscribers
        try:
            response['ctr'] = int(
                response['subscribers'] / response['views'] * 100
            )
        except ZeroDivisionError:
            response['ctr'] = 0

        return self.ajax_response(response)

class TGStatisticSubscribePageDetailView(LoginRequiredMixin, IsResetPasswordMixin, IsSubscribePageOwner, IsSubscribePageActive, DetailView):
    model = TelegramSubscribePage
    template_name = 'subscribe_pages/tg-page-statistic.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        page = int(self.request.GET.get('page', 1))

        subscribers = self.object.subscribed_tg_users.all().order_by('-pk')[:100]
        print(self.object.subscribed_tg_users.all())
        paginator = Paginator(subscribers, 10)

        context['subscribers'] = paginator.get_page(page)

        context['pages'] = paginator.page_range
        context['current_page'] = page
        context['prev_page'] = page - 1 if (page - 1) in context[
            'pages'] else page
        context['next_page'] = page + 1 if (page + 1) in context[
            'pages'] else page
        return context

class TGSubscribePageCreateView(LoginRequiredMixin, IsResetPasswordMixin, CreateView):
    model = TelegramSubscribePage
    form_class = forms.TGSubscribePageCreateForm
    template_name = 'subscribe_pages/tg-page-create.html'

    def get_success_url(self):
        self.success_url = reverse('tg-page-list')
        return str(self.success_url)

    def get_initial(self):
        """Return the initial data to use for forms on this view."""
        initial = self.initial.copy()
        initial['slug'] = self.model.slug_generate(self.request.user)
        return initial

    def get_context_data(self, **kwargs):
        """Insert the form into the context dict."""
        context = super().get_context_data(**kwargs)

        context['bg_colors'] = BGColor.objects.filter(is_active=True)

        context['domains'] = Domain.objects.filter(
            user=self.request.user)
        return context

    def form_valid(self, form):
        self.object = form.save()
        return super().form_valid(form)

    def post(self, request, *args, **kwargs):
        self.object = None
        form = self.get_form()
        if form.is_valid():
            f = form.save(commit=False)
            f.user = request.user
            f.page_hash = TelegramSubscribePage.generate_page_hash(f.slug)

            if not f.bg_color:
                f.bg_color = BGColor.objects.get(slug='default')

            return self.form_valid(form)
        else:
            print(form.errors.as_data())
            return self.form_invalid(form)


smoothies  = ['coconut', 'strawberry', 'banana', 'pineapple', 'acai berry']

has_coconut = [True, False, False, True, False]

i = 0

#while i < len(has_coconut):
#    if has_coconut[i]:
#       print(smoothies[i], 'contains coconut')
#    i = i +1

#we want to print out the smoothies from (smooothies) that have coconut
#we compare smoothies to has_coconut and print only those that match for True

for smoothie in smoothies:
    if has_coconut[i]:
      print(smoothie)
    i = i + 1


import calendar
import datetime
from abc import ABC, abstractmethod

class _Reader(ABC):

    _path = None
    _usecols = None
    _skiprows = None
    _nrows_max = None
    _df = None

    @classmethod
    def run(cls, path, usecols, skiprows, nrows_max=1e5):
        """Reads file and returns final raw data as pandas dataframe."""
        cls._customize(path, usecols, skiprows, nrows_max)
        cls._read()

    @classmethod
    def run_specific(cls, path, usecols, skiprows, nrows_max=1e5):
        """Parses file and returns final pure data as pandas dataframe.

        Args:
            path: File path.
            usecols: A list of integers representing column numbers of excel table.
                1st integer must be column number of date.
                2 - well name.
                3 - oil production.
                4 - liquid production.
                5 - formation name or bhp.
                Column numeration starts from zero.
            skiprows: Number of rows to skip at the beginning.
            nrows_max: Number of rows to parse.
        """
        cls._customize(path, usecols, skiprows, nrows_max)
        cls._read()
        cls._process()
        return cls._df

    @classmethod
    @abstractmethod
    def _read(cls):
        pass

    @classmethod
    def _customize(cls, path, usecols, skiprows, nrows_max):
        cls._path = path
        cls._usecols = usecols
        cls._skiprows = skiprows
        cls._nrows_max = nrows_max

    @classmethod
    @abstractmethod
    def _process(cls):
        cls._df = cls._df[cls._usecols]
        cls._df.columns = range(cls._df.shape[1])
        cls._df.rename(columns={0: 'date'}, inplace=True)
        cls._df['date'] = cls._df['date'].apply(func=cls._convert_date_from_string)
        cls._df.sort_values(by='date', axis='index', ascending=True, inplace=True, ignore_index=False)

    @staticmethod
    def _convert_date_from_string(x):
        if type(x) is not str:
            return x
        format_date = '%m.%Y'
        date = datetime.datetime.strptime(x, format_date)
        day_last = calendar.monthrange(date.year, date.month)[1]  # A last day of the date month.
        date = date.replace(day=day_last)
        return date


import json
import logging
from collections import defaultdict
from dataclasses import dataclass
from typing import Dict, List

import pandas as pd
import typer

logger = logging.getLogger(__name__)

@dataclass
class ResfinderResult:
    sample_name: str
    genes: List[str]
    amr_resistant: List[str]

def process_args_table(
    sample_results: ResfinderResult,
    table: Dict[str, List[int]],
    n_processed_samples: int,
):
    args_to_add = set(["_".join(arg.split("_")[:1]) for arg in sample_results.genes])
    logger.info(
        f"Adding {len(args_to_add)} ARGs corresponding to sample {sample_results.sample_name}"
    )
    # Add the sample values to the table
    for arg in table:
        if arg in args_to_add:
            table[arg].append(1)
            args_to_add.remove(arg)
        else:
            table[arg].append(0)
    # Add new ARG if it was not present in the previous samples
    for arg in args_to_add:
        table[arg] = [0] * (n_processed_samples - 1) + [1]

def main(
    results_files: List[str] = typer.Argument(
        ..., help="List of path to the parsed results from ResFinder"
    ),
    output: str = typer.Option(..., help="Filename of the final CSV file"),
):
    logger.info(f"Reading {len(results_files)} results files...")
    # Read and process all the results files
    samples_list = []
    args_table = defaultdict(list)
    for res_filepath in results_files:
        with open(res_filepath, "r") as json_file:
            sample_results = ResfinderResult(**json.load(json_file))
        samples_list.append(sample_results.sample_name)
        process_args_table(sample_results, args_table, len(samples_list))
    # Create dataframe
    logger.info(f"Creating dataframe with total of {len(args_table)} ARGs...")
    args_table = pd.DataFrame.from_records(args_table, index=samples_list)
    args_table.to_csv(output, index_label="sample_name")
    logger.info(f"Results saved to {output} successfully.")

if __name__ == "__main__":
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s][%(name)s] -- %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )
    typer.run(main)


import vlc
instance = vlc.Instance()

class VLCPlayer():
    def __init__(self,f):
        self.player = self.Instance.media_player_new()
        self.player.set_media(self.Media)

import vlc
import time
print("k")
p = instance.media_player_new()

p.set_media(instance.media_new("foo.wav"))
device = p.audio_output_device_enum()
while device:
    print ("playing on...")
    print (device.contents.device)
    print (device.contents.description)

    p.audio_output_device_set(None, device.contents.device)
    time.sleep(3)

    device = device.contents.next

p.stop()


from math import floor
import numpy as np

class Helper:
    PROMOTER_FILE: str = "data/CNNPromoterData/human_non_tata.fa"
    NONPROMOTER_FILE: str = "data/CNNPromoterData/human_nonprom_big.fa"
    _dna_dict: dict
    _lbl_dict: dict
    _variable_dict: dict

    def __init__(self):
        self._dna_dict = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
        self._lbl_dict = {'Non-Promoter': 0, 'Promoter': 1}
        self._variable_dict = {}

    def get_DNA_dict(self):
        return self._dna_dict

    def get_LABEL_dict(self):
        return self._lbl_dict

    def add_variable(self, name, value):
        try:
            _ = self._variable_dict[name]
            return False
        except KeyError:
            self._variable_dict[name] = value
            return True

    def get_variable(self, name):
        try:
            return self._variable_dict[name]
        except KeyError:
            raise Exception("Variable doesn't exist.")

    def update_variable(self, name, value):
        try:
            _ = self._variable_dict[name]
            self._variable_dict[name] = value
            return True
        except KeyError:
            return False

    @staticmethod
    def normalize(x):
        return (x-np.min(x))/(np.max(x)-np.min(x))

    @staticmethod
    def softmax(x):
        temp = np.exp(x)
        return (temp / np.sum(temp, axis=0))

    @staticmethod
    def relu(x):
        return x * (x > 0)

    @staticmethod
    def neg_relu(x, value):
        return min(x, value)

    @staticmethod
    def reciprocal(x):
        temp = 1/x
        return (temp / np.sum(temp, axis=0))

    @staticmethod
    def sum_one(x):
        dif = 1 - np.sum(x, axis=1)
        approx = x + np.expand_dims((dif / 4), axis=1)
        check = np.sum(approx, axis=1)
        if not np.all(check == 1):
            dif = 1 - check
            bad_rows = np.nonzero(check != 1)
            for row in bad_rows[0]:
                if dif[row] > 0:
                    approx[row, np.argmax(approx, axis=1)[row]] += dif[row]
                else:
                    approx[row, np.argmin(approx, axis=1)[row]] += dif[row]
        return approx

    @staticmethod
    def aggregate_weights(filter_idx, filter_weights, position, conv_result_length, weights1=None, weights2=None):
        if weights1 is None:
            weights1 = np.zeros_like(weights2)
        if weights2 is None:
            weights2 = np.zeros_like(weights1)
        return filter_weights * weights1[position + conv_result_length*filter_idx] - filter_weights * weights2[position + conv_result_length*filter_idx]

    @staticmethod
    def conv1d_out_shape(in_length, kernel_size=1, padding=0, stride=1, dilation=1):
        result = floor( ((in_length + (2 * padding) - ( dilation * (kernel_size - 1) ) - 1 )/ stride) + 1)
        return result

    def get_jaspar_matrices(self, tfbs):
        import coreapi, seqlogo
        helper_class = Helper()
        client = coreapi.Client()
        schema = client.get("http://jaspar.genereg.net/api/v1/docs")
        matrices = {}
        for tfbs_name, collection in tfbs.items():
            action = ["matrix", "list"]
            params = {
                "page_size": '1000',
                "version": 'latest'
            }
            if(tfbs_name is not None):
                params['name'] = tfbs_name
            if(collection is not None):
                params['collection'] = collection
            result_list = client.action(schema, action, params=params)

            action = ["matrix", "read"]
            for res in result_list['results']:
                params = {
                    "matrix_id": res['matrix_id']
                }
                result_read = client.action(schema, action, params=params)
                pfm = np.ndarray((len(result_read['pfm']), len(result_read['pfm']['A'])), dtype=int)
                for key, value in helper_class.get_DNA_dict().items():
                    pfm[value] = np.array(result_read['pfm'][key], dtype=int)
                pm = seqlogo.CompletePm(pfm=pfm)
                matrices[result_read['name']] = pm
        return matrices

    @staticmethod
    def get_filters(matrices, matrix_type):
        max_filter_len = 0
        pms = []
        for m_name, m in matrices.items():
            matrix = getattr(m, matrix_type)
            pm_len = len(matrix)
            if pm_len > max_filter_len:
                max_filter_len = pm_len
            pms.append([m_name, matrix._values.T])
        return max_filter_len, pms


import time

from networkautomation.common import JobState
from networkautomation import job

"""Network Automation Framework
   Exposed module to executing network automation jobs.
    - Option 1: Executing scenario in template
        job_manager.execute_job(USE_TEMPLATE, target,
                                driver_type, templates[BACKUP, APPLY, VERIFY, ROLLBACK])
    - Option 2: Executing action with specified element
        job_manager.execute_job(USE_ACTION, target,
                                action, element)
"""
class JobManager:
    JOB_POOL = {}
    DEFAULT_JOB_TIMEOUT = 3 * 60  # seconds

    def execute_job(self, job_type, target,
                    driver_type=None, templates=None,
                    action=None, element=None,
                    input_vars=None, timeout=DEFAULT_JOB_TIMEOUT):
        my_job = job.Job(job_type, target, driver_type=driver_type,
                         templates=templates, action=action, element=element,
                         input_vars=input_vars)
        if my_job:
            self.JOB_POOL[my_job.id] = my_job
            return my_job.execute(timeout)
        else:
            return False, 'Error: can not init job'

    def register_job(self, job_type, target,
                     driver_type=None, templates=None,
                     action=None, element=None,
                     input_vars=None):
        my_job = job.Job(job_type, target, driver_type=driver_type,
                         templates=templates, action=action, element=element,
                         input_vars=input_vars)
        if my_job:
            self.JOB_POOL[my_job.id] = my_job
            return my_job.id
        else:
            print('Can not init job')
            return None

    def start_job(self, job_id, timeout=DEFAULT_JOB_TIMEOUT):
        my_job = self.JOB_POOL.get(job_id)
        if my_job:
            my_job.execute(timeout)
        else:
            print('Can not find job ', job_id)

    def wait_to_finish_job(self, job_id, timeout=None, auto_terminate=True):
        my_job = self.JOB_POOL.get(job_id)
        timeout_microsecond = 0
        if timeout:
            timeout_microsecond = timeout * 1000000
        begin_time = time.time()
        while my_job.status != JobState.FINISHED:
            if (timeout_microsecond > 0) \
                    and (time.time() - begin_time >= timeout_microsecond):
                if auto_terminate:
                    my_job.terminate()
                break
            else:
                time.sleep(2)

    def terminate_job(self, job_id):
        if job_id in self.JOB_POOL:
            my_job = self.JOB_POOL.get(job_id)
            my_job.terminate()

    def get_job_status(self, job_id):
        status = None
        if job_id in self.JOB_POOL:
            my_job = self.JOB_POOL.get(job_id)
            status = my_job.status.value
        return status


# -*- coding: utf-8 -*-
"""
"""
from setuptools import setup, find_packages

with open('requirements.txt') as fd:
    requirements = fd.readlines()

with open('test-requirements.txt') as fd:
    test_requirements = fd.readlines()

setup(
    name='remarkable-friend',
    packages=find_packages(),
    setup_requires=[],
    install_requires=requirements,
    entry_points={
        'console_scripts': 'rmfriend=rmfriend.tools.manage:main'
    },
)


import numpy as np

"""
A simulator that performs utility functions simulating multiple neuron activities
"""
class Simulator:
  """Calculates the optimal decoder given x and neuron firing activities

  Params:
  x - information being encoded
  A - neuron activity matrix
  noise - std dev of the expected noise

  Returns:
  d - decoders
  """
  @staticmethod
  def GetDecoders(x, A, noise_std=None, transformation=lambda x: x):
    if noise_std:
      A = A + np.random.normal(scale=noise_std * np.max(A), size=A.shape)
    x = transformation(x)
    # Gamma = np.dot(A.T, A)
    # Upsilon = np.dot(A.T, x)
    # decoders = np.dot(np.linalg.pinv(Gamma), Upsilon)

    # Use numpy built in least square solver to improve performance
    decoders, residuals2, rank, s = np.linalg.lstsq(A, x)

    return decoders

  @staticmethod
  def FilterResponses(responses, filter_kernel):
    filtered_spikes = np.array([
        np.convolve(spikes, filter_kernel, mode='same')
          for voltage, spikes in responses]).T
    return filtered_spikes

  """Calculate decoders given input and temporal response

  Params:
    x - the information encoded
    fitler_kernel - filter used to perform convolution
      e.g. post synaptic current filter, optimal filter
    noise_std - the estimated noise standard deviation
    transformation - the transformation applied to input
  Returns:
    filtered_spikes - the filtered A matrix (activity matrix)
    decoders - decoders to decode filtered_spikes to x
  """
  @staticmethod
  def GetDecodersForTemporalResponses(
      x, responses, filter_kernel, noise_std=None, transformation=lambda x: x):
    filtered_spikes = Simulator.FilterResponses(responses, filter_kernel)
    return Simulator.GetDecoders(x, filtered_spikes, noise_std, transformation)

  """Calcualtes the optimal temporal decoder

  Calculations:
    minimizing the square error
    E = ( X(w) - X_hat(w) )^2
    E = ( X(w) - R(w)H(w) )^2
    0 = X(w) - R(w)H(w)
    H(w) = X(w)R*(w) / |R(w)|^2

    Cutting signals into small pieces and average over =>
    convolution with W(w) in both denominator and numerator
    H(w) = X(w)R*(w) conv W(w) / |R(w)|^2 conv W(w)

  Params:
    input_signal - signal
    response_sum - sum of all neuron responses
    dt - time step
    sigma_t - Gaussian window (rate code / timing code)

  Returns:
    h, H - Optimal decoder for the input signal in time and frequency
  """
  @staticmethod
  def GetTemporalOptimalDecoder(input_signal, response_sum, dt, sigma_t=0.025):
    R = np.fft.fftshift(np.fft.fft(response_sum))
    freq = np.fft.fftshift(np.fft.fftfreq(len(R), d=dt))
    omega = freq * 2 * np.pi
    X = np.fft.fftshift(np.fft.fft(input_signal))
    W2 = np.exp(-omega ** 2 * sigma_t ** 2)
    W2 = W2 / sum(W2)
    CP = X * R.conjugate()
    WCP = np.convolve(CP, W2, 'same')
    RP = R * R.conjugate()
    WRP = np.convolve(RP, W2, 'same')
    XP = X * X.conjugate()
    H = WCP / WRP
    h = np.fft.fftshift(np.fft.ifft(np.fft.ifftshift(H))).real

    return h, H

  """Get the biological plausible filter which models post synaptic current model

  h(t) = t^n * e^(-t/tau)

  Params:
    time - array of time e.g [0, 0.01, ... 0.99, 1]
    tau - neurotransmitter time constant
    n - some parameter

  Returns:
    Normalized post synaptic current filter
  """
  @staticmethod
  def GetPostSynapticFilter(time, tau, n=0):
    time = time - time[-1 * (len(time) % 2) + -1] / 2.
    h = time ** n * np.exp(-time / tau)
    h[np.where(time < 0)] = 0

    return h / np.sum(h), time


# -*- coding: utf-8 -*-
"""
Created on Thu Apr 30 09:34:57 2020

@author: CS
"""

import librosa
import librosa.display
import json
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from matplotlib.pyplot import specgram
import pandas as pd
import seaborn as sns
import glob
import os
from tqdm import tqdm
import pickle
import IPython.display as ipd  # To play sound in the notebook

fname = 'D:/Project/Sound/ShipsEar/Data_frame/6__Passengers_19.wav'
data, sampling_rate = librosa.load(fname)
melspec = librosa.feature.melspectrogram(data, sampling_rate, n_mels=128)
logmelspec = librosa.power_to_db(melspec)
plt.figure(figsize=(8,4))
librosa.display.waveplot(data, sr=sampling_rate)
ipd.Audio(data, rate=sampling_rate)
plt.figure(figsize=(8,4))
librosa.display.specshow(logmelspec, y_axis='linear')
# =============================================================================
# # 数据增广方法（Augmentations Methods）
# =============================================================================
# (1) 添加白噪声
def noise(data):
    noise_amp = 0.05*np.random.uniform() * np.amax(data)
    data = data.astype('float') + noise_amp * np.random.normal(size=data.shape[0])
    return data
# 在背景中添加静态噪声。
x = noise(data)
plt.figure(figsize=(8,4))
librosa.display.waveplot(x, sr=sampling_rate)
ipd.Audio(x , rate=sampling_rate)

# (2) 随机移动
def shift(data):
    s_range = int(np.random.uniform(low=-5, high=5)*1000)
    return np.roll(data, s_range)

x = shift(data)
plt.figure(figsize=(8,4))
librosa.display.waveplot(x, sr=sampling_rate)

# (3) 时域拉伸
def stretch(data, rate=0.8):
    data = librosa.effects.time_stretch(data, rate)
    return data

x = stretch(data)
melspec = librosa.feature.melspectrogram(x, sampling_rate, n_mels=128)
logmelspec = librosa.power_to_db(melspec)
plt.figure(figsize=(8,4))
librosa.display.waveplot(x, sr=sampling_rate)
plt.figure(figsize=(8,4))
librosa.display.specshow(logmelspec, y_axis='linear')

# (4) 音调变换，该方法强调高音
def pitch(data, sample_rate):
    bins_per_octave = 12
    pitch_pm = -2
    pitch_change = pitch_pm * 2*(np.random.uniform())
    data = librosa.effects.pitch_shift(data.astype('float64'),
                                       sample_rate, n_steps=pitch_change,
                                       bins_per_octave=bins_per_octave)
    return data

x = pitch(data, sampling_rate)
melspec = librosa.feature.melspectrogram(x, sampling_rate, n_mels=128)
logmelspec = librosa.power_to_db(melspec)
plt.figure(figsize=(8, 4))
librosa.display.waveplot(x, sr=sampling_rate)
plt.figure(figsize=(8,4))
librosa.display.specshow(logmelspec, y_axis='linear')

# (5) 动态随机变化
def dyn_change(data):
    dyn_change = np.random.uniform(low=-0.5 ,high=7)
    return (data * dyn_change)

x = dyn_change(data)
plt.figure(figsize=(8, 4))
librosa.display.waveplot(x, sr=sampling_rate)

# (6)加速(压缩)和音调变换
def speedNpitch(data):
    length_change = np.random.uniform(low=0.8, high=1)
    speed_fac =1.2 / length_change
    tmp = np.interp(np.arange(0,len(data), speed_fac), np.arange(0, len(data)), data)
    minlen = min(data.shape[0], tmp.shape[0])
    data *= 0
    data[0:minlen] = tmp[0:minlen]
    return data

x = speedNpitch(data)
plt.figure(figsize=(8, 4))
librosa.display.waveplot(x, sr=sampling_rate)


import os
import sys

import transaction
from pyramid.paster import get_appsettings, setup_logging
from pyramid.scripts.common import parse_vars
from sqlalchemy import engine_from_config

from ..models import (
    DBSession,
    Company,
    Member,
    Order,
    Event,
    Base,
    )

def usage(argv):
    cmd = os.path.basename(argv[0])
    print('usage: %s <config_uri> [var=value]\n'
          '(example: "%s development.ini")' % (cmd, cmd))
    sys.exit(1)

def main(argv=sys.argv):
    if len(argv) < 2:
        usage(argv)
    config_uri = argv[1]
    options = parse_vars(argv[2:])
    setup_logging(config_uri)
    settings = get_appsettings(config_uri, options=options)
    engine = engine_from_config(settings, 'sqlalchemy.')
    DBSession.configure(bind=engine)

    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)
    with transaction.manager:
        event1 = Event(
            name = 'Иннопром 2016',
            date = 'с 11 по 14 июля',
            #address = 'г. Екатеринбург, ЭКСПО-бульвар, дом 2',
            description = 'Главная тема ИННОПРОМ-2016 - «Промышленные сети». Страна-партнер ИННОПРОМ-2016 – Индия. Темы, которые действительно волнуют промышленников. Более 500 спикеров и экспертов на уровне СЕО. 150 мероприятий, открытых для посещения. Более 40 партнеров по организации мероприятий, среди которых: крупнейшие игроки российского и международного промышленного сектора, финансовые институты, институты развития, исследовательские учреждения. Индивидуальные/закрытые встречи лиц, принимающих решения. Прямое общение компаний с заказчиками, партнерами и всеми уровнями власти.',
        	img = 'innoprom.jpg')
        event2 = Event(
            name = 'Gadget Show 2016',
            date = 'c 26 по 28 августа',
            description = 'Концепция выставки и кибер-фестиваля заключается в максимуме интерактива, применению роботов и виртуальной реальности, созданию развлекательного и рабочего пространства для участников и посетителей. Возможности для спонсоров и партнеров в категориях генеральный спонсор, спонсор и партнер включают широкие возможности продвижения как до начала, так во время и после выставки.',
            img = 'gadgetshow.jpg')
        event3 = Event(
            name = 'Международная туристическая выставка Expotravel',
            date = 'c 7 по 8 октября',
            description = '«EXPOTRAVEL» - яркое событие в индустрии туризма, направленное на развитие внутреннего, въездного и выездного туризма, а также на укрепление взаимоотношений между региональными и зарубежными представителями туристического бизнеса за счет создания уникальной платформы для их взаимодействия. Участие в выставке позволит Вам рассказать о своих уникальных услугах, установить контакты с потенциальными клиентами, как в Уральском регионе, так и за его пределами, и обменяться опытом с вашими коллегами.',
            img = 'expotravel.jpg')
        DBSession.add(event1)
        DBSession.add(event2)
        DBSession.add(event3)

        company1 = Company(
            name = 'Госкорпорация "Росатом"',
            site = 'http://www.rosatom.ru/')
        company2 = Company(
            name = 'КУКА РОБОТИКС РУС, ООО',
            site = 'http://www.kuka-robotics.com/russia/ru/')
        DBSession.add(company1)
        DBSession.add(company2)

        member1 = Member(
            name = 'Сергей Кириенко',
            phone = '89022134935',
            company = company1)
        member2 = Member(
            name = 'Эйил Грир',
            phone = '89002107823',
            company = company2)
        member3 = Member(
            name = 'Мэтью Уэбб',
            phone = '89002107824',
            company = company2)
        DBSession.add(member1)
        DBSession.add(member2)
        DBSession.add(member3)

        order1 = Order(
            member = member1,
            payment_status = True,
            obtain_status = False)
        order2 = Order(
            member = member2,
            payment_status = True,
            obtain_status = False)
        order3 = Order(
            member = member3,
            payment_status = True,
            obtain_status = False)
        DBSession.add(order1)
        DBSession.add(order2)
        DBSession.add(order3)


import streamlit as st
import pickle
import spacy
nlp = spacy.load("en_core_web_lg")

data = {
    "Household": 0,
    "Books": 1,
    "Electronics": 2,
    "Clothing & Accessories": 3
}

def preprocess(text):
    doc = nlp(text)
    filtered_tokens = []
    for token in doc:
        if token.is_stop or token.is_punct:
            continue
        filtered_tokens.append(token.lemma_)
    return [" ".join(filtered_tokens)]

st.title('Ecommerce Product Classifier')

# Create a text element and let the reader know the data is loading.
data_load_state = st.text_input("Enter Product Details")
with open('model/ecommerce.pkl', 'rb') as f:
    model = pickle.load(f)

    if (data_load_state != ""):
        text = preprocess(data_load_state)
        pred = model.predict(text)

        matching_keys = [key for key,
                         value in data.items() if value == pred[0]]
        st.text("Output: " + matching_keys[0])


from difflib import SequenceMatcher
from sqlite3 import connect
from functools import wraps
from owlready2 import get_ontology
from random import randint
from numpy import clip
from datetime import timedelta
from bs4 import BeautifulSoup
from collections import OrderedDict
from decouple import config
from requests import get
from validators import url

from InspiringCompanion.archivist import Archivist
from InspiringCompanion import writer

TEMPERATURE_VAR = 2
WIND_STRENGTH_VAR = 2
WIND_DIRECTION_VAR = 60
PRECIPITATION_VAR = 20
ONTOLOGY_PATH = config('ONTOLOGY_PATH', default='./resources/inspiration.owl')

ONTOLOGY = get_ontology(ONTOLOGY_PATH).load()

class Director(object):
    def __init__(self, database=":memory:"):
        self.channel = None
        self.server = None
        self.scene = None
        self.database = connect(database)

    def action(self, func):
        @wraps(func)
        async def decorator(ctx, *args, **kwargs):
            self.set_scene_from(ctx.message)
            return await func(ctx, *args, **kwargs)

        decorator.__name__ = func.__name__

        return decorator

    def reaction(self, emoji, user):
        return getattr(self, emojis[emoji])(user)

    def inspiration(self):
        return f"{self.scene.calendar.description()}\n" \
               f"{self.scene.description()}\n" \
               f"{writer.compile_log(self.find_characters(), '', '')}"

    def call_archivist(self):
        return Archivist(self.database, self.server, self.channel)

    def record_scene(self):
        return self.call_archivist().record_scene(self.scene)

    def find_scene(self):
        return self.call_archivist().find_scene()

    def record_character(self, name, user_id):
        return self.call_archivist().record_character(name, user_id)

    def record_inventory(self):
        return self.call_archivist().record_inventory(self.scene.inventory)

    def record_item(self, charges, name):
        return self.call_archivist().record_item(charges, name)

    def record_bulk(self, charges, name):
        return self.call_archivist().record_bulk(charges, name)

    def record_my_pc(self, display_name, user_id, provider, provider_id):
        return self.call_archivist().record_my_pc(display_name, user_id, provider, provider_id)

    def find_characters(self):
        return self.call_archivist().find_characters()

    def delete_characters(self, to_dismiss=None):
        return self.call_archivist().delete_characters(to_dismiss=to_dismiss)

    def find_timers(self):
        return self.call_archivist().find_timers()

    def delete_timers(self):
        return self.call_archivist().delete_timers()

    def find_items(self):
        return self.call_archivist().find_items()

    def find_bulks(self):
        return self.call_archivist().find_bulks()

    def set_scene_from(self, message):
        self.server = message.guild.id
        self.channel = message.channel.id

        scene_data = self.find_scene()
        timers_data = self.find_timers()
        items_data = self.find_items()
        bulks_data = self.find_bulks()

        self.scene = Scene(scene_data, timers_data, items_data, bulks_data)

        if scene_data is None:
            self.record_scene()

        pass

    def move_scene_to(self, new_location):

        new_location = Location(new_location)

        if new_location.entity_data == self.scene.location.entity_data:
            message = f"We already are in {self.scene.location.name}"

        else:
            self.scene.location = new_location
            self.scene.weather.entity_data = find_entity_by_name(self.scene.location.entity_data.has_climate.name)
            self.record_scene()

            message = f"We move to {self.scene.location.name}"

        return message

    def sunrise(self, _, day=1):
        self.scene.characters = self.find_characters()
        sunrise_text = self.scene.sunrise(day)
        self.record_scene()
        self.record_inventory()
        self.delete_timers()

        return f" {sunrise_text}...\n\n{self.inspiration()}"

    def gather(self, user):
        self.record_character(user.display_name, user.id)
        return f"{user.display_name} heeds the call to adventure!"

    def dismiss(self, char):
        self.delete_characters(to_dismiss=char)
        return f"{char} is dismissed"

    def disband(self, _):
        self.delete_characters()
        return f"The party has been disbanded"

    def mypc(self, user, provider, provider_id):
        self.record_my_pc(user.display_name, user.id, provider, provider_id)
        return f"{user.display_name} assigned.\nhttps://{provider}.ac/characters/{provider_id}/"

    def one_minute(self, _):
        return self.timegoesby(1)

    def ten_minutes(self, _):
        return self.timegoesby(10)

    def one_hour(self, _):
        return self.timegoesby(60)

    def timegoesby(self, minutes):
        t = self.scene.clock.time_goes_by(minutes)
        output = ""
        if t is not None:
            output += f"The timer {t} just expired. "

        self.record_scene()

        return f"{output}It is {self.scene.clock.time}."

    def addtimer(self, minutes, name=""):
        self.scene.clock.add_timer(name, time_left=minutes)
        self.record_scene()
        return f"{name} timer is set at {self.scene.clock.timers[name]}"

    def additem(self, charges, name):
        bulk, name, charges = self.scene.inventory.add_item(charges, name)
        if bulk:
            self.record_bulk(charges, name)
            return f"{charges} {name} available in the scene"
        if not bulk:
            self.record_item(charges, name)
            return f"{name} with {charges} charges added to the scene"

    def log(self, channel_name, messages, ):
        user_text = writer.stick_messages_together(messages)
        page = writer.compile_log(self.find_characters(), self.scene.description(), user_text)
        adventure = writer.normalize_entity_name(channel_name).capitalize()
        image = self.scene.location.image_url()
        return adventure, page, image

class Scene(object):

    def __init__(self, scene_data=None, timers_data=None, inventory_data=None, bulks_data=None):

        if scene_data is None:
            active_calendar = "Calendar of Harptos"
            location = "Elturel"
            day = 1
            weather_data = (0, 0, 0, 0)
            minutes = 8 * 60
        else:
            location = scene_data[2]
            day = int(scene_data[3])
            weather_data = scene_data[4:8]
            active_calendar = scene_data[8]
            minutes = scene_data[9]

        self.calendar = Calendar(active_calendar)
        self.calendar.sunrise(day)

        self.location = Location(location)

        self.weather = Weather(self.location.entity_data.has_climate.name)
        self.weather.seed(weather_data)

        self.clock = Clock()
        self.clock = Clock(time=timedelta(minutes=minutes))

        self.characters = {}

        self.inventory = Inventory()

        if timers_data is not None:
            for r in timers_data:
                if timedelta(minutes=r[1]) > self.clock.time:
                    self.clock.add_timer(r[0], expiring_time=r[1])

        if inventory_data is not None:
            for record in inventory_data:
                self.inventory.add_item(record[1], record[0])

        if bulks_data is not None:
            for record in bulks_data:
                self.inventory.add_item(record[1], record[0])

        pass

    def description(self):

        description = f"We are in {self.location.name}. It is {self.clock.time}.\n" \
                      f"It {self.weather.precipitation_text(self.calendar.season)}. " \
                      f"The temperature is {self.weather.temperature_text(self.calendar.season)} " \
                      f"with {self.weather.wind_strength_text(self.calendar.season)}"

        if self.weather.wind_strength_text(self.calendar.season) != "no winds":
            description += f" {self.weather.wind_direction_text(self.calendar.season)}"

        for n, r in enumerate(self.clock.timers.keys()):
            if r == "midnight":
                break
            if n == 0:
                description += ".\n\nUpcoming events:\n"
            description += f"{r}: {self.clock.timers[r]}\n"

        for n, item in enumerate(self.inventory.items):
            if n == 0:
                description += "\nInventory:\n"
            description += f"{item.charges} {item.name}\n"

        return description

    def sunrise(self, num_sunrises):
        self.calendar.sunrise(num_sunrises)
        self.weather.sunrise(num_sunrises)
        self.inventory.sunrise(num_sunrises, len(self.characters))
        self.clock = Clock()
        if num_sunrises == 1:
            return f"One day has passed"
        else:
            return f"Many days have passed"

class Inspiration(object):

    def __init__(self, name):
        self.entity_data = find_entity_by_name(name)
        self.name = writer.normalize_entity_name(self.entity_data.name)

class Calendar(Inspiration):

    def __init__(self, name):
        super().__init__(name)
        self.minute = 0
        self.hour = 0
        self.day = 0
        self.month = self.entity_data.starts_with
        self.year = 1
        self.epoch = 0
        self.season = find_entity_by_name("Winter")

    def sunrise(self, num_sunrises):

        self.epoch += num_sunrises
        self.year += int(num_sunrises / self.entity_data.has_days)
        self.day += num_sunrises % self.entity_data.has_days

        while self.day > self.month.has_days:
            self.day = self.day - self.month.has_days
            self.month = self.month.precedes
            if self.month == self.entity_data.starts_with:
                self.year += 1

        self.season = self.month.is_in_season

        pass

    def description(self):
        if self.month.has_days == 1:
            return self.month.name
        else:
            return f"{self.day} {self.month.name}, {self.year}"

class Clock(object):

    def __init__(self, time=timedelta(hours=8)):
        self.time = time
        self.timers = OrderedDict()
        self.add_timer("midnight", expiring_time=24 * 60)

    def time_goes_by(self, minutes):

        target_time = self.time + timedelta(minutes=minutes)
        next_timer = next(iter(self.timers.items()))

        if target_time < next_timer[1]:
            self.time = target_time
            return None
        else:
            self.time = next_timer[1]
            self.timers.pop(next_timer[0])
            return next_timer[0]

    def add_timer(self, name, time_left=None, expiring_time=None):
        if time_left is None and expiring_time is None:
            return
        if time_left is not None and expiring_time is not None:
            return

        if time_left is not None:
            self.timers[name] = self.time + timedelta(minutes=time_left)

        if expiring_time is not None:
            self.timers[name] = timedelta(minutes=expiring_time)

        self.timers = OrderedDict(sorted(self.timers.items(), key=lambda x: x[1]))
        return

class Inventory(object):
    def __init__(self):
        self.items = []

    def add_item(self, charges, name):
        candidate = InventoryItem(name)
        existing_items = [x for x in self.items if x.entity_data.iri == candidate.entity_data.iri]

        if candidate.entity_data.is_bulk_item:
            if len(existing_items) == 0:
                item = candidate
                self.items.append(item)

            else:
                item = existing_items[0]

            item.charges += charges

        else:
            item = InventoryItem(name)
            item.charges = charges
            self.items.append(item)

        return_charges = item.charges

        return bool(candidate.entity_data.is_bulk_item), candidate.name, return_charges

    def sunrise(self, num_sunrises, num_characters):
        for item in self.items:
            how_often = num_sunrises * num_characters if item.entity_data.everyone_has_to_recharge else num_sunrises
            for n in range(how_often):
                item.recharge()

class InventoryItem(Inspiration):
    def __init__(self, name):
        super().__init__(name)
        self.charges = 0

    def parse_charging_formula(self):
        p = self.entity_data.has_charging_formula.split("/")
        sign = p[0][0]
        freq = p[0][1:]
        return sign, freq, p[1]

    def recharge(self):
        f = self.parse_charging_formula()
        change = 0
        all_parts = f[2].split("+")
        for part in all_parts:
            dices = part.split("d")
            dices.append(1)  # in case the 1 as in 3d1
            roll = [randint(1, int(dices[1])) for _ in range(int(dices[0]))]
            change += sum(roll)
        if f[0] == "-":
            self.charges -= change
        else:
            self.charges += change

        self.charges = max(0, self.charges)

class Weather(Inspiration):

    def __init__(self, name):
        super().__init__(name)
        self.temperature = self.entity_data.has_temperature
        self.wind_strength = self.entity_data.has_wind_strength
        self.wind_direction = self.entity_data.has_wind_direction
        self.precipitation = self.entity_data.has_precipitation

    def seed(self, data):
        self.wind_strength = data[0]
        self.wind_direction = data[1]
        self.precipitation = data[2]
        self.temperature = data[3]

    def sunrise(self, num_sunrises):
        for n in range(min(num_sunrises, 20)):
            self.temperature += randint(-TEMPERATURE_VAR, TEMPERATURE_VAR) - self.temperature / 2
            self.wind_strength += randint(-WIND_STRENGTH_VAR, WIND_STRENGTH_VAR) - self.wind_strength / 2
            self.wind_direction += randint(-WIND_DIRECTION_VAR, WIND_DIRECTION_VAR) - self.wind_direction / 2
            self.precipitation += randint(-PRECIPITATION_VAR, PRECIPITATION_VAR) - self.precipitation / 2
        pass

    def local_wind_strength(self, season):
        return self.entity_data.has_wind_strength + self.wind_strength + season.has_climate.has_wind_strength

    def wind_strength_text(self, season):
        winds_strength = ["no", "weak", "strong", "very strong", "hurricane like"]
        ws = self.local_wind_strength(season)
        ws = clip(int(ws / 10), 0, 4)
        return f"{winds_strength[ws]} winds"

    def local_wind_direction(self):
        return self.entity_data.has_wind_direction + self.wind_direction

    def wind_direction_text(self, season):

        if self.wind_strength_text(season) == "no winds":
            return ""
        else:
            winds_direction = ["south", "south-east", "east", "north-east", "north", "north-west", "west", "south-west"]
            wd = self.entity_data.has_wind_direction + self.wind_direction
            wd = int(8.0 * wd / 360) % 8
            return f"from the {winds_direction[wd]}"

    def local_precipitation(self, season):
        return self.entity_data.has_precipitation + self.precipitation + season.has_climate.has_precipitation

    def precipitation_text(self, season):
        rain_strength = ["is a sunny day", "is cloudy", "rains", "rains strongly"]
        rd = self.local_precipitation(season)
        rd = clip(int(rd / 50), 0, 3)
        return f"{rain_strength[rd]}"

    def local_temperature(self, season):
        return self.entity_data.has_temperature + self.temperature + season.has_climate.has_temperature

    def temperature_text(self, season):

        r = round(self.local_temperature(season))
        return f"{r}°C"

class Location(Inspiration):
    def __init__(self, name):
        super().__init__(name)

    def image_url(self, html=None):

        if not url(self.entity_data.iri):
            return None

        if html is None:
            html = get(self.entity_data.iri).text

        return BeautifulSoup(html, "html.parser").findAll("meta", property="og:image")[0]["content"]

def create_table(con):
    sql_create_scene_table = """ CREATE TABLE IF NOT EXISTS Scenes (
                                        server_id ui_text NOT NULL,
                                        channel_id ui_text NOT NULL,
                                        location ui_text NOT NULL,
                                        day int NOT NULL,
                                        wind_strength int NOT NULL,
                                        wind_direction int NOT NULL,
                                        rain int NOT NULL,
                                        temperature int NOT NULL,
                                        active_calendar ui_text NOT NULL,
                                        minutes int NOT NULL); """

    sql_scene_index = f"CREATE UNIQUE INDEX IF NOT EXISTS idx_scenes ON Scenes (server_id, channel_id)"

    sql_default_values = f"INSERT OR REPLACE INTO Scenes (server_id, channel_id, location, " \
                         f"day, wind_strength, wind_direction, rain, temperature, active_calendar, minutes) " \
                         f"VALUES( 'default_server', 'default_channel', " \
                         f"'Elturel', '0', '0', " \
                         f"'0', '0', '0', 'Calendar_of_Harptos', '480'); "

    sql_create_characters_table = """ CREATE TABLE IF NOT EXISTS Characters (
                                        server_id ui_text NOT NULL,
                                        channel_id ui_text NOT NULL,
                                        name ui_text NOT NULL,
                                        user_id ui_text NOT NULL,
                                        provider ui_text,
                                        provider_id ui_text); """

    sql_characters_index = f"CREATE UNIQUE INDEX IF NOT EXISTS idx_characters ON Characters (name, user_id)"

    sql_create_timers_table = """ CREATE TABLE IF NOT EXISTS Timers (
                                        server_id ui_text NOT NULL,
                                        channel_id ui_text NOT NULL,
                                        name ui_text NOT NULL,
                                        minutes int NOT NULL); """

    sql_create_items_table = """ CREATE TABLE IF NOT EXISTS Items (
                                        server_id ui_text NOT NULL,
                                        channel_id ui_text NOT NULL,
                                        name ui_text NOT NULL,
                                        charges int NOT NULL,
                                        max_charges int,
                                        next_recharge int); """

    sql_create_bulk_table = """ CREATE TABLE IF NOT EXISTS Bulks (
                                        server_id ui_text NOT NULL,
                                        channel_id ui_text NOT NULL,
                                        name ui_text NOT NULL,
                                        quantity int NOT NULL,
                                        max_quantity int,
                                        next_recharge int); """

    sql_bulk_index = f"CREATE UNIQUE INDEX IF NOT EXISTS idx_bulks ON Bulks (server_id, channel_id, name)"

    # create tables
    if con is not None:
        # create projects table
        con.cursor().execute(sql_create_scene_table)
        con.cursor().execute(sql_scene_index)
        con.cursor().execute(sql_default_values)

        con.cursor().execute(sql_create_characters_table)
        con.cursor().execute(sql_characters_index)
        con.cursor().execute(sql_create_timers_table)
        con.cursor().execute(sql_create_items_table)
        con.cursor().execute(sql_create_bulk_table)
        con.cursor().execute(sql_bulk_index)

    con.commit()

    pass

emojis = {
    "\U0001F304": "sunrise",
    "\U0001F39F": "gather",
    "\U0001F550": "one_minute",
    "\U0001F51F": "ten_minutes",
    u"\u26FA": "one_hour",
    u"\U0001F6D6": "disband"
}

def find_entity_by_name(to_find):
    max_distance = 0
    found = None

    for f in ONTOLOGY.individuals():
        data = writer.normalize_entity_name(f.name)

        m = SequenceMatcher(None, data, to_find).ratio()

        if m > max_distance:
            max_distance = m
            found = f
        if max_distance >= 1.0:
            return f

    return found


import random

correctNumber = random.randint(0, 10)

print("Welcome to the Number Guessing Game. \nTo win the game you have to guess the correct number between 0-10 that I'm thinking. \nLet's start the game")
print("You'll get five chances to guess the correct number.")

keepLooping = True
count = 0

while (keepLooping is True):

    userEnteredNumber = int(input("Try to guess the number: "))

    if (userEnteredNumber == correctNumber):
        print("Wow! You guessed the correct number. \nCongrats you won the game! :D")
        keepLooping = False
    elif (userEnteredNumber < correctNumber):
        print("OOPS! Your number is too low :( \nTry Again!")
        count += 1
        print(f"Remaining Chances: {5 - count}")
    else:
        print("OOPS! Your number is too high :( \nTry Again!")
        count += 1
        print(f"Remaining Chances: {5 - count}")

    if (count == 5):
        print("You are out of your chances :( \nYou lost the game.")
        print(f"The correct number is {correctNumber}")
        keepLooping = False


arr = [6,9,2,0,4,6,7,1,9,3]

s1, e1, s2, e2 = map(int,input().split())

def r_move(lst): # 우측회전
    tmp = lst[len(lst)-1]
    for i in range(len(lst)-1,0,-1):
        lst[i] = lst[i-1]
    lst[0] = tmp

arr1 = arr[s1:e1+1]
arr2 = arr[s2:e2+1]

r_move(arr1)
r_move(arr1)
r_move(arr2)
r_move(arr2)

arr[s1:e1+1] = arr1
arr[s2:e2+1] = arr2

print(arr)


import sys
import socket
import threading
from random import random
from time import sleep

from flask import Flask, render_template, Response, url_for, copy_current_request_context
from flask_socketio import SocketIO, emit
from camera import Camera
from data_stream import DataStream

app = Flask(__name__)

socketio = SocketIO(app, async_mode=None, logger=False, engineio_logger=False)

HOST = ''
PORT = 12801

data_stream = DataStream(PORT)

c = Camera(data_stream)

thread = threading.Thread()
thread_stop_event = threading.Event()

def randomNumberGenerator():
    """2
    Generate a random number every 1 second and emit to a socketio instance (broadcast)
    Ideally to be run in a separate thread?
    """
    #infinite loop of magical random numbers
    print("Making random numbers")
    gen = data_stream.read()
    while not thread_stop_event.isSet():
        if data_stream.connected():
            data = next(gen)
            socketio.emit('newdata', {'data': data}, namespace='/test')
        socketio.sleep(0.01)
@app.route('/video_feed')
def video_feed():
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(c.gen_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/')
def index():
    """Video streaming home page."""
    return render_template('index.html')

@socketio.on('connect', namespace='/test')
def test_connect():
    # need visibility of the global thread object
    global thread
    print('Client connected')

    #Start the random number generator thread only if the thread has not been started before.
    if not thread.is_alive():
        print("Starting Thread")
        thread = socketio.start_background_task(randomNumberGenerator)

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')

socketio.run(app)


#!/usr/bin/python3

'''
Downloading/Updating Color spreads of One Piece from the fandom site.

Usage:
python ./OP-ColorSpreads-CLI.py
    --> will download all the images in the current directory

python ./OP-ColorSpreads-CLI.py -p "{PATH-TO-UPDATE}"
    --> will download in the provided directory the latest color spreads. (can also be used to download all to a specific directory)
    --> do not end the path with a "/", it may break the script. to lazy to handle error...
'''

import requests
from bs4 import BeautifulSoup
import os
import argparse

# URL where there is a list of all the imgs to download
baseUrl = "https://onepiece.fandom.com/wiki/Category:Color_Spreads"

## Cleanup output
LINE_UP = '\033[1A'
LINE_CLEAR = '\x1b[2K'

# PARAMETER verification
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--pathToUpdate", type=str, required=False)
args = parser.parse_args()

if args.pathToUpdate:
    imgPath = args.pathToUpdate
    localImgList = []
    for item in os.listdir(imgPath):
        if (os.path.isfile(f"{imgPath}/{item}")) and ((item.endswith(".png")) or (item.endswith(".jpg")) or (item.endswith(".jpeg"))):
            localImgList.append(item)
    print(f"Updating {imgPath} --> number of local images : {len(localImgList)}")
    update = True
else:
    imgPath = (os.getcwd()).replace("\\", "/")
    print(f"Downloading all images in current folder: {imgPath}")
    update = False

# DEFINITION
def DownloadImg(session, url,name,path):
    '''
    Download the content of a get request.
    '''
    r = session.get(url)
    if r.status_code == 200:
        with open(path + "/" + name, 'wb') as f:
            f.write(r.content)
    else:
        print(f"Failed to get: {url} -- Status Code: {r.status_code}")

# Session
s = requests.Session()
# Base GET request
r = s.get(baseUrl)
if r.status_code == 200:
    print(f"{baseUrl}: 200 - OK")
    # Parse Base HTML
    soup = BeautifulSoup(r.text, 'html.parser')
    lis = (soup.find('ul',{"class": "category-page__members-for-char"})).find_all('li')
    # Populate a list of remote image names
    remoteImgList = []
    for li in lis:
        imgSrc = li.find('img')['src']
        imgUrl = imgSrc.split("/revision/")[0]
        imgName = imgUrl.split("/")[-1]
        remoteImgList.append(imgName)

    print(f"Total number of remote images: {len(remoteImgList)}")
    # Download images following the passed parameter.
    if update:
        if sorted(remoteImgList) == sorted(localImgList):
            print(f"{imgPath} up-to-date. No new images to download")
        else:
            counter = 0
            for li in lis:
                imgSrc = li.find('img')['src']
                imgUrl = imgSrc.split("/revision/")[0]
                imgName = imgUrl.split("/")[-1]

                if imgName not in localImgList:
                    print(f"Downloading: {imgName} in {imgPath}")
                    print(LINE_UP, end=LINE_CLEAR)
                    DownloadImg(s, imgUrl, imgName, imgPath)
                    counter += 1

            print(f"Downloaded {counter} images in {imgPath}")
    else:
        counter=0
        for li in lis:
            imgSrc = li.find('img')['src']
            imgUrl = imgSrc.split("/revision/")[0]
            imgName = imgUrl.split("/")[-1]

            print(f"Downloading: {imgName}")
            print(LINE_UP, end=LINE_CLEAR)
            DownloadImg(s, imgUrl, imgName, imgPath)
            counter += 1
        print(f"Downloaded {counter} images in {imgPath}")
else:
    print(f"{baseUrl}: {r.status_code} - NOT OK")


import pandas as pd
import os
import glob

# use glob to get all excel files in the folder
path = os.getcwd()
excel_files = glob.glob(os.path.join(path,"*.xlsx"))

#loop over the list of excel files
for f in excel_files:
    #read the csv file
    df = pd.read_excel(f)
    # delete unwanted columns

    newdf = df.drop(["Unnamed: 0"],axis='columns')

    newdf['Date '] = newdf['Date'].dt.strftime('%m/%d/%Y')

# shift column 'Date ' to second position
    date_column = newdf.pop('Date ')

# insert column using insert(position,column_name,
# first_column) function
    newdf.insert(2, 'Date ', date_column)
    newdf = newdf.drop(["Date"],axis='columns')

    sum_row = newdf[["Amount"]].sum()
    df_sum=pd.DataFrame(data=sum_row).T
    df_sum=df_sum.reindex(columns=df.columns)
    df_final=newdf.append(df_sum,ignore_index=True)
    new_f_df = df_final.dropna(how="all", axis=1)

    print(new_f_df.tail())
    new_f_df.info()

    new_f_df.to_excel(os.path.join('final_files', f ))

#    resources
        # https://www.journaldev.com/33492/pandas-dropna-drop-null-na-values-from-dataframe#:~:text=Pandas%20DataFrame%20dropna()%20function%20is%20used%20to%20remove%20rows,null%20values%20using%20None%2C%20pandas.


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

# Always prefer setuptools over distutils
from setuptools import setup, find_packages
from codecs import open  # To use a consistent encoding
from os import path
import io

NAME = "trading_ig"
filename = "%s/version.py" % NAME
with open(filename) as f:
    exec(f.read())

here = path.abspath(path.dirname(__file__))

def readme():
    filename = path.join(here, "README.rst")
    with io.open(filename, "rt", encoding="UTF-8") as f:
        return f.read()

setup(
    name=NAME,
    # Versions should comply with PEP440.  For a discussion on single-sourcing
    # the version across setup.py and the project code, see
    # https://packaging.python.org/en/latest/development.html#single-sourcing-the-version
    # version='0.0.1',
    version=__version__,
    description="A lightweight wrapper for the IG Markets API written in Python",
    long_description=readme(),
    # The project's main homepage.
    url=__url__,
    # Author details
    author=__author__,
    author_email=__author_email__,
    # Choose your license
    license=__license__,
    # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
    classifiers=[
        # How mature is this project? Common values are
        #   3 - Alpha
        #   4 - Beta
        #   5 - Production/Stable
        "Development Status :: 3 - Alpha",
        # Indicate who your project is intended for
        "Environment :: Console",
        # 'Topic :: Software Development :: Build Tools',
        "Intended Audience :: Science/Research",
        "Operating System :: OS Independent",
        # Specify the Python versions you support here. In particular, ensure
        # that you indicate whether you support Python 2, Python 3 or both.
        "Programming Language :: Cython",
        "Programming Language :: Python",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Topic :: Scientific/Engineering",
        # Pick your license as you wish (should match "license" above)
        "License :: OSI Approved :: BSD License",
    ],
    python_requires='>=3.6',
    # What does your project relate to?
    keywords="trading, spread betting, CFDs",
    # You can just specify the packages manually here if your project is
    # simple. Or you can use find_packages().
    packages=find_packages(exclude=["contrib", "docs", "tests*"]),
    # List run-time dependencies here.  These will be installed by pip when your
    # project is installed. For an analysis of "install_requires" vs pip's
    # requirements files see:
    # https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files
    install_requires=[
        "munch==2.5.0",
        "pycryptodome==3.9.8",
        "requests==2.24.0",
        "requests-cache==0.5.2",
        "six==1.15.0",
        "pandas==1.0.5",
    ],  # bunch->lunch->infi.bunch->munch
    # List additional groups of dependencies here (e.g. development dependencies).
    # You can install these using the following syntax, for example:
    # $ pip install -e .[dev,test]
    extras_require={"dev": ["check-manifest", "pytest"], "test": ["pytest", "pytest-cov"],},
    # If there are data files included in your packages that need to be
    # installed, specify them here.  If using Python 2.6 or less, then these
    # have to be included in MANIFEST.in as well.
    # package_data={
    #    'sample': ['logging.conf'],
    # },
    # Although 'package_data' is the preferred approach, in some case you may
    # need to place data files outside of your packages.
    # see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
    # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
    # data_files=[('my_data', ['data/data_file'])],
    # To provide executable scripts, use entry points in preference to the
    # "scripts" keyword. Entry points provide cross-platform support and allow
    # pip to create the appropriate form of executable for the target platform.
    entry_points={"console_scripts": ["sample=sample:main",],},
)


from django.shortcuts import render,redirect,get_object_or_404
from rest_framework.decorators import api_view
from .models import Receita
from .forms import Receita_Form

# Create your views here.

@api_view(['GET'])
def listar_receitas(request):
    receita = Receita.objects.all()
    qtde_receita = len(receita)
    return render(request,"receita/listar_receitas.html",{"receitas":receita,"qtde":qtde_receita})

def detalhes_receita(request,id=None,*args,**kwargs):
    receita = get_object_or_404(Receita,id = id)
    return render(request,"receita/detalhes_receita.html",{"receita":receita})

def receita(request):
    if request.method == "GET":
        form = Receita_Form()
        context = {
            'form':form
        }
        return render(request,"receita/cadastrar_receita.html",context=context)
    else:
        form = Receita_Form(request.POST)
        if form.is_valid():
            receita = form.save()
            form = Receita_Form()
        context = {
        'form':form
            }
        return render(request,"receita/cadastrar_receita.html",context=context)

def editar_receita(request,id_receita):
    if request.method == "GET":
        receita = Receita.objects.filter(id=id_receita).first()
        form = Receita_Form(instance=receita)
        context = {
            'form':form,
        }
        return render(request,"receita/cadastrar_receita.html",context=context)

    elif request.method == "POST":
        receita = Receita.objects.filter(id=id_receita).first()
        form = Receita_Form(request.POST,instance=receita)
        if form.is_valid():
            form.save()
            return redirect("/")
        else:
            context = {
            'form':form,
            }
            return render(request,"receita/cadastrar_receita.html",context=context)

def excluir_receita(request,id_receita):
    Receita.objects.filter(id=id_receita).delete()
    return redirect("/")


"""
High level functions
--------------------

"""
from . import solubility as sol
from .area import get_area_from_dataset

def flux_bulk(
    temp_C,
    salt,
    pCO2_sea_uatm,
    pCO2_air_uatm,
    pres_hPa,
    kw_cmhr,
):
    """
    Calculates bulk air-sea CO2 fluxes

    .. math::
        FCO_2 = k_w \\cdot K_0 \\cdot \\Delta pCO_2

    Args:
        temp_C (array): temperature from OISST in degCelcius with an allowable
            range of [-2:45]
        salt (array): salinity from EN4 in PSU. Allowable range [5 : 50]
        pCO2_sea_uatm (array): partial pressure of CO2 in the sea in micro-atmospheres.
            Allowable range is [50 : 1000]
        pCO2_air_uatm (array): partial pressure of CO2 in the air in micro-atmospheres.
            Allowable range is [50 : 1000].
        press_hPa (array): atmospheric pressure in hecto-Pascals with allowable range [500:1500]
        kw_cmhr (array): the gas transfer velocity in (cm/hr). Given the careful choices
            involved in estimating kw, we require the user to explicitly provide kw.
            kw can be calculated with pyseaflux.gas_transfer_velocity.<func>. Things to be
            aware of when calculating kw: wind product and scaling coeffient of gas transfer,
            resolution resampling, and the formulation (i.e. quadratic, cubic).

    Returns:
        array:
            Sea-air CO2 flux where positive is out of the ocean and negative is
            into the ocean. Units are gC.m-2.day-1 (grams Carbon per metre squared
            per day). If the input is an xarray.DataArray, then the output will be
            a data array with fluxes, globally integrated flux, and the area used to
            integrate the fluxes.
    """
    import xarray as xr

    pres_atm = pres_hPa / 1013.25
    temp_K = temp_C + 273.15

    pCO2sea = pCO2_sea_uatm * 1e-6  # to atm
    pCO2air = pCO2_air_uatm * 1e-6

    K0 = sol.solubility_weiss1974(salt, temp_K, pres_atm)

    """unit analysis
    kw = (cm . hr-1) * hr . day-1 . cm-1 . m
    kw = m . day-1   """
    kw = kw_cmhr * (24 / 100)

    # molar mas of carbon in g . mmol-1
    mC = 12.0108 * 1000  # (g . mol-1) / (mmol . mol-1)

    """ unit analysis
    flux = (m . day-1) .  (mol . L-1 . atm-1) . atm . (gC . mmol-1)
    flux = (m . day-1) . (mmol . m-3 . atm-1) . atm . (gC . mmol-1)
    flux = gC . m-2 . day-1   """
    CO2flux_bulk = kw * K0 * (pCO2sea - pCO2air) * mC

    if isinstance(CO2flux_bulk, xr.DataArray):
        area = get_area_from_dataset(CO2flux_bulk)
        ds = xr.Dataset()
        ds["fgco2"] = CO2flux_bulk.assign_attrs(
            units="gC/m2/day",
            description="Air sea CO2 fluxes calculated using the bulk formulation.",
        )
        ds["area"] = area
        ds["fgco2_global"] = (
            (CO2flux_bulk * area * 365)
            .sum(["lat", "lon"])
            .assign_attrs(units="gC/Yr", description="integrated fluxes fgco2 * area")
        )
        return ds
    else:
        return CO2flux_bulk


# Jesus Carlos Martinez Gonzalez
# 17/08/2023
# Donation rewards (https://www.codechef.com/problems/DOREWARD)

"""
On the occasion of World Blood Donor Day, Chef has organized an event to reward regular blood
donars in Chefland.
• Ifthe donor has made less than or equal to 3 donations, they receive a BRONZE donor badge.
• Ifthe donor has made more than 3 but less than equal to 6 donations, they receive a SILVER donor
badge.
• Ifthe donor has made more than 6 donations, they receive a GOLD donor badge.
Given that a person has made X donations, find the badge they receive.
"""

for _ in range(int(input())):
    x = int(input())
    if x <= 3:
        print("BRONZE")
    elif x <= 6:
        print("SILVER")
    else:
        print("GOLD")


from queue import PriorityQueue

def ifExists(pQueue, X, Y):
    if pQueue.empty():
        return False

    for ele in pQueue.queue:
        if ele[1] == X and ele[2] == Y:
            return ele
    return False

def printInFileAS(visited, key):
    pass

def heuristic(curr_X, curr_Y, lodge_X, lodge_Y):
    return (pow(curr_X - lodge_X, 2) + pow(curr_Y - lodge_Y, 2))

def calcPathCost(Enext, Ecurr, M, HMC):
    if Enext - Ecurr <= M:
        return HMC
    else:
        return max(0, Enext - Ecurr - M) + HMC

def expandAS(children, curr_X, curr_Y, mtrx, height, width, stamina, visited, parent_cost, lodge_X, lodge_Y):

    pass

def aStarSearch(start_Y, start_X, stamina, lodge_coordinates, mtrx, height, width):
    for lodge in lodge_coordinates:
        flag = 1
        open_queue = PriorityQueue()
        close = PriorityQueue()
        visited = {}

        open_queue.put((0 + heuristic(start_X, start_Y, lodge[1], lodge[0]), 0, (start_X, start_Y)))

        while not open_queue.empty():
            currNode = open_queue.get()

            children = PriorityQueue()
            expandAS(children, currNode[2][0], currNode[2][1], mtrx, height, width, stamina, visited, currNode[1], lodge[1], lodge[0])

            while not children.empty():
                child = children.get()

                if child[2][0] == lodge[1] and child[2][1] == lodge[0]:
                    printInFileAS(visited, currNode[2])
                    flag = 0
                    print("YAAAAAYYYYYYYYYYY")
                    break

                checkOpen = ifExists(open_queue, child[2][0], child[2][1])
                checkClosed = ifExists(close, child[2][0], child[2][1])

                if checkOpen != False:
                    pass

def main():
    input_file = open("input.txt", "r")
    lines = input_file.readlines()
    data = [line.strip() for line in lines]

    algorithm = data[0] #algortihm to be used
    data[1] = data[1].split(" ")
    width, height = int(data[1][0]), int(data[1][1]) #get height and width of mtrx3

    data[2] = data[2].split(" ")
    start_X, start_Y = int(data[2][0]), int(data[2][1]) #get starting coordinates

    stamina = int(data[3])

    no_of_lodges = int(data[4])

    lodges_coordinates = []

    for i in range(0, no_of_lodges):
        data[4+1+i] = data[4+1+i].split(" ")
        temp = (int(data[4+1+i][0]), int(data[4+1+i][1]))
        lodges_coordinates.append(temp)
        i = i+1

    mtrx = []

    for i in range(0, height):
        idx = 4 + no_of_lodges + i + 1
        data[idx] = data[idx].split(" ")
        res = [eval(i) for i in data[idx]]
        mtrx.append(res)
        i = i + 1

    fp = open('output.txt', 'w')

    if algorithm == "A*":
        aStarSearch(start_X, start_Y, stamina, lodges_coordinates, mtrx, height, width)

if __name__ == "__main__":
    main()


# A module to parse commands embedded into the tests themselfes
from functools import partial
from steps     import create_step_append_flags
import logging
import re
import sys

_LOGGER = logging.getLogger("sisyphus")

def _check_regex(result, regex, txt, count, expected_result):
    realcount = 0
    for line in result.stdout.splitlines():
        if regex.search(line):
            realcount += 1
            if realcount > count:
                break
    if not expected_result and realcount > 0:
        result.error = "!check '%s' failed" % (txt,)
    elif expected_result and count == 0 and realcount == 0:
        result.error = "check '%s' failed" % (txt,)
    elif count > 0 and realcount != count:
        assert expected_result
        result.error = "check[%s] '%s' failed" % (count, txt,)

def _embedded_add_check(regex_string, count_arg, flag):
    """create a regex check (for assembler output)"""
    c = 0
    if count_arg:
        if flag:
            c = int(count_arg[1:-1])
        else:
            raise Exception("!check cannot be used with an argument")
    regex = re.compile(regex_string)
    return partial(_check_regex, regex=regex, txt=regex_string, count=c, expected_result=flag)

def _parse_embedded_command(cmd, flags, asm_checks):
    """parse one /*$ $*/ embedded command"""
    cmdre = re.compile("(!?check(\[[0-9]+\])?|cflags|ldflags)(.*)")
    m = cmdre.match(cmd)
    if m:
        base = m.group(1)
        if m.group(2):
            base = base[0:-len(m.group(2))]
        if m.group(3):
            arg = m.group(3).strip()

        if base == "check":
            check = _embedded_add_check(arg, m.group(2), True)
            asm_checks.append(check)
        elif base == "!check":
            check = _embedded_add_check(arg, m.group(2), False)
            asm_checks.append(check)
        elif base == "cflags":
            flags["cflags"] += " %s" % (arg,)
        elif base == "ldflags":
            flags["ldflags"] += " %s" % (arg,)
        else:
            _LOGGER.error("unsupported embedded command %s" % base)
    else:
        # treat as a cflag option
        flags["cflags"] += " %s" % (cmd.strip(), )

def parse_embedded_commands(test, filename, asm_step_factory=None):
    """Parse a given file for embedded test commands (/*$ ... $*/ sequences).
    Modifies the test and adds an additional assembly generation step with the
    asm_step callback if necessary."""
    cmd_regex  = re.compile("/\\*\\$ (.+) \\$\\*/")
    asm_checks = []
    flags      = dict(cflags="", ldflags="")
    for line in open(filename, "rb"):
        m = cmd_regex.match(line)
        if m:
            cmd = m.group(1)
            _LOGGER.info("%s: embedded cmd %s\n" % (filename, cmd))
            _parse_embedded_command(cmd, flags, asm_checks)
    if len(asm_checks) > 0:
        step = asm_step_factory()
        step.add_checks(asm_checks)
    if flags["cflags"] != "":
        test.prepend_step("embedded_cflags", create_step_append_flags(cflags=flags["cflags"]))
    if flags["ldflags"] != "":
        test.prepend_step("embedded_ldflags", create_step_append_flags(ldflags=flags["ldflags"]))


"""056- Desenvolva um programa leia o nome,idaade
 e sexo de 4 pessoas. No final do programa mostre:
 - A média da idades do grupo
 - Qual é o nome do homem mais velho
 - Quantas mulheres têm menos de 20 anos.
 """
soma=0
media=0
contagem=0
mVelho=0
for contador in range(1,5):
    print('-----{}ª PESSOA-------'.format(contador))
    nome=str(input('Escreva o nome: '))
    idade=int(input('Escreva a idade: '))
    sexo=str(input('Escreva o sexo: ')).upper()
    soma+=idade
    media=soma/4
if sexo == 'FEMININO' and idade < 20:
    contagem=contagem+1

elif sexo=='MASCULINO':
    if idade > mVelho:
        mVelho=idade
        name=nome
else:
    print('Não tem macho aqui')

print(' A media de idade do grupo é {}:'.format(media))
print('A quantidade de mulheres com menos de 20 anos é: {}'.format(contagem))
print('O nome do homem mais velho é: {}'.format(name))