import json
import operator

from functools import reduce

from mailchimp3 import MailChimp
from easy_thumbnails.files import get_thumbnailer
from ipware.ip import get_client_ip as get_ip

from cms.models import Title
from django.db.models.functions import Lower
from django.contrib import messages
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import get_language_from_request
from django.utils.html import strip_tags
from django.utils.text import Truncator
from django.shortcuts import redirect
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.template.defaultfilters import slugify
from django.core.management import call_command
from django.core.mail import send_mail
from django.db.models import Q

from rest_framework.generics import GenericAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response as RestResponse
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import PermissionDenied

from shop.models.defaults.customer import Customer
from shop.modifiers.pool import cart_modifiers_pool
from shop.models.order import OrderModel
from shop.rest.renderers import CMSPageRenderer
from shop.views.order import OrderView
from shop.serializers.auth import PasswordResetConfirmSerializer

from dal import autocomplete

from dshop.models import Product, ProductFilterGroup, ProductFilter
from dshop.models import Attribute, \
    AttributeValue, ProductCategory, ProductBrand

from settings import DEFAULT_FROM_EMAIL, DEFAULT_TO_EMAIL, THEME_SLUG
from settings import MAILCHIMP_KEY, MAILCHIMP_LISTID

from shop.views.auth import AuthFormsView as ShopAuthFormView
from django.core.exceptions import NON_FIELD_ERRORS
from rest_framework.response import Response
from shop.models.customer import CustomerModel

from feature_settings import QUOTATION

try:
    from apps.dmRabais.models import dmCustomerPromoCode
except ImportError:
    dmCustomerPromoCode = None

#######################################################################
# ===---   OrderView Bug fix                                   ---=== #
#######################################################################

class OrderPermission(BasePermission):
    """
    Allow access to a given Order if the user is entitled to.
    """
    def has_permission(self, request, view):
        if view.many and request.customer.is_visitor:
            detail = _("Only signed in customers can \
                view their list of orders.")
            raise PermissionDenied(detail=detail)
        return True

    def has_object_permission(self, request, view, order):
        if request.user.is_authenticated and \
           not request.user.is_staff and \
           not request.user.is_superuser:
            return order.customer.pk == request.user.pk
        if order.secret and \
           order.secret == view.kwargs.get('secret') or \
           request.user.is_staff or \
           request.user.is_superuser:
            return True
        detail = _("This order does not belong to you.")
        raise PermissionDenied(detail=detail)

class OrderView(OrderView):

    permission_classes = [OrderPermission]

    def get_queryset(self):
        queryset = OrderModel.objects.all()
        if self.request.customer.user.is_staff or \
           self.request.customer.user.is_superuser:
            return queryset
        if self.request.customer.is_visitor:
            return queryset.none()
        if self.request.customer.is_authenticated:
            queryset = queryset.filter(
                customer=self.request.customer
            ).order_by('-updated_at')
        return queryset

#######################################################################
# ===---   Views used in products                              ---=== #
#######################################################################

class DshopProductListView(APIView):

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):  # noqa: C901
        attribute = self.request.query_params.get('attribute', None)
        category = self.request.query_params.get('category', None)
        fltr = self.request.query_params.get('filter', None)
        brand = self.request.query_params.get('brand', None)
        response_type = self.request.query_params.get('type', None)
        offset = int(request.GET.get("offset", 0))
        limit = int(request.GET.get("limit", 9))
        sortby = request.COOKIES.get("dm_psortby", "default")
        if sortby == "date-new":
            orderby = "-created_at"
        elif sortby == "date-old":
            orderby = "created_at"
        elif sortby == "alpha-asc":
            orderby = Lower("product_name")
        elif sortby == "alpha-des":
            orderby = Lower("product_name").desc()
        elif sortby == "price-asc":
            orderby = "get_p"
        elif sortby == "price-des":
            orderby = "-get_p"
        else:
            orderby = "order"

        products = Product.objects.filter(
            Q(categories__active=True) | Q(categories=None),
            active=True
        )
        if request.LANGUAGE_CODE == "fr":
            title = 'Produits'
        else:
            title = 'Products'
        current_category = None
        current_brand = None
        if 'category_id' in kwargs:
            products = products.filter(categories__id=kwargs['category_id'])
            cat = ProductCategory.objects.filter(
                id=kwargs['category_id']
            ).first()
            if cat:
                current_category = cat
                title = cat.name
        elif 'brand_id' in kwargs:
            products = products.filter(brand=kwargs['brand_id'])
            brnd = ProductBrand.objects.filter(id=kwargs['brand_id']).first()
            if brnd:
                current_brand = brnd
                title = brnd.name

        if category:
            category = [val for val in category.split(',') if val]
            if len(category) > 0:
                q = reduce(
                    operator.and_, (Q(categories__id=i) for i in category)
                )
                products = products.exclude(~q).distinct()
            else:
                products = products.distinct()

        if fltr:
            fltr = [val for val in fltr.split(',') if val]
            if len(fltr) > 0:
                q = reduce(
                    operator.and_, (Q(filters__id=i) for i in fltr)
                )
                products = products.exclude(~q).distinct()
            else:
                products = products.distinct()

        if brand:
            brand = [val for val in brand.split(',') if val]
            if len(brand) > 0:
                q = reduce(
                    operator.and_, (Q(brand__id=i) for i in brand)
                )
                products = products.exclude(~q).distinct()
            else:
                products = products.distinct()

        if attribute:
            attributes = [val for val in attribute.split(',') if val]
            attributes = AttributeValue.objects.filter(id__in=attributes)
            attributes = [atr.value for atr in attributes]
            ids = []
            for q in products:
                attrs = []
                try:
                    for var in q.variants.all():
                        attrs += [
                            val[0] for val in
                            var.attribute.all().values_list('value')
                        ]
                except Exception:
                    continue

                for atr in attributes:
                    if atr in attrs:
                        ids.append(q.id)
                        break
            if len(ids) > 0:
                q = reduce(
                    operator.and_, (Q(id=i) for i in ids)
                )
                products = products.exclude(~q).distinct()
            else:
                products = products.distinct()

        if orderby == 'get_p':
            products = sorted(
                products.distinct(),
                key=lambda product: product.get_price(request)
            )
        elif orderby == '-get_p':
            products = sorted(
                products.distinct(),
                key=lambda product: product.get_price(request),
                reverse=True
            )
        else:
            products = products.order_by(orderby)
        categories = ProductCategory.objects.filter(parent=None, active=True)
        brands = ProductBrand.objects.all()
        filters = ProductFilter.objects.all()
        next_page = False

        if not type(products) == list:
            products = products.distinct()

        if len(products) > offset + limit:
            products = products[offset:limit]
            next_page = True
        else:
            products = products[offset:]
        filter_data = LoadFilters.as_view()(request=request._request).data
        data = {
            'products': products,
            'brands': brands,
            'categories': categories,
            'filters': filters,
            'filter_data': filter_data,
            'is_quotation': QUOTATION,
            'title_str': title,
            'current_category': current_category,
            'current_brand': current_brand,
            'next': next_page
        }

        if not response_type:
            return render(
                request,
                'theme/{}/pages/produits.html'.format(THEME_SLUG),
                context=data
            )
        # ===---
        all_produits = []
        for produit in products:
            data = {}
            data['name'] = produit.product_name_trans
            data['url'] = produit.get_absolute_url()
            data['caption'] = strip_tags(Truncator(produit.caption).words(18))
            data['slug'] = produit.slug
            try:
                if produit.main_image:
                    data['image'] = get_thumbnailer(
                        produit.main_image).get_thumbnail({
                            'size': (540, 600),
                            'upscale': True,
                            'background': "#ffffff"
                        }).url
                elif produit.images.first():
                    data['image'] = get_thumbnailer(
                        produit.images.first()).get_thumbnail({
                            'size': (540, 600),
                            'upscale':
                            True,
                            'background':
                            "#ffffff"
                        }).url
                else:
                    data['image'] = None
            except Exception:
                data['image'] = None
            if produit.filters.all():
                data['filters'] = " ".join(
                    [slugify(d.name) for d in produit.filters.all()]
                )
            else:
                data['filters'] = None
            if produit.label:
                data['label'] = {}
                data['label']['name'] = produit.label.name
                data['label']['colour'] = produit.label.colour
                data['label']['bg_colour'] = produit.label.bg_colour
            else:
                data['label'] = None
            if hasattr(produit, 'variants'):
                data['variants'] = True
                data['variants_count'] = produit.variants.all().count()
                if produit.variants.first():
                    data['variants_product_code'] = produit.variants.first(
                    ).product_code
                    data['price'] = produit.variants.first().get_price(request)
                    data['realprice'] = produit.variants.first().unit_price
                    data['is_discounted'] = False
                    for v in produit.variants.all():
                        if v.is_discounted:
                            data['is_discounted'] = True
                    data['quantity'] = 0
                    for v in produit.variants.all():
                        if v.quantity > 0:
                            data['quantity'] = v.quantity
                else:
                    data['variants_product_code'] = ""
                    data['price'] = "-"
                    data['is_discounted'] = False
                    data['quantity'] = 0
            else:
                data['product_code'] = produit.product_code
                data['price'] = produit.get_price(request)
                data['realprice'] = produit.unit_price
                data['variants'] = False
                data['variants_count'] = 0
                data['is_discounted'] = produit.is_discounted
                data['quantity'] = produit.quantity
            data['is_quotation'] = QUOTATION
            all_produits.append(data)
        # ===---
        result = {"products": all_produits, "next": next_page}
        return RestResponse(result)

class LoadFilters(APIView):

    def get(self, request, *args, **kwargs):
        groups = ProductFilterGroup.objects.all()
        data = {}
        # ===--- Filters with group
        for group in groups:
            temp = {}
            filters = []
            subfilt = ProductFilter.objects.filter(group=group)
            if subfilt.count() > 0:
                temp['id'] = group.id
                temp['order'] = group.order
                for filt in subfilt:
                    url = ''
                    if filt.image:
                        url = filt.image.url
                    try:
                        if filt.name_trans:
                            name = filt.name_trans
                        else:
                            name = filt.name
                    except Exception:
                        name = filt.name
                    # ===---
                    filters.append({
                        'id': filt.id,
                        'name': name,
                        'order': filt.order,
                        'image': url,
                        'description': ''
                    })
                temp['filter'] = filters
                if group.name_trans:
                    group_name = group.name_trans
                else:
                    group_name = group.name
                data[group_name] = temp
        temp = {}
        # ===--- Filters without group
        filters = []
        for filt in ProductFilter.objects.filter(group=None):
            try:
                name = filt.name_trans if filt.name_trans else filt.name
            except Exception:
                name = filt.name
            filters.append({'id': filt.id, 'name': name, 'order': filt.order})
        data['default'] = {'filter': filters}
        # ===---

        a_data = {}
        for attr in Attribute.objects.all():
            try:
                name = attr.name_trans if attr.name_trans else attr.name
            except Exception:
                name = attr.name
            a_data[name] = {}
            a_data[name]["id"] = attr.id
            a_data[name]["values"] = []
            for val in AttributeValue.objects.filter(attribute=attr):
                try:
                    value = val.value_trans if val.value_trans else val.name
                except Exception:
                    value = val.name
                a_data[name]["values"].append({
                    'id': val.id,
                    'name': value
                })

        categories = ProductCategory.objects.filter(parent=None, active=True)
        cat_data = []
        for cat in categories:
            try:
                name = cat.name_trans if cat.name_trans else cat.name
            except Exception:
                name = cat.name
            cat_d = {'id': cat.id, 'name': name}
            child_c = []
            categories = ProductCategory.objects.filter(
                parent=cat, active=True
            )
            for child in categories:
                try:
                    if child.name_trans:
                        child_name = child.name_trans
                    else:
                        child_name = child.name
                except Exception:
                    child_name = child.name
                child_c.append({'id': child.id, 'name': child_name})
            cat_d['child'] = child_c
            cat_data.append(cat_d)

        brands = []
        for brand in ProductBrand.objects.all():
            brands.append({'id': brand.id, 'name': brand.name})

        return RestResponse({
            'filter': data,
            'attribute': a_data,
            'categories': cat_data,
            'brands': brands
        })

class LoadProduits(APIView):
    """
    Retrieve products.

    GET
    ===

    :param category (int)
    :param offset (int)
    :param limit (int)

    :return An object with the list of Products in "products"
    and the count of Products in the next page in "next".
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):  # noqa: C901
        category = request.GET.get("category", None)
        brand = request.GET.get("brand", None)
        offset = int(request.GET.get("offset", 0))
        limit = int(request.GET.get("limit", 2))
        # ===---
        sortby = request.COOKIES.get("dm_psortby", "default")
        if sortby == "date-new":
            orderby = "-created_at"
        elif sortby == "date-old":
            orderby = "created_at"
        elif sortby == "alpha-asc":
            orderby = "product_name"
        elif sortby == "alpha-des":
            orderby = "-product_name"
        elif sortby == "price-asc":
            orderby = "order"
        elif sortby == "price-des":
            orderby = "order"
        else:
            orderby = "order"
        # ===---
        try:
            is_quotation = QUOTATION_FEATURE # noqa
        except Exception:
            is_quotation = False
        if category is not None:
            category = int(category)
            products = Product.objects.filter(
                Q(categories=category) | Q(categories__parent=category)
                | Q(categories__parent__parent=category)
                | Q(categories__parent__parent__parent=category),
                active=True).order_by(orderby).distinct()
            next_products = Product.objects.filter(
                Q(categories=category) | Q(categories__parent=category)
                | Q(categories__parent__parent=category)
                | Q(categories__parent__parent__parent=category), active=True
            ).order_by(orderby).distinct()[
                offset + limit:offset + limit + limit
            ].count()
        elif brand is not None:
            brand = int(brand)
            products = Product.objects.filter(
                Q(brand=brand), active=True
            ).order_by(orderby).distinct()
            next_products = Product.objects.filter(
                brand=brand, active=True
            ).order_by(orderby).distinct()[
                offset + limit:offset + limit + limit
            ].count()
        else:
            products = Product.objects.filter(
                Q(categories__active=True) | Q(categories=None),
                active=True
            ).order_by(orderby).distinct()
            next_products = Product.objects.filter(
                Q(categories__active=True) | Q(categories=None),
                active=True
            ).order_by(orderby).distinct()[
                offset + limit:offset + limit + limit
            ].count()
        # ===---
        if sortby == "price-asc":
            products = sorted(
                products, key=lambda t: t.get_price(request)
            )
        elif sortby == "price-des":
            products = sorted(
                products, key=lambda t: t.get_price(request),
                reverse=True
            )
        # ===---
        products = products[offset:offset+limit]
        # ===---
        all_produits = []
        for produit in products:
            data = {}
            data['name'] = produit.product_name_trans
            data['url'] = produit.get_absolute_url()
            data['caption'] = strip_tags(Truncator(produit.caption).words(18))
            data['slug'] = produit.slug
            if produit.main_image:
                data['image'] = get_thumbnailer(
                    produit.main_image).get_thumbnail({
                        'size': (540, 600),
                        'upscale': True,
                        'background': "#ffffff"
                    }).url
            elif produit.images.first():
                data['image'] = get_thumbnailer(
                    produit.images.first()).get_thumbnail({
                        'size': (540, 600),
                        'upscale':
                        True,
                        'background':
                        "#ffffff"
                    }).url
            else:
                data['image'] = None
            if produit.filters.all():
                data['filters'] = " ".join(
                    [slugify(d.name) for d in produit.filters.all()])
            else:
                data['filters'] = None
            if produit.label:
                data['label'] = {}
                data['label']['name'] = produit.label.name
                data['label']['colour'] = produit.label.colour
                data['label']['bg_colour'] = produit.label.bg_colour
            else:
                data['label'] = None
            if hasattr(produit, 'variants'):
                data['variants'] = True
                data['variants_count'] = produit.variants.all().count()
                if produit.variants.first():
                    data['variants_product_code'] = produit.variants.first(
                    ).product_code
                    data['price'] = produit.variants.first().get_price(request)
                    data['realprice'] = produit.variants.first().unit_price
                    data['is_discounted'] = False
                    for v in produit.variants.all():
                        if v.is_discounted:
                            data['is_discounted'] = True
                    data['quantity'] = 0
                    for v in produit.variants.all():
                        if v.quantity > 0:
                            data['quantity'] = v.quantity
                else:
                    data['variants_product_code'] = ""
                    data['price'] = "-"
                    data['is_discounted'] = False
                    data['quantity'] = 0
            else:
                data['product_code'] = produit.product_code
                data['price'] = produit.get_price(request)
                data['realprice'] = produit.unit_price
                data['variants'] = False
                data['variants_count'] = 0
                data['is_discounted'] = produit.is_discounted
                data['quantity'] = produit.quantity
            data['is_quotation'] = is_quotation
            all_produits.append(data)
        # ===---
        result = {"products": all_produits, "next": next_products}
        return RestResponse(result)

class LoadProductsByCategory(APIView):
    """
    Retrieve products for plugin Products by Category.
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):  # noqa: C901
        category = request.GET.get("category", None)
        products = None
        all_produits = []
        try:
            is_quotation = QUOTATION_FEATURE # noqa
        except Exception:
            is_quotation = False
        if category is not None:
            category = int(category)
            products = Product.objects.filter(
                Q(categories=category) | Q(categories__parent=category)
                | Q(categories__parent__parent=category)
                | Q(categories__parent__parent__parent=category),
                active=True).distinct()[:8]
            # ===---
            all_produits = []
            for produit in products:
                data = {}
                if produit.product_name_trans:
                    data['name'] = produit.product_name_trans
                else:
                    data['name'] = produit.product_name
                data['url'] = produit.get_absolute_url()
                data['caption'] = strip_tags(
                    Truncator(produit.caption).words(18))
                data['slug'] = produit.slug
                if produit.main_image:
                    try:
                        data['image'] = get_thumbnailer(
                            produit.main_image).get_thumbnail({
                                'size': (540, 600),
                                'upscale':
                                True,
                                'background':
                                "#ffffff"
                            }).url
                    except Exception:
                        data['image'] = None
                elif produit.images.first():
                    try:
                        data['image'] = get_thumbnailer(
                            produit.images.first()).get_thumbnail({
                                'size': (540, 600),
                                'upscale':
                                True,
                                'background':
                                "#ffffff"
                            }).url
                    except Exception:
                        data['image'] = None
                else:
                    data['image'] = None
                if produit.filters.all():
                    data['filters'] = " ".join(
                        [slugify(d.name) for d in produit.filters.all()])
                else:
                    data['filters'] = None
                if produit.label:
                    data['label'] = {}
                    data['label']['name'] = produit.label.name
                    data['label']['colour'] = produit.label.colour
                    data['label']['bg_colour'] = produit.label.bg_colour
                else:
                    data['label'] = None
                if hasattr(produit, 'variants'):
                    data['variants'] = True
                    data['variants_count'] = produit.variants.all().count()
                    if produit.variants.first():
                        data['variants_product_code'] = produit.variants.first(
                        ).product_code
                        data['price'] = produit.variants.first(
                            ).get_price(request)
                        data['realprice'] = produit.variants.first(
                            ).unit_price
                        data['is_discounted'] = False
                        for v in produit.variants.all():
                            if v.is_discounted:
                                data['is_discounted'] = True
                        data['quantity'] = 0
                        for v in produit.variants.all():
                            if v.quantity > 0:
                                data['quantity'] = v.quantity
                    else:
                        data['variants_product_code'] = ""
                        data['price'] = "-"
                        data['is_discounted'] = False
                        data['quantity'] = 0
                else:
                    data['product_code'] = produit.product_code
                    data['price'] = produit.get_price(request)
                    data['realprice'] = produit.unit_price
                    data['variants'] = False
                    data['variants_count'] = 0
                    data['is_discounted'] = produit.is_discounted
                    data['quantity'] = produit.quantity
                data['is_quotation'] = is_quotation
                all_produits.append(data)

        # ===---
        result = {"products": all_produits}
        return RestResponse(result)

class LoadVariantSelect(APIView):
    """
    Retrieve product from attribute selected.
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):  # noqa: C901
        product_pk = request.GET.get("product", None)
        attributes = request.GET.get("attributes", None)
        variants = []
        QUOTATION = False
        try:
            QUOTATION = QUOTATION_FEATURE # noqa
        except Exception:
            pass
        if product_pk is not None and attributes is not None:
            attributes = attributes.replace(",", "//separator//").replace(
                "//comma//", ",")
            product = Product.objects.get(pk=product_pk)
            attr_list = attributes.split("//separator//")
            attrs = AttributeValue.objects.none()
            for a in attr_list:
                attrs |= AttributeValue.objects.filter(
                    value=a.split("_____")[1],
                    attribute__name=a.split("_____")[0]
                )
            print(attrs)
            if attrs.count() > 0:
                variant_all = product.variants.all()
            else:
                variant_all = []
            for a in attrs:
                variant_all = variant_all.filter(
                    attribute=a
                )
            for v in variant_all:
                datas = {}
                datas["product_code"] = v.product_code
                datas["unit_price"] = v.unit_price
                datas["quotation"] = 0
                if QUOTATION:
                    datas["quotation"] = 1
                try:
                    datas["real_price"] = v.get_price(request)
                except Exception:
                    datas["real_price"] = v.unit_price
                datas["is_discounted"] = v.is_discounted
                datas["quantity"] = v.quantity
                variants.append(datas)
        # ===---
        result = {"variants": variants}
        return RestResponse(result)

#######################################################################
# ===---   Views used in frontend                              ---=== #
#######################################################################

class CustomerView(APIView):
    """
    Retrieve current customer data
    to be used in the frontend app.

    GET
    ===

    Check if a customer is authenticated.

    Check if customer's shipping address exist.

    Check if customer's billing address exist.

    :return An object with customer basic informations,
    customer's shipping address and customer's billing address.
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        # ===---
        tos = Title.objects.filter(page__reverse_id="terms-and-conditions",
                                   language=request.LANGUAGE_CODE)
        if tos.count() > 0:
            tos = "/" + request.LANGUAGE_CODE + "/" + str(tos.first().slug)
        else:
            tos = ""
        # ===---
        is_visitor = True if request.customer.is_visitor else False
        # ===---
        if request.user.is_authenticated:
            customer = {
                "salutation": request.user.customer.salutation,
                "first_name": request.user.first_name,
                "last_name": request.user.last_name,
                "email": request.user.email,
                "is_visitor": is_visitor
            }
            aso = request.user.customer.shippingaddress_set.first()
            if aso is not None:
                address_shipping = {
                    "active_priority": 1,
                    "plugin_order": 1,
                    "name": aso.name if aso.name is not None else "",
                    "address1":
                    aso.address1 if aso.address1 is not None else "",
                    "address2":
                    aso.address2 if aso.address2 is not None else "",
                    "country": aso.country if aso.country is not None else "",
                    "province":
                    aso.province if aso.province is not None else "",
                    "city": aso.city if aso.city is not None else "",
                    "zip_code":
                    aso.zip_code if aso.zip_code is not None else "",
                    "siblings_summary": []
                }
            else:
                address_shipping = {
                    "plugin_order": 1,
                    "active_priority": "add",
                }
            abo = request.user.customer.billingaddress_set.first()
            if abo is not None:
                address_billing = {
                    "plugin_order": 1,
                    "use_primary_address": False,
                    "name": abo.name if abo.name is not None else "",
                    "address1":
                    abo.address1 if abo.address1 is not None else "",
                    "address2":
                    abo.address2 if abo.address2 is not None else "",
                    "country": abo.country if abo.country is not None else "",
                    "province":
                    abo.province if abo.province is not None else "",
                    "city": abo.city if abo.city is not None else "",
                    "zip_code":
                    abo.zip_code if abo.zip_code is not None else "",
                    "siblings_summary": []
                }
            else:
                address_billing = {
                    "plugin_order": 1,
                    "use_primary_address": True
                }
            ###############
            return RestResponse({
                "customer": customer,
                "address_shipping":
                address_shipping if address_shipping is not None else {},
                "address_billing":
                address_billing if address_billing is not None else {},
                "tos": tos
            })
            ###############
        else:
            return RestResponse({
                "customer": {
                    "plugin_order": 1,
                    "guest": True,
                    "is_visitor": is_visitor
                },
                "address_shipping": {
                    "plugin_order": 1,
                    "active_priority": "add",
                },
                "address_billing": {
                    "plugin_order": 1,
                    "use_primary_address": True,
                },
                "tos": tos
            })

class CustomerCheckView(APIView):
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        email = request.data.get("email", None)
        if email is not None:
            customer = Customer.objects.filter(
                email=email,
                user__is_active=True
            ).count()
            if customer > 0:
                return RestResponse({"exist": True})
            else:
                return RestResponse({"exist": False})
        else:
            return RestResponse({"valid": False})

class ShippingMethodsView(APIView):
    """
    Retrieve all shipping methods
    to be used in the frontend app.

    GET
    ===

    :return An object with all shipping methods.
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        result = [
            m.get_choice()
            for m in cart_modifiers_pool.get_shipping_modifiers()
        ]
        return RestResponse({"shipping_methods": result})

class BillingMethodsView(APIView):
    """
    Retrieve all billing methods
    to be used in the frontend app.

    GET
    ===

    :return An object with all billing methods.
    """

    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        result = [
            m.get_choice()
            for m in cart_modifiers_pool.get_payment_modifiers()
        ]
        return RestResponse({"billing_methods": result})

def make_stored_request(request):
    """
    Create some data from request and
    return an object to be stored in some shop's models
    """

    return {
        'language': get_language_from_request(request),
        'absolute_base_uri': request.build_absolute_uri('/'),
        'remote_ip': get_ip(request),
        'user_agent': request.META.get('HTTP_USER_AGENT'),
    }

def mailchimp(request):
    """
    Evaluate a "calcul" answer.
    If okay, create a member in the client's mailchimp list.

    MAILCHIMP_KEY in settings.py

    MAILCHIMP_LISTID in settings.py
    """

    client = MailChimp(mc_api=MAILCHIMP_KEY)
    email = request.POST.get('email_infolettre', '')
    calcul = request.POST.get('calcul_infolettre', '')
    if calcul == '6':
        try:
            client.lists.members.create(MAILCHIMP_LISTID, {
                'email_address': email,
                'status': 'subscribed',
            })
            messages.success(
                request, _("You successfully been added to our newsletter."))
        except Exception as e:
            print(e)
            messages.error(request, _("An error occurred, sorry."))
            redirect("/")
    else:
        messages.error(request, _("Your answer was wrong."))
    return redirect("/")

def sendemail(request):
    """
    Retrieve form data and send an email
    to the client.
    Then, redirect to the page /message-envoye/.

    DEFAULT_FROM_EMAIL in settings.py

    DEFAULT_TO_EMAIL in settings.py
    """

    send_mail(
        'Message du formulaire de contact de votre site web',
        'Bonjour, voici le message:\n\nNom: ' + request.POST.get('name') +
        '\nCourriel: ' + request.POST.get('email') + '\nTéléphone: ' +
        request.POST.get('phone') + '\nSujet: ' + request.POST.get('subject') +
        '\nMessage:\n' + request.POST.get('message'),
        DEFAULT_FROM_EMAIL,
        [DEFAULT_TO_EMAIL],
        fail_silently=False,
    )
    call_command('send_queued_mail')
    return redirect('/message-envoye/')

#######################################################################
# Password Reset
#######################################################################

class PasswordResetConfirmView(GenericAPIView):
    renderer_classes = (CMSPageRenderer, JSONRenderer, BrowsableAPIRenderer)
    serializer_class = PasswordResetConfirmSerializer
    permission_classes = (AllowAny, )
    form_name = 'password_reset_confirm_form'

    def post(self, request, uidb64=None, token=None):
        try:
            data = dict(request.data['form_data'])
        except (KeyError, TypeError, ValueError):
            errors = {'non_field_errors': [_("Invalid POST data.")]}
        else:
            serializer = self.get_serializer(data=data)
            if serializer.is_valid():
                serializer.save()
                response_data = {
                    self.form_name: {
                        'success_message':
                        _("Password has been reset with the new password."),
                    }
                }
                return RestResponse(response_data)
            else:
                errors = serializer.errors
        return RestResponse({self.form_name: errors},
                            status=status.HTTP_422_UNPROCESSABLE_ENTITY)

@csrf_exempt
def unclone_customers(request):
    data = json.loads(request.body)["form_data"]
    email = data.get("email", None)
    if email is not None:
        users = User.objects.filter(email=email)
        if users.count() > 1:
            i = 0
            for u in users:
                if i > 0:
                    u.email = ""
                    u.save()
                i = i + 1
    return HttpResponse(json.dumps({"valid": True}))

def send_queued_mail(request):
    call_command('send_queued_mail')
    return HttpResponse(json.dumps({"valid": True}))

class AttributeAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        if not self.request.user.is_authenticated:
            return AttributeValue.objects.none()

        qs = AttributeValue.objects.all()

        if self.q:
            qs = qs.filter(
                Q(value__istartswith=self.q) |
                Q(attribute__name__istartswith=self.q)
            )

        return qs

class DshopAuthFormView(ShopAuthFormView):
    serializer_class = None
    form_class = None

    def post(self, request, *args, **kwargs):
        if request.customer.is_visitor:
            customer = CustomerModel.objects.get_or_create_from_request(
                request
            )
        else:
            customer = request.customer
        form_data = request.data.get(self.form_class.scope_prefix, {})
        form = self.form_class(data=form_data, instance=customer)

        if form.is_valid():
            form.save(request=request)
            # Code to merge all inactive user's order
            if form.form_name == "register_user_form":
                new_user = request.user
                new_customer = CustomerModel.objects.get(user=new_user)
                email = form.cleaned_data['email']
                customers = CustomerModel.objects.filter(
                    email=email, user__is_active=False
                )
                for customer in customers:
                    for order in OrderModel.objects.filter(customer=customer):
                        order.customer = new_customer
                        order.save()
                    customer.email = ""
                    customer.save()
                    customer.user.email = ""
                    customer.user.save()
            # End of code
            response_data = {form.form_name: {
                'success_message': _("Successfully registered yourself."),
            }}
            return Response(response_data, status=status.HTTP_200_OK)
        errors = dict(form.errors)
        if 'email' in errors:
            errors.update({NON_FIELD_ERRORS: errors.pop('email')})
        return Response(
            {form.form_name: errors},
            status=status.HTTP_422_UNPROCESSABLE_ENTITY
        )


import os

import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors

def init_youtube(oauth=False):
    """Initialize the YouTube API.
    If ``oauth`` then use the oauth ``client_secret.json`` located in the current directory, otherwise use the ``YT_API_KEY`` environment variable.
    """
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

    api_service_name = "youtube"
    api_version = "v3"
    if oauth:
        scopes = ["https://www.googleapis.com/auth/youtube.force-ssl"]
        client_secrets_file = "client_secret.json"
        flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
            client_secrets_file, scopes
        )
        credentials = flow.run_console()
        youtube = googleapiclient.discovery.build(
            api_service_name, api_version, credentials=credentials
        )
    else:
        DEVELOPER_KEY = os.environ["YT_API_KEY"]
        youtube = googleapiclient.discovery.build(
            api_service_name, api_version, developerKey=DEVELOPER_KEY
        )

    return youtube


#!/bin/bash

import os
import subprocess
import shutil

# python3 utils/build-move.py

docs = "web-docs"

subprocess.call("npm run build", cwd=docs, shell=True)

shutil.copytree(f"{docs}/dist/assets", "docs/assets", dirs_exist_ok=True)

shutil.copy(f"{docs}/dist/index.html", "docs")

with open(f"docs/index.html", 'r') as file:
    data = file.read()
    data = data.replace("/assets", "./assets")

with open(f"docs/index.html", 'w') as file:
    file.write(data)


## Returns ODEs for y
from utilities import *

def y_ODE(y,t,T,C,G,B,params) :

	rho = params["rho"]
	kv = params["kv"]
	#print t

	dy1 = -3*rho*kv*G*(y[3]+y[7])
	dy2 = 0
	dy3 = G*y[1]
	dy4 =  2*G*y[2]
	dy5 = 3*G*y[3]
	dy6 = B
	dy7 = G*y[5]
	dy8 = 2*G*y[6]
	dy9 = 3*G*y[7]

	return [dy1,dy2,dy3,dy4,dy5,dy6,dy7,dy8,dy9]


import json

from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QSlider, QStatusBar, QHBoxLayout, QVBoxLayout,
                             QDesktopWidget, QPushButton, QFileDialog, QHeaderView, QTableView, QStyle, QGroupBox,
                             QLabel, QSpinBox)
from pathlib import Path
from PyQt5.QtCore import Qt
from actilib.analysis.rois import CircleROI, SquareROI
from actilib.gui.TableModel import ROITableModel
from actilib.gui.MplCanvas import MplCanvas

def roi_from_row(row):
    if row[1] == 'Square':
        return SquareROI(row[4], row[2], row[3])
    elif row[1] == 'Circle':
        return CircleROI(row[4] / 2.0, row[2], row[3])
    raise ValueError

class RoiCreator(QMainWindow):
    def __init__(self):
        super(RoiCreator, self).__init__()

        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)

        self.canvas = MplCanvas()
        self.roimodel = ROITableModel()
        self.roitable = QTableView()
        self.roitable.setModel(self.roimodel)

        self.spb_slice_first = QSpinBox()
        self.spb_slice_last = QSpinBox()
        self.spb_slice_first.setMaximum(0)
        self.spb_slice_last.setMaximum(0)

        self.drag_callback_id = None
        self.drag_start_xy = None
        self.drag_roi_cxcy = None

        self.setGeometry(50, 50, 1300, 800)
        self.setWindowTitle("ROI Creator")
        #self.setWindowIcon(QIcon(resource_filename('isi.resources', 'templogo.jpg')))
        self.draw_ui()
        self.center()
        self.show()

    def center(self):
        qr = self.frameGeometry()  # geometry of the main window
        cp = QDesktopWidget().availableGeometry().center()  # center point of screen
        qr.moveCenter(cp)  # move rectangle's center point to screen's center point
        self.move(qr.topLeft())  # top left of rectangle becomes top left of window centering it

    def roi_current_index(self):
        try:
            return self.roitable.selectedIndexes()[0].row()
        except IndexError:
            return None

    def mouse_is_over_selected_roi(self, event):
        row = self.roimodel.getRowData(self.roi_current_index())
        return -row[4] / 2.0 < event.xdata - row[2] < + row[4] / 2.0 and -row[4] / 2.0 < event.ydata - row[3] < row[
            4] / 2.0

    def roi_mouse_stop_drag(self, event):
        self.canvas.mpl_disconnect(self.drag_callback_id)

    def roi_mouse_start_drag(self, event):
        roi_index = self.roi_current_index()
        if roi_index is None:
            return
        row = self.roimodel.getRowData(roi_index)
        if self.mouse_is_over_selected_roi(event):
            self.drag_start_xy = (event.xdata, event.ydata)
            self.drag_roi_cxcy = (row[2], row[3])
            self.drag_callback_id = self.canvas.mpl_connect('motion_notify_event', self.roi_mouse_drag)
            self.canvas.mpl_connect('button_release_event', self.roi_mouse_stop_drag)

    def roi_mouse_drag(self, event):
        delta_x = int(event.xdata - self.drag_start_xy[0])
        delta_y = int(event.ydata - self.drag_start_xy[1])
        roi_index = self.roi_current_index()
        self.roimodel.setData(self.roimodel.index(roi_index, 2), self.drag_roi_cxcy[0] + delta_x, Qt.EditRole)
        self.roimodel.setData(self.roimodel.index(roi_index, 3), self.drag_roi_cxcy[1] + delta_y, Qt.EditRole)

    def roi_mouse_resize(self, event):
        roi_index = self.roi_current_index()
        if roi_index is None or not self.mouse_is_over_selected_roi(event):
            if event.button == 'up':
                self.slider.setValue(min(self.slider.value() + 1, self.slider.maximum()))
            elif event.button == 'down':
                self.slider.setValue(max(self.slider.value() - 1, self.slider.minimum()))
        else:
            row = self.roimodel.getRowData(roi_index)
            if event.button == 'up':
                self.roimodel.setData(self.roimodel.index(roi_index, 4), row[4] + 2, Qt.EditRole)
            elif event.button == 'down':
                self.roimodel.setData(self.roimodel.index(roi_index, 4), row[4] - 2, Qt.EditRole)

    def draw_ui(self):
        lay_h_main = QHBoxLayout()
        central_widget = QWidget()
        central_widget.setLayout(lay_h_main)
        self.setCentralWidget(central_widget)
        #
        # left panel: image display
        #
        lay_h_images = QHBoxLayout()
        # slider
        self.slider = QSlider(Qt.Vertical)
        self.slider.setMinimum(0)
        self.slider.setMaximum(0)
        self.slider.valueChanged.connect(self.select_image)
        lay_h_images.addWidget(self.slider)
        # canvas
        self.canvas.image_loaded.connect(self.update_number_of_images)
        lay_h_images.addWidget(self.canvas)
        lay_h_main.addLayout(lay_h_images, 67)
        # self.canvas.mpl_connect('motion_notify_event', self.react)
        self.canvas.mpl_connect('button_press_event', self.roi_mouse_start_drag)
        self.canvas.mpl_connect('scroll_event', self.roi_mouse_resize)
        self.canvas.setAcceptDrops(True)
        #
        # right panel: ROI operations
        #
        lay_v_rois = QVBoxLayout()
        lay_h_main.addLayout(lay_v_rois, 33)
        # ROI buttons
        lay_h_roibtns = QHBoxLayout()
        btn_roi_loa = QPushButton(' Load...')
        btn_roi_loa.setIcon(self.style().standardIcon(getattr(QStyle, 'SP_DialogOpenButton')))
        btn_roi_loa.clicked.connect(self.roi_load_list)
        lay_h_roibtns.addWidget(btn_roi_loa)
        btn_roi_add = QPushButton(' Add Square ROI')
        btn_roi_add.setIcon(self.style().standardIcon(getattr(QStyle, 'SP_FileIcon')))
        btn_roi_add.clicked.connect(lambda: self.roi_add('Square'))
        lay_h_roibtns.addWidget(btn_roi_add)
        btn_roi_add = QPushButton(' Add Circle ROI')
        btn_roi_add.setIcon(self.style().standardIcon(getattr(QStyle, 'SP_FileIcon')))
        btn_roi_add.clicked.connect(lambda: self.roi_add('Circle'))
        lay_h_roibtns.addWidget(btn_roi_add)
        btn_roi_del = QPushButton(' Delete ROI')
        btn_roi_del.setIcon(self.style().standardIcon(getattr(QStyle, 'SP_TrashIcon')))
        btn_roi_del.clicked.connect(self.roi_remove_selected)
        lay_h_roibtns.addWidget(btn_roi_del)
        btn_roi_sav = QPushButton(' Save...')
        btn_roi_sav.setIcon(self.style().standardIcon(getattr(QStyle, 'SP_DialogSaveButton')))
        btn_roi_sav.clicked.connect(self.roi_save_list)
        lay_h_roibtns.addWidget(btn_roi_sav)
        lay_v_rois.addLayout(lay_h_roibtns)
        # ROI table
        self.roitable.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.roitable.verticalHeader().setVisible(True)
        self.roitable.verticalHeader().setFixedWidth(20)
        self.roimodel.dataChanged.connect(self.roi_update_current)  # changed ROI
        self.roitable.clicked.connect(self.roi_highlight_selected)  # selected another ROI
        lay_v_rois.addWidget(self.roitable)
        # Slice filter
        gbx_image_filter = QGroupBox('Image range selection')
        lay_h_imgfil = QHBoxLayout()
        lay_h_imgfil.addWidget(QLabel('First slice:'), alignment=Qt.AlignRight)
        lay_h_imgfil.addWidget(self.spb_slice_first)
        lay_h_imgfil.addWidget(QLabel('Last slice:'), alignment=Qt.AlignRight)
        lay_h_imgfil.addWidget(self.spb_slice_last)
        self.spb_slice_first.valueChanged.connect(self.update_image_range_lower)
        self.spb_slice_last.valueChanged.connect(self.update_image_range_upper)
        gbx_image_filter.setLayout(lay_h_imgfil)
        lay_v_rois.addWidget(gbx_image_filter)

    def update_image_range_lower(self, new_limit):
        if new_limit > self.spb_slice_last.value():
            new_limit = self.spb_slice_last.value()
            self.spb_slice_first.setValue(new_limit)
        self.slider.setMinimum(new_limit)
        self.display_new_image_index()

    def update_image_range_upper(self, new_limit):
        if new_limit < self.spb_slice_first.value():
            new_limit = self.spb_slice_first.value()
            self.spb_slice_last.setValue(new_limit)
        self.slider.setMaximum(new_limit)
        self.display_new_image_index()

    def display_new_image_index(self):
        self.statusBar.showMessage('Slice {} of {} - {}'.format(self.slider.value(), len(self.canvas.image_paths),
                                   self.canvas.image_paths[self.slider.value()-1]))

    def update_number_of_images(self, img_num):
        # order of operations matter here: first set the maximum, then set the minimum
        # otherwise we may have for a moment min = 1 > max = 0 and the slider won't update its minimum properly
        self.spb_slice_first.setMaximum(img_num)
        self.spb_slice_last.setMaximum(img_num)
        self.spb_slice_last.setValue(img_num)
        self.spb_slice_first.setMinimum(1)
        self.spb_slice_last.setMinimum(1)
        self.spb_slice_first.setValue(1)
        self.display_new_image_index()

    def select_image(self):
        image_index = self.canvas.show_image(array_index=self.slider.value()-1)
        if image_index is not None:
            self.display_new_image_index()

    def roi_redraw_all(self):
        self.canvas.clear_rois()
        for r in range(self.roimodel.rowCount(0)):
            self.canvas.add_roi(roi_from_row(self.roimodel.getRowData(r)))
        self.roi_highlight_selected()

    def roi_remove_selected(self):
        try:
            if self.roimodel.removeRow(self.roi_current_index()):
                self.roi_redraw_all()
        except IndexError:
            pass

    def roi_update_current(self):
        roi_index = self.roi_current_index()
        new_roi = roi_from_row(self.roimodel.getRowData(roi_index))
        self.canvas.replace_roi(roi_index, new_roi)
        self.roi_highlight_selected()

    def roi_highlight_selected(self):
        if self.roi_current_index() is not None:
            self.canvas.highlight_roi(self.roi_current_index())

    def roi_add(self, shape):
        self.roimodel.addRow(shape)
        self.roitable.selectRow(self.roimodel.rowCount(0) - 1)
        self.canvas.add_roi(roi_from_row(self.roimodel.getRowData(self.roimodel.rowCount(0) - 1)))
        self.roi_highlight_selected()

    def roi_load_list(self):
        # select file and write
        fname = QFileDialog.getOpenFileName(self, 'Open file', '.', "JSON text file (*.json)")
        if fname != ('', ''):
            file_path = Path(fname[0] if isinstance(fname, tuple) else fname).with_suffix('.json')
            with open(file_path, 'r', encoding='utf-8') as fin:
                data = json.load(fin)
            # loading images first
            self.canvas.recursively_validate_and_load_files(data['images']['files'])
            self.spb_slice_last.setValue(data['images']['last'])
            self.spb_slice_first.setValue(data['images']['first'])
            self.slider.setValue(self.spb_slice_first.value())
            # loading ROIs
            self.roimodel.clear()
            header = self.roimodel.getColumns()
            for roi in data['rois']:
                self.roimodel.addRow(roi[header[1]], roi[header[2]], roi[header[3]], roi[header[4]], roi[header[0]])
            self.roitable.selectRow(0)
            self.roi_redraw_all()

    def roi_save_list(self):
        # prepare the data structure for writeout
        roi_out = []
        for r in range(self.roimodel.rowCount(0)):
            row = self.roimodel.getRowData(r)
            columns = self.roimodel.getColumns()
            roi_out.append({
                columns[0]: row[0],
                columns[1]: row[1],
                columns[2]: row[2],
                columns[3]: row[3],
                columns[4]: row[4]
            })
        imgs_out = {
            'files': self.canvas.image_paths,
            'first': self.spb_slice_first.value(),
            'last': self.spb_slice_last.value()
        }
        # select file and write
        fname = QFileDialog.getSaveFileName(self, 'Save file', '.', "JSON text file (*.json)")
        if fname != ('', ''):
            file_path = Path(fname[0] if isinstance(fname, tuple) else fname).with_suffix('.json')
            with open(file_path, 'w', encoding='utf-8') as fout:
                json.dump({'images': imgs_out, 'rois': roi_out}, fout, indent=4)

if __name__ == '__main__':
    app = QApplication([])
    roi_creator = RoiCreator()
    app.exec_()


##
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##

from __future__ import annotations
from typing import Hashable, List, Tuple, Dict, Optional, Sequence, Union, Iterable

import glob
import os

import pandas as pd
import pyarrow as pa
from pyarrow import parquet as pq
from pycylon.frame import CylonEnv
from pycylon.net.comm_ops import allgather_buffer, gather_buffer

def get_files(paths: Union[str, List[str]], ext: str = None) -> List[str]:
    """
    convert a list of glob strings to a list of files
    if directory paths are given, ext string added to the directory path.
    Possible ext values are: "*.parquet", "*.csv", "*.json"

    get all file names as a single list
    sort them alphabetically and return
    """
    if isinstance(paths, str):
        paths = [paths]

    all_files = []
    for p in paths:
        p = os.path.join(p, ext) if (os.path.isdir(p) and ext is not None) else p
        all_files.extend(glob.glob(p))

    return sorted(all_files)

def indices_per_worker(nfiles, my_rank, nworkers):
    """
    calculate indices for a worker by evenly dividing files among them
    """
    files_per_worker = int(nfiles / nworkers)
    workers_with_exra_file = nfiles % nworkers
    start = files_per_worker * my_rank + \
            (my_rank if my_rank < workers_with_exra_file else workers_with_exra_file)
    end = start + files_per_worker + (1 if my_rank < workers_with_exra_file else 0)
    return start, end

def get_worker_files(paths: List[str], env: CylonEnv, ext: str = None) -> List[str]:
    """
    calculate the list of files that this worker will read
    """
    all_files = get_files(paths=paths, ext=ext)
    start, end = indices_per_worker(len(all_files), env.rank, env.world_size)
    return all_files[start:end]

def all_schemas_equal(schema: pyarrow.Schema, env: CylonEnv) -> pyarrow.Schema:
    """
    after reading files, check whether all DataFrame schemas are equal
    return a schema in case the worker has no DataFrame and needs to create an empty table
    """

    # serialize the schema if exist, otherwise allocate empty buffer
    buf = schema.serialize() if schema is not None else pa.allocate_buffer(0)

    buffers = allgather_buffer(buf=buf, context=env.context)

    schemas = []
    for schema_buf in buffers:
        if len(schema_buf) > 0:
            with pa.ipc.open_stream(schema_buf) as reader:
                schemas.append(reader.schema)

    if len(schemas) == 0:
        raise ValueError("No worker has any schema.")

    # make sure all schemas are equal, compare consecutive ones
    for first, second in zip(schemas, schemas[1:]):
        if not first.equals(second):
            raise ValueError("Not all DataFrame schemas are equal.")

    return schemas[0]

def gen_file_name(rank: int, file_ext: str) -> str:
    """
    generate filename to write a DataFrame partition
    """
    if rank < 10:
        numeric_ext = "000" + str(rank)
    elif rank < 100:
        numeric_ext = "00" + str(rank)
    elif rank < 1000:
        numeric_ext = "0" + str(rank)
    else:
        numeric_ext = str(rank)
    return "part_" + numeric_ext + "." + file_ext

def determine_file_name_to_write(dir_path, name_function, file_ext, env):
    """
    Determine the filename to write for a worker
    """
    if not os.path.isdir(dir_path):
        os.makedirs(dir_path)

    file_name = gen_file_name(env.rank, file_ext) if name_function is None else name_function(env.rank)
    return os.path.join(dir_path, file_name)

#####################################################################################
# Parquet io functions
#####################################################################################

def serialize_metadata_file(fmd: pa._parquet.FileMetaData) -> pa.Buffer:
    """
    serialize a FileMetaData object
    return empty buffer if None
    """
    if fmd is None:
        return pa.allocate_buffer(0)
    else:
        _, buf_tuple = fmd.__reduce__()
        return buf_tuple[0]

def deserialize_metadata_buffers(buffers: List[pa.Buffer]) -> pa._parquet.FileMetaData:
    """
    deserialize FileMetaData buffers
    """
    fmd_all = []
    for received_buf in buffers:
        if received_buf.size > 0:
            fmd_all.append(pa._parquet._reconstruct_filemetadata(received_buf))
    return fmd_all

def schemas_equal(fmd_list: List[pa._parquet.FileMetaData], my_rank: int):
    """
    compare schemas of consecutive FileMetaData objects
    """
    for fmd1, fmd2 in zip(fmd_list, fmd_list[1:]):
        if not fmd1.schema.equals(fmd2.schema):
            f1 = fmd1.row_group(0).column(0).file_path
            f2 = fmd2.row_group(0).column(0).file_path
            raise ValueError(my_rank, f"schemas are not equal for the files: {f1} and {f2}")

def all_gather_metadata(worker_files: List[str], env: CylonEnv) -> pa._parquet.FileMetaData:
    """
    allgather FileMetaData objects and check schemas for equality
    """
    fmd_list = []
    for worker_file in worker_files:
        fmd = pq.read_metadata(worker_file)
        fmd.set_file_path(worker_file)
        fmd_list.append(fmd)

    # make sure all schemas are equal for this worker
    schemas_equal(fmd_list, env.rank)

    fmd_single = fmd_list[0] if fmd_list else None
    for fmd in fmd_list[1:]:
        fmd_single.append_row_groups(fmd)

    # serialize and all gather
    buf = serialize_metadata_file(fmd_single)
    buffers = allgather_buffer(buf=buf, context=env.context)

    # deserialize
    fmd_all = deserialize_metadata_buffers(buffers)
    if len(fmd_all) == 0:
        raise ValueError("No worker has any parquet files.")

    # make sure all received schemas are equal
    schemas_equal(fmd_all, env.rank)

    # combine all received schemas into one
    fmd_single = fmd_all[0]
    [fmd_single.append_row_groups(fmd) for fmd in fmd_all[1:]]
    return fmd_single

def row_groups_this_worker(df: pd.DataFrame, env: CylonEnv):
    """
    Determine the row groups this worker will read.
    Try to distribute rows evenly among workers.
    Each row_group will be read once by a single worker.
    Each worker will get consecutive row_groups in files so that reading might be efficient.
    """
    # if the number of workers are more than the number of row_groups,
    # just return a single row_group for each worker corresponding to its rank or an empty df
    if len(df.index) <= env.world_size:
        return df[env.rank:(env.rank + 1)]

    total_rows = df['row_group_size'].sum()
    remaining_workers = env.world_size
    rows_per_worker = total_rows / remaining_workers
    start_index = 0
    end_index = 0
    last_worker = env.rank == env.world_size - 1
    loop_count = env.rank if last_worker else env.rank + 1
    for _ in range(loop_count):
        rows_this_worker = 0
        start_index = end_index
        for i, rg_size in zip(df.index[start_index:], df['row_group_size'][start_index:]):
            rows_this_worker += rg_size
            if rows_this_worker >= rows_per_worker:
                end_index = i + 1
                break
        total_rows -= rows_this_worker
        remaining_workers -= 1
        rows_per_worker = total_rows / remaining_workers

    return df[end_index:] if last_worker else df[start_index:end_index]

def construct_df(fmd: pa._parquet.FileMetaData) -> pd.DataFrame:
    """
    construct a DataFrame with three columns
    for calculating row_groups per worker
    """
    row_group_indices = []
    row_group_sizes = []
    files = []
    rg_index = 0
    for i in range(fmd.num_row_groups):
        rg = fmd.row_group(i)
        worker_file = rg.column(0).file_path
        row_group_sizes.append(rg.num_rows)
        if rg_index > 0 and worker_file != files[len(files) - 1]:
            rg_index = 0
        row_group_indices.append(rg_index)
        rg_index += 1
        files.append(worker_file)

    return pd.DataFrame({'row_group_index': row_group_indices, 'row_group_size': row_group_sizes, 'file': files})

def gather_metadata_save(outfile, env: CylonEnv):
    fmd = pq.read_metadata(outfile)
    fmd.set_file_path(outfile)

    gather_root = 0
    buf = serialize_metadata_file(fmd=fmd)
    buffers = gather_buffer(buf, root=gather_root, context=env.context)
    if gather_root != env.rank:
        return outfile

    fmd_all = deserialize_metadata_buffers(buffers)
    fmd_single = fmd_all[0]
    [fmd_single.append_row_groups(fmd) for fmd in fmd_all[1:]]

    outfile_rp = os.path.realpath(outfile)
    meta_file = os.path.join(os.path.dirname(outfile_rp), "_metadata")
    fmd_single.write_metadata_file(meta_file)


import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import math
from server import app
from Skills_Selector import select_skills
from Job_Selector import jobs

new_Jobs = jobs()
new_skills = select_skills()

app.layout = dbc.Container([
    dbc.Row(
        dbc.Col(
            [
                html.Img(src="assets\img\skillflair.PNG", height="150px"),
            ],
            width=12,
        ),
    ),

    dbc.Row([
        dbc.Col([
            dcc.Dropdown(id='search-dropdown',
                         options=[{'label': 'Jobs', 'value': 'Jobs'}, {'label': 'Skills', 'value': 'Skills'}],
                         placeholder="Search by jobs or skills",
                         ),
            dcc.Dropdown(id='jobs-dropdown',
                         options=[{'label': job['label'], 'value': job['label']} for job in new_Jobs],
                         placeholder="Select a job",
                         style={'display': 'none'}),
            dcc.Dropdown(id='skills-dropdown',
                         options=new_skills,
                         value=[],
                         multi=True,
                         style={'display': 'none'}),
            html.Div(id='job-skills', className="my-3"),
            html.Div(id='hidden-skills', className="my-3"),
            dbc.Button('Match Skills', id='match-skills-button', className="mt-3 mb-3 dynamic-job-button"),
            dbc.Button('Exact Match Skills', id='exact-match-skills-button', className="mt-3 mb-3 dynamic-job-button"),
            html.Div(id='job-matches', className="my-3"),
            html.Div(id='hidden-div', style={'display': 'none'}),
            html.Div(id='selected-job', style={'display': 'none'}),
            html.Div(id='clicked-job', style={'display': 'none'}),
            dcc.Store(id='job-link-styles', data={}),
            dcc.Store(id='last-button-pressed', data=''),
            dcc.Store(id='selected-job-store', storage_type='session'),
            dcc.Store(id='clicked-button-store', data=None),
            dcc.Store(id='clicked-button-id', storage_type='memory'),
            dbc.Pagination(id='pagination', max_value=1, size='lg', className='mt-3 mb-3'),
            html.A(
            'Go to Flask homepage',
            href='/',
            className='fancy-link'  # Apply the CSS class to the hyperlink
        ),
        ], width=6, className="mx-auto"),
        dbc.Col([
            dcc.Graph(id='skills-barchart'),
        ], width=6, className="mx-auto"),
    ])
], fluid=True, className='py-5', style={'backgroundColor': '#ffffff'})


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 23 10:09:53 2019

@author: Minh Nguyen
"""

import numpy as np
from random import random, randint, choices

def RandomPNOTCircuit(fileName):
    with open(fileName, 'w+') as f:
        num_wires = randint(1,4)
        f.write('%d\n' % num_wires)

        f.write('INITSTATE BASIS |%s>\n' % bin(randint(1,2**num_wires))[2:])

        gate_list = choices(['P','NOT'],k=randint(5,20))
        for gate in gate_list:
            wire = randint(0,num_wires-1)
            if gate == 'P':
                phase = random()*2*np.pi
                f.write('P %d %.9f\n' % (wire, phase))
            elif gate == 'NOT':
                f.write('NOT %d\n' % wire)

RandomPNOTCircuit('my_random.circuit')


# aclint: py2 py3
# mypy: allow-untyped-defs
# LCM Definition File tokenizer
# We use PLY and regexes to convert a byte stream into a sequence of tokens.
from __future__ import absolute_import, print_function

import os
import shutil
import sys
import tempfile
import typing as T
from functools import wraps

from ply import lex

# Sorry pylint, PLY expects certain names in the module.
tokens = (
    "CLOSE_BRACE",
    "CLOSE_BRACKET",
    "COLON",
    "COMMA",
    "CONST",
    "ENUM",
    "EQUALS",
    "MACRO",
    "OPEN_BRACE",
    "OPEN_BRACKET",
    "PACKAGE",
    "RESERVED",
    "SEMICOLON",
    "STRING",
    "STRUCT",
    "WORD",
)

# Simple tokens without extra actions
t_CLOSE_BRACKET = r"\]"
t_COLON = ":"
t_COMMA = ","
t_EQUALS = "="
t_OPEN_BRACE = "{"
t_OPEN_BRACKET = r"\["

# The remaining tokens are definited using the special functions below.
# PLY looks for functions prefixed with t_ and uses their docstrings as regex patterns.
# When a pattern matches, the function is called with a token object
# The function can modify or remove the token.

# A note on comments in lcm defintion files:
# lcm-gen tracks comments and associates them with structs
# try_parse_and_consume_comment calls are littered throughout that code.
# I haven't figured out an elegant way to do this in PLY's LR parser yet.
# So for now I create a COMMENT_QUEUE which holds unprocessed comments
# When a STRUCT, PACKAGE, CLOSE_BRACE, or SEMICOLOR token is found, the queue gets processed.
# This enables the parser to associate comments without complicating the syntax rules.
COMMENT_QUEUE = []  # type: T.List[str]

def consume_comment_queue(f):
    "Decorator to attach the comments in the queue to the current token"
    # PLY depends on the exact function name and doctring, so we need to copy them with "wraps"
    @wraps(f)
    def f_with_line_counting(t):
        # Put the existing comments on this token for later access
        t.value = list(COMMENT_QUEUE)
        # Clear the comment queue
        COMMENT_QUEUE[:] = []
        return f(t)

    return f_with_line_counting

def count_lines(f):
    "Decorator to count newlines in a token and increment the line number"
    # PLY depends on the exact function name and doctring, so we need to copy them with "wraps"
    @wraps(f)
    def f_with_line_counting(t):
        t.lexer.lineno += sum(1 for c in t.value if c == "\n")
        return f(t)

    return f_with_line_counting

@consume_comment_queue
def t_CLOSE_BRACE(t):
    "}"
    return t

@count_lines
def t_COMMENT(t):
    r"\/\/(.*?)[\n]"
    # Assumes 2 or more leading slashes, strips whitespace.
    text = t.value.lstrip("/").strip()
    # Saves the comment (if non-empty) and makes it accessible to a future token.
    if text:
        COMMENT_QUEUE.append(text)
    # Prevent the comment from entering the token sequence by returning None
    return None

@count_lines
def t_CONST(t):
    r"const\W"
    return t

@count_lines
@consume_comment_queue
def t_ENUM(t):
    r"enum\W"
    return t

@count_lines
def t_EXTENDED_COMMENT(t):
    r"/\*((.*?[\n]*)*?)\*/"
    # Assumes /* text */ and one or more lines.
    comment_body = t.value[2:-2]
    lines = comment_body.splitlines()
    for line in lines:
        # Remove leading stars, and trim whitespace
        text = line.strip().lstrip("*").strip()
        if text:
            # Saves comment lines and makes them accessible to a future token
            COMMENT_QUEUE.append(text)
    # Prevent the comment from entering the token sequence by returning None
    return None

@count_lines
@consume_comment_queue
def t_PACKAGE(t):
    r"package\W"
    return t

def t_RESERVED(t):
    r"reserved\W"
    return t

@count_lines
@consume_comment_queue
def t_STRUCT(t):
    r"struct\W"
    return t

def t_SEMICOLON(t):
    r";[ \t]*(\/\/[^\n]*)?"
    # Copy the queue.
    comments = list(COMMENT_QUEUE)
    # Clear the queue.
    COMMENT_QUEUE[:] = []
    # Get the trailing comment, if any, without the leading semicolon or slashes.
    trailing = t.value[1:].strip().lstrip("/").lstrip()
    if trailing:
        comments.append(trailing)
    # Assign to the value for later retrieval during parsing.
    t.value = comments
    return t

def t_MACRO(t):
    r"[#][a-zA-Z._0-9-]+"
    # Attach the current line number to the macro so we can access it later for debugging
    t.value = (t.lexer.lineno, t.value)
    return t

def t_WORD(t):
    "[a-zA-Z._0-9-]+"
    # Attach the current line number to the word so we can access it later for debugging
    t.value = (t.lexer.lineno, t.value)
    return t

def t_STRING(t):
    r'"[^"]+"'
    return t

@count_lines
def t_WHITESPACE(_):
    "[ \n\t]+"
    # Drop all whitespace tokens from the sequence
    return None

def t_error(arg):
    print("error", arg)

if sys.version_info.major < 3:
    lextab_opt = "lextab_py2"
else:
    lextab_opt = "lextab_py3"

# Create the lexer (this lowercase name is required by PLY)
if os.environ.get("SKYMARSHAL_REGENERATE_LEXER"):
    lexer = lex.lex(optimize=1)  # this will create lextab.py
else:
    tempdir = tempfile.mkdtemp()
    try:
        lexer = lex.lex(optimize=1, lextab=lextab_opt, outputdir=tempdir)
    finally:
        shutil.rmtree(tempdir)

def generate_tokens(src):
    "Yield a sequence of tokens"
    lexer.input(src)
    for t in lexer:
        yield t.type
    # Should we reset?
    lexer.lineno = 1

def debug_tokens(src):
    "Print the tokens to stdout"
    print("\n".join(generate_tokens(src)))


data = input()
divisor = input()
for x in range(len(divisor)-1):
    data+='0'
cdivisor = divisor
zero_divisor = ""
for x in divisor:zero_divisor+='0'
starting = data[:4]
loda = len(divisor)
bitch_answer = ""
while True:
    if(loda==len(data)-1):break
    som = ""
    for (x,y) in zip(starting,divisor):
        if x!=y:som+='1'
        else : som+='0'
    starting = starting[1:]
    starting+=data[loda]
    print(starting)
    loda+=1
    if(starting[0]=='0'):
        bitch_answer+='0'
        divisor = zero_divisor
    else :
        bitch_answer+='1'
        divisor=cdivisor

print("final answer"  , bitch_answer)


#! /usr/bin/env python3
import sys
import uuid
import hashlib
import json
import base64

if len(sys.argv) < 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help':
  print("""usage: makenodeids files...
    Write an unique node id to each of the kelips configuration files passed
    in arguments""")
  sys.exit(0)
for f in sys.argv[1:]:
  v = str(uuid.uuid4())
  print(v)
  sha = hashlib.sha256(v.encode('latin-1')).digest()
  encoded = base64.b64encode(sha)
  print(encoded)
  with open(f, "r") as fj:
    content = json.load(fj)
  content['model']['overlay']['config']['node_id'] = encoded.decode('utf-8')
  with open(f, "w") as fj:
    json.dump(content, fj, indent=2)


import sys
import os
import random

def main():
    random.seed(0)

    amount_cap = int(float(sys.argv[1]) * 1e18)
    total_addresses = int(sys.argv[2])

    cd = bytes()

    total = 0
    for _ in range(total_addresses):
        amount = random.randint(0, amount_cap)
        total += amount
        addr = os.urandom(20)

        encoded = amount.to_bytes(12, 'big') + addr

        cd += encoded

    print(f'amount: {total}')
    print(f'0x{cd.hex()}')

if __name__ == '__main__':
    main()


# 현수의 위치 s, 송아지의 위치 e
def solution(s, e):
    # 현수의 위치가 송아지의 위치보다 값이 작은 경우
    if s < e:
        count = (e-s) // 5
        s = s + (count * 5)
    # 현수의 위치가 송아지의 위치보다 값이 큰 경우
    else:
        return s - e

    to_visit = [s]

    visited = [False for _ in range(10001)]

    while to_visit:

        for _ in range(len(to_visit)):
            current = to_visit.pop(0)

            for next_ in [current+1, current-1, current+5]:
                if next_ == e:

                    return count
                elif 0 < next_ <= 10000 and not visited[next_]:
                    visited[current] = True
                    to_visit.append(next_)
            count += 1

# 3
print(solution(5, 14))

# 5
print(solution(8, 3))

# def solution(s, e):
#
#     count = 0
#
#     to_visits = [s]
#
#     visited = [False for _ in range(10001)]
#
#     while to_visits:
#         for _ in range(len(to_visits)):
#
#             current = to_visits.pop(0)
#
#             if not visited[current]:
#
#                 visited[current] = True
#
#                 if current == e:
#                     return count
#                 for nxt in [current+1, current -1, current+5]:
#                     if 0 < nxt <= 10000 and not visited[nxt]:
#                         to_visits.append(nxt)
#     count += 1


from django import forms
from .models import Post, Comment

class PostForm(forms.ModelForm):
    body = forms.CharField(
        label='',
        widget=forms.Textarea(attrs={
            'rows': '3',
            'placeholder': 'Say Something...'
        }))
    picture = forms.ImageField(required=False)  # Add this line for the image field

    class Meta:
        model = Post
        fields = ['body', 'picture']  # Include the 'image' field in the form

class CommentForm(forms.ModelForm):
    comment = forms.CharField(
        label='',
        widget=forms.Textarea(attrs={
            'rows': '3',
            'placeholder': 'Say Something...'
            }))

    class Meta:
        model = Comment
        fields = ['comment']


import pandas as pd
import datetime
import win32com.client as win32
import yfinance as yf
from matplotlib import pyplot as plt

# import matplotlib.pyplot as plt
# import matplotlib.style as style

if __name__ == '__main__':
    print("Relatorio mercado financeiro!")

#-----------------BUSCANDO OS DADOS E SENTANDO--------
minhas_acoes = ["MGLU3.SA"]

# Definindo quais ativos vou pegar as cotações do yahoo
codigos_de_negociacao = ["^BVSP", "BRL=X"]

# Pegando a data de hoje
hoje = datetime.datetime.now()

# pegando um perido de 1 ano a partir de hoje
um_ano_atras = hoje - datetime.timedelta(days=365)

# Baixando os dados do yahoo conforme parametros acima
dados_mercado = yf.download(codigos_de_negociacao, um_ano_atras, hoje)
periodo = um_ano_atras.date() - hoje.date()

#-------------MANIPULANDO OS DADOS-------------

# Renomeando os nomes das tabelas
dados_fechamento = dados_mercado['Adj Close']
dados_fechamento.columns = ["dolar", "ibovespa"]

# Excluindo dados onde está vazio e pegando os 3 primeiros dados
exclua_dados_faltante = dados_fechamento.dropna()
primeiros_50_dados = exclua_dados_faltante.head(20)

print("Abaixo consta a cotação em um periodo de", periodo)
print(primeiros_50_dados)

# Pegando e exibindos os dados por ano e por mes e por dia
dados_anuais = dados_fechamento.resample("y").last()
dados_mensais = dados_fechamento.resample("M").last()

retorno_anual = dados_anuais.pct_change().dropna()
retorno_mensal = dados_mensais.pct_change().dropna()
retorno_diario = dados_fechamento.pct_change().dropna()

print("Dados anuais", retorno_anual)
print("Dados mensais", retorno_mensal)
print("Dados diarios", retorno_diario)

#--------------LOCALIZANDO DADOS DENTRO DE UM DATAFRAME---------------------#

# loc -> referencia elementos a partir pelo nome
retorno_fev_17_2022 = retorno_diario.loc["2022-02-17", "ibovespa"]
print(retorno_fev_17_2022)

# iloc -> faz o mesmo mas por uma matriz, como se fosse o procv do excel
retorno_fev_17_2022 = retorno_diario.iloc[2, 1]
print(retorno_fev_17_2022)

# Pegando sempre o fechamento diariamente
retorno_diario_ibov = retorno_diario.iloc[-1, 1]
print("Fechamento do ultimo dia do ibov", retorno_diario_ibov)

# Transformando em %
retorno_diario_ibov_em_perct = round((retorno_diario_ibov * 100), 2)
print(retorno_diario_ibov_em_perct, "%")

#--------------------GERANDO O GRAFICO-------------------#

plt.style.use("cyberpunk")
# Definindo que o eixo vertical será os dados do ibov e os index as datas
dados_fechamento.plot(y = "ibovespa", use_index = True, legend = False)
plt.title("Ibovespa")

plt.savefig("ibovespa.png", dpi = 300)
plt.show()

#--------------------ENVIANDO OS DADOS POR EMAIL-------------------#

# Logando no outlook
outlook = win32.Dispatch("outlook.application")

email = outlook.CreateItem(0)

email.To = "matheushenriquesilva.th@gmail.com"
email.Subject = "Relatório Diário Ibov"
nome = "Matheus Henrique"

# Criando uma string personalizada com quebra de linhas
email.Body = f''' Olá {nome}, o fechamento do Ibov foi de {retorno_diario_ibov_em_perct}.

Obrigado!
'''

# Anexando arquivo e enviando o email
anexo_ibov = r"C:\Development\Python Projects\ibov-fechamento-relatorio\ibov\ibovespa.png"

email.Attachments.Add(anexo_ibov)

email.Send()


import io
import webbrowser
from parsePDF import pdfExport
from parseXML import parseXML
from graficar import graficar
from princF import pFunc
class menu:
    def menuP(self):
        lista_piso = None
        opcion = 0
        print()
        while opcion != 4:
            try:
                self.opciones()
                opcion = int(input('Opción: '))
                if opcion == 1:
                    try:
                        ruta = input('\nIngrese la ruta del archivo XML de entrada: ')
                        lista_piso = parseXML().getXML(ruta)
                        print('Información cargada\n')
                    except:
                        print('El XML no se encuentra en la ubicación especificada\n')
                elif opcion == 2:
                    if lista_piso:
                        lista_piso.ordenar()
                        lista_piso.recorrer()
                    else:
                        print('\nNo se ha cargado información de los pisos\n')
                elif opcion == 3:
                    if lista_piso:
                        self.operaciones(lista_piso)
                    else:
                        print('\nNo se ha cargado información de los pisos\n')
                elif opcion == 4:
                    print('\n¡Finalizado!')
                else:
                    print('\nSolo números entre 1 y 5\n')
            except:
                print('\nOpción inválida\n')

    def opciones(self):
        print("""Menú Principal
1. Cargar Archivos XML
2. Ver Pisos Y Patrones
3. Operaciones Con Pisos
4. Salir""")

    def operaciones(self,lista_piso):
        g = graficar()
        piso1 = input("\nIngrese el nombre del primer piso: ")
        while lista_piso.buscarP(piso1):
            piso1 = input("Ingrese el nombre del primer piso: ")
        ptrn1 = input("Ingrese el código del patrón: ")
        while lista_piso.buscarPatronP(piso1,ptrn1):
            ptrn1 = input("Ingrese el código del patrón: ")
        f = lista_piso.getF(piso1)
        c = lista_piso.getC(piso1)
        mosaico1 = lista_piso.getMos(piso1,ptrn1)
        mdot1 = g.dibujar(f,c,mosaico1)
        mdot1 = g.getDot(mdot1,'')
        g.exportPDF('mosaico0',mdot1)
        g.exportPNG(0,mdot1)
        print()
        piso2 = input("Ingrese el nombre del segundo piso: ")
        while lista_piso.buscarS(f,c,piso2):
            piso2 = input("Ingrese el nombre del segundo piso: ")
        ptrn2 = input("Ingrese el código del patrón: ")
        while lista_piso.buscarPatronS(piso1,ptrn1,piso2,ptrn2):
            ptrn2 = input("Ingrese el código del patrón: ")
        print()
        mosaico2 = lista_piso.getMos(piso2,ptrn2)
        costInt = lista_piso.getCostI(piso1)
        costVolt = lista_piso.getCostV(piso1)
        d = pFunc()
        pares = d.getCantCol(f,c,mosaico1,mosaico2)
        color = d.getMenorC(pares)
        priSec = d.getPriSec(pares)
        crd1 = d.getCrd(f,c,mosaico1,color)
        crd2 = d.getCrd(f,c,mosaico2,color)
        rutas = d.getRutas(priSec.get(0),priSec.get(1),crd1,crd2)
        lenRutas = d.cantOpt(priSec.get(0) * priSec.get(1),rutas)
        rutas = d.optRutas(priSec.get(0) * priSec.get(1),rutas)
        rutas = d.crearCaminos(mosaico1,lenRutas,rutas,priSec.get(1),crd2,color)
        lenRutas = d.optCmns(mosaico1,priSec.get(1),crd2,color)
        d.transMos(f,c,lenRutas,rutas,mosaico1,mosaico2,color,costInt,costVolt)
        intercambios = d.getIntercambios()
        volteos = d.getVolteos()
        minCost = d.minCost()
        print('Costo Mínimo: Q',minCost)
        print('Intercambios:',intercambios)
        print('Volteos:',volteos,'\n')
        self.menuInstrucciones(f,c,d)
        g.parsePDF('mosaico' + str(intercambios + volteos))

    def menuInstrucciones(self,fil,col,d):
        opcion = 0
        while True:
            try:
                print("""Ver Instrucciones
1. Ver En Consola
2. Exportar En Archivo .txt
3. Exportar En Archivo .pdf""")
                opcion = int(input('Opción: '))
                if opcion == 1:
                    print('\n' + d.getInstConsola() + '\n')
                    break
                elif opcion == 2:
                    with io.open("Instrucciones.txt","w",encoding="utf-8") as f:
                        f.write(d.getInstArchivo())
                    webbrowser.open("Instrucciones.txt")
                    print('\nInstrucciones Exportadas\n')
                    break
                elif opcion == 3:
                    pdfExport().exportarPDF(fil,col,d.getIntercambios() + d.getVolteos(),d.getListaInst())
                    print('\nInstrucciones Exportadas\n')
                    break
            except:
                print('\nOpción Inválida\n')


from setuptools import setup

PACKAGE = 'FlashView'
VERSION = '0.1.3'

setup(name=PACKAGE,
      version=VERSION,
      packages=['flashview'],
      author = 'Yuanying',
      author_email = 'yuanying@fraction.jp',
      url = 'http://trac-hacks.org/wiki/FlashViewPlugin',
      description = 'Flash view plugin for Trac',
      license='BSD',
      entry_points={'trac.plugins': '%s = flashview' % PACKAGE},
)


"""Játék main scriptje, gerince"""

import sys
import pygame as pg
import python_kotelezo_program.map as m         # Az ilyen fajta importokra import-errort ír a pylint,
import python_kotelezo_program.settings as s    # pedig működnek úgyhogy disable-re raktam
import python_kotelezo_program.player as p
import python_kotelezo_program.raycasting as r
import python_kotelezo_program.object_renderer as o
import python_kotelezo_program.object_handler as oh
import python_kotelezo_program.weapon as w
import python_kotelezo_program.sound as so
import python_kotelezo_program.pathfinding as pa

class Game:
    """Magát a játékot reprezentáló osztály"""

    def __init__(self):
        pg.init()
        pg.mouse.set_visible(False)
        self.screen = pg.display.set_mode(s.RES)
        pg.event.set_grab(True)
        self.clock = pg.time.Clock()
        self.delta_time = 1
        self.levels_done = -1
        self.new_game(m.mini_map_1)

    def new_game(self, mini_map):
        """Új játékot létrehozó függvény"""

        self.map = m.Map(self, mini_map)
        self.player = p.Player(self)
        self.object_renderer = o.ObjectRenderer(self)
        self.raycasting = r.RayCasting(self)
        self.object_handler = oh.ObjectHandler(self)
        self.weapon = w.Weapon(self)
        self.sound = so.Sound(self)
        self.pathfinding = pa.PathFinding(self)
        self.npc_count = len(self.object_handler.npc_list)

    def update(self):
        """Ablakot megjelenítő, azt adatokkal folyamatosan ellátó függvény"""

        self.player.update()
        self.raycasting.update()
        self.object_handler.update()
        self.weapon.update()
        self.sound.volume_control()
        pg.display.flip()
        self.delta_time = self.clock.tick(s.FPS)
        pg.display.set_caption(f'{self.clock.get_fps() :.1f}')

    def draw(self):
        """Ablakba elemeket rajzoló függvény"""

        # self.screen.fill('black')
        self.object_renderer.draw()
        self.weapon.draw()
        # self.map.draw()
        # self.player.draw()

    def check_events(self):
        """Billentyű kezelő függvény"""

        for event in pg.event.get():
            if event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
                pg.quit()
                sys.exit()
            self.player.single_fire_event(event)

    def run(self):
        """Játékot futtató függvény"""

        while True:
            self.check_events()
            self.update()
            self.draw()

if __name__ == '__main__':
    game = Game()
    game.run()


log_file = open("um-server-01.txt")
#opening file "um-server-01.txt"

def sales_reports(log_file):
    for line in log_file:
        line = line.rstrip()
        day = line[0:3]
        if day == "Tue":
            print(line)

#creating a for loop, if statement, & editing/deleting file data

sales_reports(log_file)

#displaying results


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

# 注册蓝本 必须用下列顺序 避免陷入循环依赖
from flask import Blueprint

auth = Blueprint('auth', __name__)

from . import views

from ..models import SecondPageName, WebSetting, FriendLink, User

# 返回数据库内的页面标题以及url
@auth.context_processor
def get_page_names():
    """获得二级页面的内容以及id"""
    data = SecondPageName.query.all()
    names = {}
    for name in data:
        names[name.page_name] = name.id
    return dict(names=names)

@auth.context_processor
def get_setting():
    """获得设置"""
    data = WebSetting.query.get(1)
    if data is not None:
        data = data.to_json()
        return dict(setting=data)
    return dict(setting=None)

@auth.context_processor
def get_links():
    """获得设置"""
    links = FriendLink.query.all()
    return dict(links=[link.to_json() for link in links])