from email import message
from django.shortcuts import render
from .models import *
from .serializers import *
from rest_framework.mixins import *
from rest_framework import generics, status
from django.http.response import JsonResponse
from rest_framework.response import Response
from rest_framework.views import APIView, exception_handler
from rest_framework.exceptions import APIException
from rest_framework.validators import UniqueValidator
# from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.exceptions import bad_request
from django.db.models import Prefetch
from django.contrib.auth.tokens import default_token_generator
import phonenumbers
import datetime
from django.template import Context
from django.template.loader import get_template

# Для загрузки файлов
import mimetypes
import os
from django.http.response import HttpResponse
import xlsxwriter
from .forms import *
from django.http import HttpResponseRedirect

class ParticipantCreate(APIView):
    # permission_classes = [AllowAny]
    #API that allows to create new Participant
    def post(self, request):
        participantizer = ParticipantCreateSerializer(data=request.data)
        if participantizer.is_valid(raise_exception=True):
            print(participantizer.data['phonenumber'])
            if participantizer.data['phonenumber'] != '':
                parsedPhone = phonenumbers.parse(participantizer.data['phonenumber'], "RU")
                if not phonenumbers.is_possible_number(parsedPhone):
                    return Response(status=status.HTTP_400_BAD_REQUEST)
            participant = Participant.objects.create(phonenumber = participantizer.data['phonenumber'], birthday = participantizer.data['birthday'], middlename = participantizer.data['middlename'], firstname = participantizer.data['firstname'], lastname = participantizer.data['lastname'], email = participantizer.data['email'], sex = participantizer.data['sex'], last_login = datetime.datetime.now())
            participant.set_password(participantizer.data['password'])
            participant.save()
            token = Token.objects.get(user=participant).key
            # resp = {}
            # resp['id'] = participant.id
            # resp['token'] = token
            confirmation_token = default_token_generator.make_token(participant)
            actiavation_link = f'83.221.202.194:2500/oborona/activate-account/?user_id={participant.id}&confirmation_token={confirmation_token}'
            message = get_template("emails/email_activation.html").render({'act_mail': actiavation_link})
            send_mail(
                # title:
                "Активация аккаунта участника фестиваля \"Оборона Таганрога 1855 года\"",
                # message:
                "\n",
                # "http:\\\\{}\n\nДля подтверждения почты перейдите по указанной ссылке, далее вернитесь в приложение и авторизуйтесь по почте и паролю, указанными при регистрации.\nЕсли Вы изменили свою почту на новую в профиле, авторизуйтесь в приложении с новой почтой, после того как её подтвердите.".format(actiavation_link),
                # from:
                "daniil-kochubey@yandex.ru",
                # to:
                [participant.email],

                html_message=message
            )
            print("USER DATA",participant.id, participantizer.data)
            return Response(status.HTTP_200_OK)
        # response = exception_handler(exc, context)
        # return Response(status.HTTP_400_BAD_REQUEST, context)

class ParticipantList(APIView):
    # permission_classes = [IsAuthenticated]
    #API that allows to view all Participants
    def get(self, request):
        queryset = Participant.objects.all()
        serializer = ParticipantSerializer(queryset, many = True)
        return Response(serializer.data)

class ParticipantDetail(APIView):
    # permission_classes = [IsAuthenticated]
    #API that allows to view single participant by pk
    def get(felf, request):

        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        queryset = Participant.objects.get(id=pk)
        serializer = ParticipantDetailedSerializer(queryset)
        print(serializer.data)
        return Response(serializer.data)

class MyObtainAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        response = super(MyObtainAuthToken, self).post(request, *args, **kwargs)
        token = Token.objects.get(key=response.data['token'])
        return Response({'id': token.user_id, 'token': token.key})

# class ParticipantUpdate(generics.RetrieveUpdateAPIView):
#     #API that allows to update participant record
#     queryset = Participant.objects.all()
#     serializer_class = ParticipantSerializer

# class ParticipantDelete(generics.RetrieveDestroyAPIView):
#     #API that allows to delete participant record
#     queryset = Participant.objects.all()
#     serializer_class = ParticipantSerializer

#------------------------------------------------------------------
class ListCasualEvents(APIView):
#   permission_classes = [IsAuthenticated]
  def get(sels, request):
      events = Event.objects.filter(is_epic=False)
      serializer = EventCasualListSerializer(events, many=True)
      return Response(serializer.data)

class ListEpicEvents(APIView):
#   permission_classes = [IsAuthenticated]
  def get(sels, request):
      events = Event.objects.filter(is_epic=True)
      serializer = EventEpicListSerializer(events, many=True)
      return Response(serializer.data)

class ListAllEvents(APIView):
#   permission_classes = [IsAuthenticated]
  def get(sels, request):
      events = Event.objects.all()
      serializer = EventShortSerializer(events, many=True)
      return Response(serializer.data)

class EventCreate(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        event = EventCreateSerializer(data=request.data)
        if event.is_valid():
            event.save()
            return Response(status=status.HTTP_201_CREATED)
        return Response(status=status.HTTP_400_BAD_REQUEST)

class EventAdminCreate(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        event = EventAdminCreateSerializer(data=request.data)
        if event.is_valid():
            event.save()
            return Response(status=status.HTTP_201_CREATED)
        else:
            print(event.errors.values())
        return Response(status=status.HTTP_400_BAD_REQUEST)

class EventDetail(APIView):
    def get(self, request, pk):
        events = Event.objects.get(id=pk)
        serialized_event = EventSerializer(events)
        return Response(serialized_event.data)

#формирование списка ролей с айдишниками и названиями вместо просто айдишников
        # roles = serialized_event.data["roles"]
        # roles_with_names = '{'
        # new_roles = []
        # for i in roles: new_roles.append(Role.objects.get(id=i))
        # for j in new_roles:
        #     serialized_role = RoleSerializer(j)
        #     roles_with_names = roles_with_names + "\""+str(serialized_role.data['id'])+"\": \"" + str(serialized_role.data["role_name"]) + "\","
        # roles_with_names = roles_with_names.rstrip(",") + "}"
        # newdata = dict(serialized_event.data)#
        # newdata.update({"roles": roles_with_names})
        # print(newdata)
#------------------------------------------------------------------

class RoleDetail(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request, pk):
        roles = Role.objects.get(id=pk)
        serializer = RoleSerializer(roles)
        return Response(serializer.data)

#------------------------------------------------------------------

class AdditionalInfoCreate(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        entry_serialized = EntryCreateSerializer(data={'event': 2, 'user':pk, 'role':5})
        print("INIITAL DATA FOR COSTUME")
        print(request.data)
        if entry_serialized.is_valid():
            entry_serialized.save()
        else:
            print(entry_serialized.errors)
            return Response(status.HTTP_400_BAD_REQUEST)#, data=entry_serialized.errors)
        request.data.update({'user': pk, 'entry':entry_serialized.data['id']})

        info = AdditionalInfoCreateSerializer(data=request.data)
        if info.is_valid():
            info.save()
            return Response(status.HTTP_200_OK)
        print(info.errors)
        return Response(status.HTTP_400_BAD_REQUEST, data=info.errors)

#-----------------------------------------------------------------

class EntryCreate(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        serialized_entry = EntryCreateSerializer(data=request.data)
        if serialized_entry.is_valid():
            serialized_entry.save()
            return Response(status.HTTP_201_CREATED)
        return Response(status.HTTP_400_BAD_REQUEST)

class EntryList(APIView):
    # permission_classes = [IsAuthenticated]

    def get(self, request):
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        entrys = Entry.objects.filter(user = pk)
        # print(entrys)
        serialized_entrys = EntryListSerializer(entrys, many=True)
        # print(serialized_entrys.data)
        # if serialized_entrys.is_valid(raise_exception=True):
        return Response(serialized_entrys.data)

#-----------------------------------------------------------------

class PromoCodeCreate(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request, count):

        while count !=0:
            newCode = PromoCodes.create_code(number=count)
            data_for_serializer = {'code': newCode}
            serialized_code = PromoCodeSerializer(data=data_for_serializer)
            if serialized_code.is_valid():
                print("Noice")
                new_promo_code = PromoCodes.objects.create(code=serialized_code.data['code'])
                new_promo_code.save()
                count -= 1

        return Response(newCode)

class PromoCodeVerify(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        codes = PromoCodes.objects.filter(code=request.data['code'])
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        user = Participant.objects.get(id=pk)
        user_with_code = PromoCodes.objects.filter(user=pk)

        if not codes:
            return Response(status=status.HTTP_400_BAD_REQUEST, data="No such promocode")
        codes = codes[0]
        if user_with_code:
            return Response(status=status.HTTP_400_BAD_REQUEST, data="You already activated promocode")
        elif codes.user != None:#update the object
            return Response(status=status.HTTP_400_BAD_REQUEST, data="No such promocode")
        else:
            codes.user = user
            codes.save()
            user.is_sponsor = True
            user.save()
            return Response(status=200, data="Ok")

class MapPinsList(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request):
        horecas = HoReCa.objects.all()
        events = Event.objects.all()

        serialized_horecas = HoReCaDetailSerializer(horecas, many=True)
        serialized_events = EventMapSerializer(events, many=True)
        return Response({
            "HoReCas":serialized_horecas.data,
            "Events":serialized_events.data
        })

class InfoWindowsList(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request):
        info_windows_que = InfoWindow.objects.all()
        s_info_windows = InfoWindowListSerializer(info_windows_que, many=True)
        return Response(s_info_windows.data)

class InfoWindowsSingle(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request, pk):
        info_window = InfoWindow.objects.get(id=pk)
        s_info_window = InfoWindowSingleSerializer(info_window)
        return Response(s_info_window.data)

class TechInfoWindowImport(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):
        info_window = TechInfoWindowImportSerializer(data=request.data)
        if info_window.is_valid():
            info_window.save()
            return Response(status=status.HTTP_201_CREATED)
        return Response(status=status.HTTP_400_BAD_REQUEST)

class UnsubscribeFromEvent(APIView):
    # permission_classes = [IsAuthenticated]
    def post(self, request):

        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        req_data = request.data
        event_to_delete = Entry.objects.filter(event_id=req_data['event_id']).filter(user_id=pk)
        if event_to_delete:
            event_to_delete.delete()
            return Response(status.HTTP_200_OK)
        else:
            return Response(status.HTTP_400_BAD_REQUEST)

class ListRoles(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request):
        all_roles = Role.objects.all()
        serialized_roles = RoleSerializer(all_roles, many=True)
        return Response(serialized_roles.data)

class CountSexes(APIView):
    # permission_classes = [IsAuthenticated]
    def get(self, request):
        ladys_count = 0
        gentleman_count = 0
        all_entrys = Entry.objects.all().filter(event=3)

        serialized_entrys = EntrysWithParticipantSerializer(all_entrys, many=True)
        print(serialized_entrys.data)
        for part in serialized_entrys.data:
            if part['user']['sex'] == 'f' and part['role'] == 7:
                ladys_count+=1
            if part['user']['sex'] == 'm' and part['role'] == 7:
                gentleman_count+=1
        resp={'woman': ladys_count, 'man': gentleman_count}
        return Response(resp, status=status.HTTP_200_OK)

class ParticipantUpdate(APIView, UpdateModelMixin):
    # permission_classes = [IsAuthenticated]
    queryset = Participant.objects.all()
    serializer_class = ParticipantCreateSerializer

    # def patch(self, request, *args, **kwargs):
    #     pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
    #     user_instance = Participant.objects.get(id=pk)
    #     user_instance.partial_update(request, *args, **kwargs)
    #     return Response(200)
    #     return self.partial_update(request, *args, **kwargs)

    # # def get_object(self, *args, **kwargs):

    def patch(self, request):
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        user_instance = Participant.objects.get(id=pk)
        # user_instance['name'].update("Вася")
        serialized_participant= ParticipantUpdateSerializer(user_instance, data=request.data, partial=True)

        print(user_instance)
        if serialized_participant.is_valid(raise_exception=True):

            serialized_participant.save()
            pass
        serialized_participant.save()
        # part_serialized = ParticipantDetailedSerializer(user_instance)
        print(serialized_participant.data)
        # user_instance.perform_update(serialized_participant)
        return Response(status=status.HTTP_200_OK)

class ParticipantUpdateEmail(APIView):
    def post(self, request):
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        user_instance = Participant.objects.get(id=pk)
        newEmail = request.data['email']

        user_instance.email = newEmail
        user_instance.is_active = False
        user_instance.save()
        confirmation_token = default_token_generator.make_token(user_instance)
        actiavation_link = f'83.221.202.194:2500/oborona/activate-account/?user_id={user_instance.id}&confirmation_token={confirmation_token}'
        message = message = get_template("emails/email_activation.html").render({'act_mail': actiavation_link})
        send_mail(
                # title:
                "Активация аккаунта участника фестиваля \"Оборона Таганрога 1855 года\"",
                # message:
                "{}\nЕсли Вы изменили свою почту на новую в профиле, авторизуйтесь в приложении с новой почтой, после того как её подтвердите.".format(actiavation_link),
                # from:
                "daniil-kochubey@yandex.ru",
                # to:
                [newEmail],

                html_message=message
            )
        return Response(status.HTTP_200_OK)

class ParticipantCangePassword(APIView):
    def post(self, request):
        pk = Token.objects.get(key = request.META.get('HTTP_AUTHORIZATION').lstrip('Token ')).user_id
        request.data.update({"pk": pk})

        ser_pass = ChangePasswordSerializer(data = request.data)
        if ser_pass.is_valid(raise_exception=True):
            ser_pass.save(validated_data=ser_pass.validated_data)
        return Response(status.HTTP_200_OK)

class ActivateParticipantByLink(APIView):
    # permission_classes = [AllowAny]
    def get(self, request):
        participant_id = request.query_params.get('user_id', '')
        # participant = Participant.objects.get(id = participant_id)
        confirmation_token = request.query_params.get('confirmation_token', '')
        participant = Participant.objects.get(id=participant_id)
        if participant == None:
            return Response(status.HTTP_400_BAD_REQUEST)
        if not default_token_generator.check_token(participant, confirmation_token):
            return Response(status.HTTP_400_BAD_REQUEST)
        participant.is_active = True
        participant.save()
        return Response(status.HTTP_200_OK)

# Site
#----------------------------------------------------------------------------------------------------------------------------------------#
def horeca(request):
    queryset = HoReCa.objects.all()

    context = {
        "welcome": "Партнёры HoReCa",
        "queryset": queryset
    }
    return render(request, 'oborona_taganroga/horeca.html', context=context)

def people(request):
    queryset = Participant.objects.all()

    # Не выводим
    # birthday, password, entrys, is_admin, is_active, last_login

    context = {
        "welcome": "Участники фестиваля",
        "queryset": queryset
    }
    return render(request, 'oborona_taganroga/people.html', context=context)

def events(request):
    queryset = Event.objects.all()

    # Не выводим
    # is_epic

    context = {
        "welcome": "События фестиваля",
        "queryset": queryset
    }
    return render(request, 'oborona_taganroga/events.html', context=context)

def how_to_use(request):
    context = {
        "welcome": "Как пользоваться сайтом",
    }
    return render(request, 'oborona_taganroga/how_to_use.html', context=context)

def download_people(request):
    queryset = Participant.objects.all()
    serializer = ParticipantSerializerSite(queryset, many = True)

    # Создание excel файла
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    filename = 'people.xlsx'
    filepath = BASE_DIR + '/oborona_taganroga/files/' + filename

    size = 'A1:G'+str(len(serializer.data) + 1)
    workbook = xlsxwriter.Workbook(filepath)
    worksheet = workbook.add_worksheet()
    worksheet.add_table(size, {'autofilter': False, 'columns':
                                         [{'header': 'Имя'},
                                          {'header': 'Фамилия'},
                                          {'header': 'Отчество'},
                                          {'header': 'Телефон'},
                                          {'header': 'Пол'},
                                          {'header': 'Электронная почта'},
                                          {'header': 'Спонсор'},
                                          ]})

    # Настройка размеров отображения таблицы
    cell_format = workbook.add_format()
    cell_format.set_text_wrap()
    worksheet.set_column('A:G', 30)

    # Запись в Excel файл
    row,col = 1,0

    # Добавить сюда код чтобы всё было норм
    for item in serializer.data:
        worksheet.write(row, col, item['firstname'],cell_format)
        worksheet.write(row, col + 1, item['lastname'],cell_format)
        worksheet.write(row, col + 2, item['middlename'],cell_format)
        worksheet.write(row, col + 3, item['phonenumber'],cell_format)
        worksheet.write(row, col + 4, item['sex'],cell_format)
        worksheet.write(row, col + 5, item['email'],cell_format)
        worksheet.write(row, col + 6, item['is_sponsor'],cell_format)
        row += 1
    workbook.close()

    # Отправляем сформированный документ
    if os.path.exists(filepath):
        with open(filepath, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            response['Content-Disposition'] = 'attachment; filename=people.xlsx'
            return response

def download_events(request):
    queryset = Event.objects.all()
    serializer = EventSerializerSite(queryset, many = True)

    # Создание excel файла
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    filename = 'events.xlsx'
    filepath = BASE_DIR + '/oborona_taganroga/files/' + filename

    size = 'A1:K'+str(len(serializer.data) + 1)
    workbook = xlsxwriter.Workbook(filepath)
    worksheet = workbook.add_worksheet()
    worksheet.add_table(size, {'autofilter': False, 'columns':
                                         [{'header': 'Название'},
                                          {'header': 'Иллюстрация'},
                                          {'header': 'Краткое описание'},
                                          {'header': 'Полное описание'},
                                          {'header': 'Адрес'},
                                          {'header': 'Старт'},
                                          {'header': 'Финиш'},
                                          {'header': 'Роли'},
                                          {'header': 'Широта'},
                                          {'header': 'Долгота'},
                                          {'header': 'Телефонный номер'},
                                          ]})

    # Настройка размеров отображения таблицы
    cell_format = workbook.add_format()
    cell_format.set_text_wrap()
    worksheet.set_column('A:K', 30)

    # Запись в Excel файл
    row,col = 1,0

    # Добавить сюда код чтобы всё было норм
    for item in serializer.data:
        worksheet.write(row, col, item['name'],cell_format)
        worksheet.write(row, col + 1, item['pic_url'],cell_format)
        worksheet.write(row, col + 2, item['brief_disc'],cell_format)
        worksheet.write(row, col + 3, item['full_disc'],cell_format)
        worksheet.write(row, col + 4, item['adress'],cell_format)
        worksheet.write(row, col + 5, item['time_start'],cell_format)
        worksheet.write(row, col + 6, item['time_end'],cell_format)

        # Тут надо отедльную обработку для ролей придумать
        print(item['roles'])

        worksheet.write(row, col + 8, item['coord_long'],cell_format)
        worksheet.write(row, col + 9, item['coord_lat'],cell_format)
        worksheet.write(row, col + 10, item['phonenumber'],cell_format)
        row += 1
    workbook.close()

    # Отправляем сформированный документ
    if os.path.exists(filepath):
        with open(filepath, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            response['Content-Disposition'] = 'attachment; filename=events.xlsx'
            return response

def download_horeca(request):

    # Формируем excel
    queryset = HoReCa.objects.all()
    serializer = HoReCaDetailSerializer(queryset, many = True)

    # Создание excel файла
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    filename = 'horeca.xlsx'
    filepath = BASE_DIR + '/oborona_taganroga/files/' + filename

    # size = 'A1:Е'+str(len(serializer.data) + 1)
    size = 'A1:E'+str(len(serializer.data) + 1)
    workbook = xlsxwriter.Workbook(filepath)
    worksheet = workbook.add_worksheet()
    worksheet.add_table(size, {'autofilter': False, 'columns':
                                         [{'header': 'Название'},
                                          {'header': 'Описание'},
                                          {'header': 'Широта'},
                                          {'header': 'Долгота'},
                                          {'header': 'Мобильный'},
                                          ]})

    # Настройка размеров отображения таблицы
    cell_format = workbook.add_format()
    cell_format.set_text_wrap()
    worksheet.set_column('A:E', 30)

    # Запись в Excel файл
    row,col = 1,0

    # Добавить сюда код чтобы всё было норм
    for item in serializer.data:
        worksheet.write(row, col, item['name'],cell_format)
        worksheet.write(row, col + 1, item['discription'],cell_format)
        worksheet.write(row, col + 2, item['coord_long'],cell_format)
        worksheet.write(row, col + 3, item['coord_lat'],cell_format)
        worksheet.write(row, col + 4, item['phonenumber'],cell_format)
        row += 1
    workbook.close()

    # Отправляем сформированный документ
    if os.path.exists(filepath):
        with open(filepath, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            response['Content-Disposition'] = 'attachment; filename=horeca.xlsx'
            return response

def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'oborona_taganroga/name.html', {'form': form})


from menuProf import menuProf
from controladorProfessor import *
def mainprof():
    while True:
        opcMenu=menuProf()
        if opcMenu==1:
            CadastroProf()
        elif opcMenu==2:
            ListarProfessor()
        elif opcMenu==3:
            removerProfessor()
        elif opcMenu==4:
            ListraPorDiciplina()
        elif opcMenu == 5:
            print('Aplicação finalizada!')
            break
        else:
            print("Opção invalida!!")

   # mainprof()

Projetos utilizando lista-dicionario-CRUD/sistema CRUD/mainProfessor.py


balance = 700
papers=[100, 50, 10, 5,4,3,2,1]

def withdraw(balance, request):
    if balance < request :
        print('Sorry, you are try withdraw: {0}, but Your balance just : {1}'.format(request, balance))
    else:
        print ('your balance >>', balance)
        orgnal_request = request
        while request > 0:
            for i in papers:
                while request >= i:
                    print('give', i)
                    request-=i
        balance -= orgnal_request
    return balance

def withdraw1(balance, request):
    give = 0
    if balance < request :
        print('Sorry, you are try withdraw: {0}, but Your balance just : {1}'.format(request, balance))
    else:
        print ('your balance >>', balance)
        balance -= request
        while request > 0:
                if request >= 100:
                    give = 100
                elif request >= 50:
                    give = 50
                elif request >= 10:
                    give = 10
                elif request >= 5:
                    give = 5
                else :
                    give = request
                print('give',give)
                request -= give
    return balance

balance = withdraw(balance, 777)
balance = withdraw(balance, 276)
balance = withdraw1(balance, 276)
balance = withdraw(balance, 34)
balance = withdraw1(balance, 5)
balance = withdraw1(balance, 500)


class Solution:
    # O(N*K) Time | O(N*K) Space => N -> Number of words; K -> Max Word Length
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        anagrams = collections.defaultdict(list)
        result = []

        for word in strs:
            charCount = [0 for __ in range(26)]
            for char in word:
                charIdx = ord(char) - ord("a")
                charCount[charIdx] += 1
            anagrams[tuple(charCount)].append(word)

        for anagramGroup in anagrams.values():
            result.append(anagramGroup)

        return result


import time
import numpy as np
import sys
import random
import os
import warnings

warnings.filterwarnings("ignore", category=UserWarning)

import torch
from torch.utils.tensorboard import SummaryWriter
import torch.distributed as dist
import torch.multiprocessing as mp
import torch.utils.data.distributed
from tqdm import tqdm

sys.path.append('./')

from data_process.kitti_dataloader import create_train_dataloader, create_val_dataloader
from models.model_utils import create_model, make_data_parallel, get_num_parameters
from utils.train_utils import create_optimizer, create_lr_scheduler, get_saved_state, save_checkpoint
from utils.train_utils import reduce_tensor, to_python_float, get_tensorboard_log
from utils.misc import AverageMeter, ProgressMeter
from utils.logger import Logger
from config.train_config import parse_train_configs
from evaluate import evaluate_mAP

def main():
    configs = parse_train_configs()

    # Re-produce results
    if configs.seed is not None:
        random.seed(configs.seed)
        np.random.seed(configs.seed)
        torch.manual_seed(configs.seed)
        torch.backends.cudnn.deterministic = True
        torch.backends.cudnn.benchmark = False

    if configs.gpu_idx is not None:
        print('You have chosen a specific GPU. This will completely disable data parallelism.')

    if configs.dist_url == "env://" and configs.world_size == -1:
        configs.world_size = int(os.environ["WORLD_SIZE"])

    configs.distributed = configs.world_size > 1 or configs.multiprocessing_distributed

    if configs.multiprocessing_distributed:
        configs.world_size = configs.ngpus_per_node * configs.world_size
        mp.spawn(main_worker, nprocs=configs.ngpus_per_node, args=(configs,))
    else:
        main_worker(configs.gpu_idx, configs)

def main_worker(gpu_idx, configs):
    configs.gpu_idx = gpu_idx
    configs.device = torch.device('cpu' if configs.gpu_idx is None else 'cuda:{}'.format(configs.gpu_idx))

    if configs.distributed:
        if configs.dist_url == "env://" and configs.rank == -1:
            configs.rank = int(os.environ["RANK"])
        if configs.multiprocessing_distributed:
            # For multiprocessing distributed training, rank needs to be the
            # global rank among all the processes
            configs.rank = configs.rank * configs.ngpus_per_node + gpu_idx

        dist.init_process_group(backend=configs.dist_backend, init_method=configs.dist_url,
                                world_size=configs.world_size, rank=configs.rank)
        configs.subdivisions = int(64 / configs.batch_size / configs.ngpus_per_node)
    else:
        configs.subdivisions = int(64 / configs.batch_size)

    configs.is_master_node = (not configs.distributed) or (
            configs.distributed and (configs.rank % configs.ngpus_per_node == 0))

    if configs.is_master_node:
        logger = Logger(configs.logs_dir, configs.saved_fn)
        logger.info('>>> Created a new logger')
        logger.info('>>> configs: {}'.format(configs))
        tb_writer = SummaryWriter(log_dir=os.path.join(configs.logs_dir, 'tensorboard'))
    else:
        logger = None
        tb_writer = None

    # model
    model = create_model(configs)

    # load weight from a checkpoint
    if configs.pretrained_path is not None:
        assert os.path.isfile(configs.pretrained_path), "=> no checkpoint found at '{}'".format(configs.pretrained_path)
        model.load_state_dict(torch.load(configs.pretrained_path))
        if logger is not None:
            logger.info('loaded pretrained model at {}'.format(configs.pretrained_path))

    # resume weights of model from a checkpoint
    if configs.resume_path is not None:
        assert os.path.isfile(configs.resume_path), "=> no checkpoint found at '{}'".format(configs.resume_path)
        model.load_state_dict(torch.load(configs.resume_path))
        if logger is not None:
            logger.info('resume training model from checkpoint {}'.format(configs.resume_path))

    # Data Parallel
    model = make_data_parallel(model, configs)

    # Make sure to create optimizer after moving the model to cuda
    optimizer = create_optimizer(configs, model)
    lr_scheduler = create_lr_scheduler(optimizer, configs)
    configs.step_lr_in_epoch = True if configs.lr_type in ['multi_step'] else False

    # resume optimizer, lr_scheduler from a checkpoint
    if configs.resume_path is not None:
        utils_path = configs.resume_path.replace('Model_', 'Utils_')
        assert os.path.isfile(utils_path), "=> no checkpoint found at '{}'".format(utils_path)
        utils_state_dict = torch.load(utils_path, map_location='cuda:{}'.format(configs.gpu_idx))
        optimizer.load_state_dict(utils_state_dict['optimizer'])
        lr_scheduler.load_state_dict(utils_state_dict['lr_scheduler'])
        configs.start_epoch = utils_state_dict['epoch'] + 1

    if configs.is_master_node:
        num_parameters = get_num_parameters(model)
        logger.info('number of trained parameters of the model: {}'.format(num_parameters))

    if logger is not None:
        logger.info(">>> Loading dataset & getting dataloader...")
    # Create dataloader
    train_dataloader, train_sampler = create_train_dataloader(configs)
    if logger is not None:
        logger.info('number of batches in training set: {}'.format(len(train_dataloader)))

    if configs.evaluate:
        val_dataloader = create_val_dataloader(configs)
        precision, recall, AP, f1, ap_class = evaluate_mAP(val_dataloader, model, configs, None)
        print('Evaluate - precision: {}, recall: {}, AP: {}, f1: {}, ap_class: {}'.format(precision, recall, AP, f1,
                                                                                ap_class))
        print('mAP {}'.format(AP.mean()))
        return

    for epoch in range(configs.start_epoch, configs.num_epochs + 1):
        if logger is not None:
            logger.info('{}'.format('*-' * 40))
            logger.info('{} {}/{} {}'.format('=' * 35, epoch, configs.num_epochs, '=' * 35))
            logger.info('{}'.format('*-' * 40))
            logger.info('>>> Epoch: [{}/{}]'.format(epoch, configs.num_epochs))

        if configs.distributed:
            train_sampler.set_epoch(epoch)
        # train for one epoch
        train_one_epoch(train_dataloader, model, optimizer, lr_scheduler, epoch, configs, logger, tb_writer)
        if not configs.no_val:
            val_dataloader = create_val_dataloader(configs)
            print('number of batches in val_dataloader: {}'.format(len(val_dataloader)))
            precision, recall, AP, f1, ap_class = evaluate_mAP(val_dataloader, model, configs, logger)
            val_metrics_dict = {
                'precision': precision.mean(),
                'recall': recall.mean(),
                'AP': AP.mean(),
                'f1': f1.mean(),
                'ap_class': ap_class.mean()
            }
            if tb_writer is not None:
                tb_writer.add_scalars('Validation', val_metrics_dict, epoch)

        # Save checkpoint
        if configs.is_master_node and ((epoch % configs.checkpoint_freq) == 0):
            model_state_dict, utils_state_dict = get_saved_state(model, optimizer, lr_scheduler, epoch, configs)
            save_checkpoint(configs.checkpoints_dir, configs.saved_fn, model_state_dict, utils_state_dict, epoch)

        if not configs.step_lr_in_epoch:
            lr_scheduler.step()
            if tb_writer is not None:
                tb_writer.add_scalar('LR', lr_scheduler.get_lr()[0], epoch)

    if tb_writer is not None:
        tb_writer.close()
    if configs.distributed:
        cleanup()

def cleanup():
    dist.destroy_process_group()

def train_one_epoch(train_dataloader, model, optimizer, lr_scheduler, epoch, configs, logger, tb_writer):
    batch_time = AverageMeter('Time', ':6.3f')
    data_time = AverageMeter('Data', ':6.3f')
    losses = AverageMeter('Loss', ':.4e')

    progress = ProgressMeter(len(train_dataloader), [batch_time, data_time, losses],
                             prefix="Train - Epoch: [{}/{}]".format(epoch, configs.num_epochs))

    num_iters_per_epoch = len(train_dataloader)

    # switch to train mode
    model.train()
    start_time = time.time()
    for batch_idx, batch_data in enumerate(tqdm(train_dataloader)):
        data_time.update(time.time() - start_time)
        _, imgs, targets = batch_data
        global_step = num_iters_per_epoch * (epoch - 1) + batch_idx + 1

        batch_size = imgs.size(0)

        targets = targets.to(configs.device, non_blocking=True)
        imgs = imgs.to(configs.device, non_blocking=True)
        total_loss, outputs = model(imgs, targets)

        # For torch.nn.DataParallel case
        if (not configs.distributed) and (configs.gpu_idx is None):
            total_loss = torch.mean(total_loss)

        # compute gradient and perform backpropagation
        total_loss.backward()
        if global_step % configs.subdivisions == 0:
            optimizer.step()
            # Adjust learning rate
            if configs.step_lr_in_epoch:
                lr_scheduler.step()
                if tb_writer is not None:
                    tb_writer.add_scalar('LR', lr_scheduler.get_lr()[0], global_step)
            # zero the parameter gradients
            optimizer.zero_grad()

        if configs.distributed:
            reduced_loss = reduce_tensor(total_loss.data, configs.world_size)
        else:
            reduced_loss = total_loss.data
        losses.update(to_python_float(reduced_loss), batch_size)
        # measure elapsed time
        # torch.cuda.synchronize()
        batch_time.update(time.time() - start_time)

        if tb_writer is not None:
            if (global_step % configs.tensorboard_freq) == 0:
                tensorboard_log = get_tensorboard_log(model)
                tb_writer.add_scalar('avg_loss', losses.avg, global_step)
                for layer_name, layer_dict in tensorboard_log.items():
                    tb_writer.add_scalars(layer_name, layer_dict, global_step)

        # Log message
        if logger is not None:
            if (global_step % configs.print_freq) == 0:
                logger.info(progress.get_message(batch_idx))

        start_time = time.time()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        try:
            cleanup()
            sys.exit(0)
        except SystemExit:
            os._exit(0)


from typing import List

from stx import app, logger
from stx.components import (
    Component, Composite, CodeBlock, Table, Image,
    FunctionCall, CustomText, Layout)
from stx.components import ListBlock, Paragraph, PlainText, StyledText
from stx.components import LinkText, Literal, Figure, Section, Separator
from stx.components import ContentBox, TableOfContents, ElementReference
from stx.components import CapturedText
from stx.document import Document
from stx.outputs.html.dom import Tag
from stx.outputs.html.themes import HtmlTheme
from stx.utils.stx_error import StxError

TYPE_H_TAGS = {
    'chapter': 'h1',
    'sect1': 'h1',
    'sect2': 'h2',
    'sect3': 'h3',
    'sect4': 'h4',
    'sect5': 'h5',
}

CAPTURED_CLASS_TAGS = [
    'cite', 'ins', 'kbd', 'mark', 'q', 's',
    'samp', 'small', 'sub', 'sup', 'var',
]

def document_to_html(document: Document, theme: HtmlTheme) -> List[Tag]:
    logger.info('Serializing HTML5 book...')

    html = Tag('html')

    generate_head(document, html, theme)

    generate_body(document, html, theme)

    return [Tag('!DOCTYPE html'), html]

def generate_head(document: Document, html: Tag, theme: HtmlTheme):
    head = html.append_tag('head')

    if document.encoding:
        head.append_tag('meta', {'charset': document.encoding})

    if document.author:
        head.append_tag('meta', {
            'name': 'author',
            'content': document.author,
        })

    head.append_tag('meta', {
        'name': 'generator',
        'content': app.app_title,
    })

    if document.title:
        head.append_tag('title', text=document.title)

    for css in theme.head_styles:
        head.append_tag('style', {
            'type': 'text/css',
        }, text=css, text_literal=True)

    for stylesheet in document.stylesheets:
        head.append_tag('link', {
            'rel': 'stylesheet',
            'type': 'text/css',
            'href': stylesheet,
        })

    for js in theme.head_scripts:
        head.append_tag('script', {
            'type': 'application/javascript',
        }, text=js, text_literal=True)

def generate_body(document: Document, html: Tag, theme: HtmlTheme):
    body = html.append_tag('body', {'data-type': 'book'})

    if document.title is not None:
        body.append_tag('h1', text=document.title)

    if document.header is not None:
        header = body.append_tag('header')

        generate_component(header, document.header)

    if document.content is not None:
        generate_component(body, document.content)

    if document.footer is not None:
        footer = body.append_tag('footer')

        generate_component(footer, document.footer)

    for js in theme.body_scripts:
        body.append_tag('script', {
            'type': 'application/javascript',
        }, text=js, text_literal=True)

def generate_component(
        parent: Tag, component: Component,
        collapse_paragraph=False,
        collapse_section=False):
    if isinstance(component, Composite):
        generate_components(parent, component.components)
    elif isinstance(component, CodeBlock):
        generate_code_block(parent, component)
    elif isinstance(component, Table):
        generate_table(parent, component)
    elif isinstance(component, ListBlock):
        generate_list_block(parent, component)
    elif isinstance(component, Paragraph):
        generate_paragraph(parent, component, collapse_paragraph)
    elif isinstance(component, PlainText):
        generate_plain_text(parent, component)
    elif isinstance(component, StyledText):
        generate_styled_text(parent, component)
    elif isinstance(component, CustomText):
        generate_custom_text(parent, component)
    elif isinstance(component, LinkText):
        generate_link_text(parent, component)
    elif isinstance(component, CapturedText):
        generate_captured_text(parent, component)
    elif isinstance(component, Literal):
        generate_literal(parent, component)
    elif isinstance(component, Figure):
        generate_figure(parent, component)
    elif isinstance(component, Section):
        generate_section(parent, component, collapse_section)
    elif isinstance(component, TableOfContents):
        generate_toc(parent, component)
    elif isinstance(component, Separator):
        generate_separator(parent, component)
    elif isinstance(component, ContentBox):
        generate_box(parent, component)
    elif isinstance(component, Image):
        generate_image(parent, component)
    elif isinstance(component, FunctionCall):
        generate_function_call(parent, component)
    elif isinstance(component, Layout):
        generate_layout(parent, component)
    else:
        raise NotImplementedError(f'Not implemented type: {type(component)}')

def generate_components(parent: Tag, components: List[Component]):
    for child in components:
        generate_component(parent, child)

def generate_code_block(parent: Tag, code_block: CodeBlock):
    pre = append_component_tag(parent, code_block, 'pre')

    pre.preserve_spaces = True

    pre['data-type'] = 'programlisting'

    if code_block.lang is not None:
        pre['data-code-language'] = code_block.lang

    generate_components(pre, code_block.contents)

def generate_table(parent: Tag, table: Table):
    table_tag = append_component_tag(parent, table, 'table')

    if table.caption is not None:
        caption_tag = table_tag.append_tag('caption')

        if table.number is not None:
            caption_tag['data-number'] = table.number

        generate_component(
            caption_tag, table.caption, collapse_paragraph=True)

    for row in table.rows:
        row_tag = table_tag.append_tag('tr')

        if row.header:
            cell_tag_name = 'th'
        else:
            cell_tag_name = 'td'

        for cell in row.cells:
            cell_tag = row_tag.append_tag(cell_tag_name)

            generate_component(cell_tag, cell, collapse_paragraph=True)

def generate_list_block(parent: Tag, list_block: ListBlock):
    if list_block.ordered:
        list_tag_name = 'ol'
    else:
        list_tag_name = 'ul'

    list_tag = append_component_tag(parent, list_block, list_tag_name)

    for item in list_block.items:
        item_tag = list_tag.append_tag('li')

        generate_component(item_tag, item, collapse_paragraph=True)

def generate_paragraph(parent: Tag, paragraph: Paragraph, collapse: bool):
    if not collapse:
        p_tag = append_component_tag(parent, paragraph, 'p')
    else:
        p_tag = parent

    generate_components(p_tag, paragraph.contents)

def generate_plain_text(parent: Tag, plain_text: PlainText):
    for ref in plain_text.get_refs():
        parent.append_tag('a', {'id': ref}, text='')

    parent.append_text(plain_text.content)

def generate_styled_text(parent: Tag, styled_text: StyledText):
    if styled_text.style == 'strong':
        tag_name = 'strong'
    elif styled_text.style == 'emphasized':
        tag_name = 'em'
    elif styled_text.style == 'code':
        tag_name = 'code'
    elif styled_text.style == 'deleted':
        tag_name = 'del'
    else:
        tag_name = None

    if tag_name is not None:
        styled_tag = append_component_tag(parent, styled_text, tag_name)

        generate_components(styled_tag, styled_text.contents)
    else:
        if styled_text.style == 'double-quote':
            parent.append_literal('“')
            generate_components(parent, styled_text.contents)
            parent.append_literal('”')
        elif styled_text.style == 'single-quote':
            parent.append_literal('‘')
            generate_components(parent, styled_text.contents)
            parent.append_literal('’')
        else:
            raise StxError(
                f'Not supported style: {styled_text.style}.',
                styled_text.location)

def generate_custom_text(parent: Tag, styled_text: CustomText):
    styled_tag = append_component_tag(parent, styled_text, 'span')

    if styled_text.custom_style is not None:
        styled_tag['class'] = styled_text.custom_style

    generate_components(styled_tag, styled_text.contents)

def generate_link_text(parent: Tag, link_text: LinkText):
    a_tag = append_component_tag(parent, link_text, 'a')

    if link_text.is_internal():
        a_tag['href'] = f'#{link_text.reference}'
        a_tag['data-type'] = 'xref'
    elif link_text.is_external():
        a_tag['href'] = link_text.reference

    if link_text.invalid:
        a_tag['data-status'] = 'invalid'

    generate_components(a_tag, link_text.contents)

def generate_captured_text(parent: Tag, captured: CapturedText):
    if captured.class_ in CAPTURED_CLASS_TAGS:
        cap_tag = append_component_tag(parent, captured, captured.class_)
    else:
        cap_tag = append_component_tag(parent, captured, 'span')

        if captured.class_:
            cap_tag['class'] = captured.class_

    generate_components(cap_tag, captured.contents)

def generate_literal(parent: Tag, literal: Literal):
    parent.append_literal(literal.text)

def generate_figure(parent: Tag, figure: Figure):
    figure_tag = append_component_tag(parent, figure, 'figure')

    generate_component(figure_tag, figure.content)

    caption_tag = figure_tag.append_tag('figcaption')

    if figure.number is not None:
        caption_tag['data-number'] = figure.number

    generate_component(caption_tag, figure.caption, collapse_paragraph=True)

def generate_section(parent: Tag, section: Section, collapse: bool):
    if not collapse:
        section_tag = append_component_tag(parent, section, 'section')
    else:
        section_tag = parent

    if section.type is not None:
        section_tag['data-type'] = section.type

    if section.type in TYPE_H_TAGS:
        h_tag_name = TYPE_H_TAGS[section.type]
    else:
        level = section.level

        if level < 1:
            level = 1
        elif level > 6:
            level = 6

        h_tag_name = f'h{level}'

    h_tag = section_tag.append_tag(h_tag_name)

    if section.number is not None:
        h_tag['data-number'] = section.number

    generate_component(h_tag, section.heading, collapse_paragraph=True)

    generate_component(section_tag, section.content)

def generate_toc(parent: Tag, toc: TableOfContents):
    nav_tag = append_component_tag(parent, toc, 'nav')
    nav_tag['data-type'] = 'toc'

    if toc.title is not None:
        nav_tag.append_tag('h1', text=toc.title)

    generate_toc_elements(nav_tag, toc.elements)

def generate_toc_elements(parent: Tag, elements: List[ElementReference]):
    if len(elements) == 0:
        return

    list_tag = parent.append_tag('ol')

    for element in elements:
        item_tag = list_tag.append_tag('li')

        a_tag = item_tag.append_tag('a', {
            'href': f'#{element.reference}',
            'data-type': 'xref',
        }, text=element.title)

        if element.number is not None:
            a_tag['data-number'] = element.number

        generate_toc_elements(item_tag, element.elements)

def generate_separator(parent: Tag, separator: Separator):
    sep = append_component_tag(parent, separator, 'hr')
    sep['data-level'] = separator.level

def generate_box(parent: Tag, box: ContentBox):
    box_tag = append_component_tag(parent, box, 'div')

    if box.style is not None:
        box_tag['data-type'] = box.style

    generate_component(box_tag, box.content, collapse_section=True)

def generate_image(parent: Tag, image: Image):
    img_tag = parent.append_tag('img')
    img_tag['src'] = image.src

    if image.alt:
        img_tag['alt'] = image.alt

def generate_function_call(parent: Tag, call: FunctionCall):
    if call.result is None:
        raise StxError(
            f'Function {call.key} was not processed.', call.location)

    generate_component(parent, call.result)

def generate_layout(parent: Tag, layout: Layout):
    container = parent.append_tag('div', {
        'data-type': 'layout',
        'data-dir': layout.direction,
    })

    for component in layout.components:
        item = container.append_tag('div', {
            'data-type': 'layout-item',
        })

        generate_component(item, component)

def append_component_tag(
        parent: Tag, component: Component, tag_name: str) -> Tag:
    for other_id in reversed(component.get_other_refs()):
        parent.append_tag('a', {'id': other_id}, text='')

    tag = parent.append_tag(tag_name)

    tag_id = component.get_main_ref()

    if tag_id is not None:
        tag['id'] = tag_id

    return tag


from flask import Blueprint, jsonify, request
from app.models import TipoSitioEtiqueta, Etiqueta

mostrar_etiquetas_bp = Blueprint('mostrar_etiquetas', __name__)

@mostrar_etiquetas_bp.route('/mostrar_etiquetas/<int:cve_tipo_sitio>', methods=['GET'])
def mostrar_etiquetas(cve_tipo_sitio):

    ## VALIDACIONES DE ENTRADA ##
    relacion_etiquetas = TipoSitioEtiqueta.query.filter_by(cve_tipo_sitio=cve_tipo_sitio).all()
    if not relacion_etiquetas:
        return jsonify({"mensaje": "No se encontraron etiquetas relacionadas con ese tipo sitio."}), 404

    arreglo_etiquetas = []
    for relacion in relacion_etiquetas:
        etiqueta: Etiqueta = Etiqueta.query.get(relacion.cve_etiqueta)
        infoEtiqueta = {}
        infoEtiqueta["cve_etiqueta"] = etiqueta.cve_etiqueta
        infoEtiqueta["nombre_etiqueta"] = etiqueta.nombre_etiqueta
        arreglo_etiquetas.append(infoEtiqueta)

    return jsonify(arreglo_etiquetas), 200


# Singly-linked lists are already defined with this interface:
# class ListNode(object):
#   def __init__(self, x):
#     self.value = x
#     self.next = None
#
def condense_linked_list(node):
    cache = {}

    newlist = []

    while node:
        for i in node:
            if i in cache:
                newlist.append(i)

            else:
                newlist.append(i)
    return newlist

node = [3, 4, 3, 2, 6, 1, 2, 6]
# Expected Output: [3, 4, 2, 6, 1]

print(node)
print(condense_linked_list(node))


import os, inspect, datetime
from qgis.PyQt import uic, QtCore, QtGui
from qgis.PyQt.QtWidgets import QWidget

from ...base3.qgswidgets.lamia_form_deficiency import BaseDeficiencyTool
from .lamia_form_observation import BaseConstructionsiteObservationTool
from Lamia.api.libslamia.lamiareport.lamiareport import ReportCore

from Lamia.qgisiface.iface.qgiswidget.tools.form_subwidgets.subwidget_lidchooser import (
    LidChooserWidget,
)

# from Lamia.qgisiface.iface.qgiswidget.tools.form_subwidgets.subwidget_createsubfeature import (
#     CreateSubFeatureWidget,
# )

class BaseConstructionsiteDeficiencyTool(BaseDeficiencyTool):

    PREPROTOOLNAME = "deficiencypv"
    tooltreewidgetSUBCAT = QtCore.QCoreApplication.translate(
        "base3_cs", "Proces verbal"
    )

    def __init__(self, **kwargs):
        super(BaseConstructionsiteDeficiencyTool, self).__init__(**kwargs)

    def initMainToolWidget(self):
        if self.dbase.variante in [None, "Lamia"]:
            self.toolwidgetmain = UserUI()
            self.formtoolwidgetconfdictmain = {
                "deficiency": {
                    "linkfield": "id_deficiency",
                    "widgets": {
                        #'groupedesordre': self.toolwidgetmain.comboBox_groupedes,
                        # 'deficiencyobservatortype': self.toolwidgetmain.comboBox_detecteur,
                        # 'detecteur_com': self.toolwidgetmain.lineEdit_detecteur,
                    },
                },
                "object": {
                    "linkfield": "id_object",
                    "widgets": {
                        # 'comment': self.toolwidgetmain.lineEdit_detecteur,
                    },
                },
            }

            # self.tabWidget.removeTab(0)
            # self.SKIP_LOADING_UI = True
            self.TABLEFILTERFIELD = {"deficiencycategory": "PVE"}
            self.toolwidgetmain.stackedWidget.setCurrentIndex(1)
            self.dbasechildwdgfield = []
            self.instancekwargs["parentwidget"] = self
            self.temppropertieswdgOBSERVATION = BaseConstructionsiteObservationTool(
                **self.instancekwargs
            )
            self.temppropertieswdgOBSERVATION.TABLEFILTERFIELD = {
                "observationcategory": "PVA"
            }
            # self.temppropertieswdgOBSERVATION.SKIP_LOADING_UI = True
            self.temppropertieswdgOBSERVATION.tooltreewidgetSUBCAT = "Procès verbal"
            # temppropertieswdgOBSERVATION.tooltreewidgetSUBCAT = displayname
            # exec('self.propertieswdgOBSERVATION{} = temppropertieswdgOBSERVATION'.format(observationcategory))
            # exec('self.dbasechildwdgfield.append(self.propertieswdgOBSERVATION{} )'.format(observationcategory))
            self.dbasechildwdgfield.append(self.temppropertieswdgOBSERVATION)

            # # * lamiawdg
            # self.createobswdg = CreateSubFeatureWidget(
            #     self, self.temppropertieswdgOBSERVATION
            # )
            # self.lamiawidgets.append(self.createobswdg)

        else:
            self.unloadWidgetinToolTree()
            self.loadWidgetinToolTree = lambda: None
            # self.toolTreeWidgetCurrentItemChanged = lambda: None

    def magicFunction(self):
        self.featureSelected()
        self.addGPSPoint()
        self.saveFeature()
        for wdgobservation in self.dbasechildwdgfield:
            if hasattr(wdgobservation, "OBSTYPE") and wdgobservation.OBSTYPE == "NCA":
                wdgobservation.featureSelected()
                wdgobservation.saveFeature()

    # def postInitFeatureProperties(self, feat):
    def postSelectFeature(self):
        super().postSelectFeature()

    """
    def postSaveFeature(self, savedfeaturepk=None):
        self.formutils.createNewSubFeature(
            self.temppropertieswdgOBSERVATION, savedfeaturepk
        )
    """

    def printWidget(self):

        # create finelname
        pdfdirectory = os.path.join(self.dbase.dbaseressourcesdirectory, "Print")
        if not os.path.isdir(pdfdirectory):
            os.mkdir(pdfdirectory)

        currentid = self.dbase.getValuesFromPk(
            "deficiency", "id_deficiency", self.currentFeaturePK
        )

        date = str(datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))

        filename = str(currentid) + "_deficiency_" + date + ".pdf"

        pdffilename = os.path.join(pdfdirectory, filename)

        # choose phaseA report or phase C report
        sql = (
            "SELECT observationcategory FROM  observation_now WHERE observation_now.lid_deficiency = "
            + str(currentid)
        )
        sql = self.dbase.updateQueryTableNow(sql)
        res = self.dbase.query(sql)

        if (
            res is not None
            and len(res) > 0
            and not self.dbase.utils.isAttributeNull(res[0][0])
        ):
            if res[0][0] == "PVA":
                reporttype = "TRAMprocesverbalmiseadisposition"
            """
            elif res[0][0][0:2] == "NC":
                sql = "SELECT id_observation FROM observation_now WHERE observation_now.typeobservation = 'NCB'"
                sql += " AND Observation_now.lid_desordre = " + str(currentid)
                sql = self.dbase.updateQueryTableNow(sql)
                res = self.dbase.query(sql)
                if self.dbase.variante in [None, "Lamia"]:
                    if (
                        res is not None
                        and len(res) > 0
                        and not self.dbase.utils.isAttributeNull(res[0][0])
                    ):
                        reportype = "TRAMnonconformite"
                    else:
                        reportype = "TRAMnonconformitephaseA"
                elif self.dbase.variante in ["Orange"]:
                    print("*********ORANGEnonconformitephaseA")
                    reportype = "ORANGEnonconformitephaseA"
            """
        else:
            return

        # run report
        self.reporttool = ReportCore(
            dbaseparser=self.dbase, messageinstance=self.mainifacewidget.connector
        )
        self.reporttool.runReport(
            destinationfile=pdffilename,
            reportconffilename=reporttype,
            pklist={0: [self.currentFeaturePK]},
        )

class UserUI(QWidget):
    def __init__(self, parent=None):
        super(UserUI, self).__init__(parent=parent)
        uipath = os.path.join(os.path.dirname(__file__), "lamia_form_deficiency_ui.ui")
        uic.loadUi(uipath, self)


from abc import ABC, abstractmethod

class Camara(ABC):
    def __init__(self, idcam, nombre, resolucion):
        self.idcam = idcam
        self.nombre = nombre
        self.resolucion = resolucion

    @abstractmethod
    def tr(self):
        pass

class Sesion:
    def __init__(self, id, nombre_asignatura, nombre_profesor, sala, fecha_clase, hora_inicio, hora_fin):
        self.id = id
        self.nombre_asignatura = nombre_asignatura
        self.nombre_profesor = nombre_profesor
        self.sala = sala
        self.fecha_clase = fecha_clase
        self.hora_inicio = hora_inicio
        self.hora_fin = hora_fin
        self.camara_en_uso = None
        self.lista_camaras = []

    def agregar_camara(self, camara):
        self.lista_camaras.append(camara)

    def cambiar_camara(self, indice):
        if indice < len(self.lista_camaras):
            self.camara_en_uso = self.lista_camaras[indice]
            print(f"Cambiando a la cámara {self.camara_en_uso.nombre}")
        else:
            print("Índice de cámara inválido")

    def crear_camara(self):
        idcam = input("Ingrese el ID de la cámara: ")
        nombre = input("Ingrese el nombre de la cámara: ")
        resolucion = input("Ingrese la resolución de la cámara: ")
        camara = Camara(idcam, nombre, resolucion)
        self.agregar_camara(camara)

class Main:
    def __init__(self):
        self.sesion = None

    def crear_sesion(self):
        self.sesion = Sesion(input("Ingrese el ID de la sesión: "),
                             input("Ingrese el nombre de la asignatura: "),
                             input("Ingrese el nombre del profesor: "),
                             input("Ingrese el nombre de la sala: "),
                             input("Ingrese la fecha de la clase (en formato AAAA-MM-DD): "),
                             input("Ingrese la hora de inicio de la clase (en formato HH:MM): "),
                             input("Ingrese la hora de fin de la clase (en formato HH:MM): "))
        print(f"Sesión creada con ID {self.sesion.id}")

    def crear_camara(self):
        self.sesion.crear_camara()

    def cambiar_camara(self):
        indice = int(input("Ingrese el índice de la cámara a la que desea cambiar: "))
        self.sesion.cambiar_camara(indice)

    def ejecutar(self):
        opcion = input("¿Desea crear una sesión? (s/n): ")
        if opcion == "s":
            self.crear_sesion()
        while True:
            opcion = input("Ingrese 'c' para crear una cámara, 's' para cambiar de cámara o 'salir' para terminar: ")
            if opcion == "c":
                self.crear_camara()
            elif opcion == "s":
                self.cambiar_camara()
            elif opcion == "salir":
                break

# Ejemplo de uso
main = Main()
main.ejecutar()

Taller de programacion aplicada/Actividades y Tareas/Tarea 2/main test.py


from yahooquery import Ticker
from datetime import datetime

simbolo = "TAEE11.SA"

papel = Ticker(simbolo)
data_ex = papel.summary_detail[simbolo]["exDividendDate"]
data_ex = datetime.strptime(data_ex, "%Y-%m-%d %H:%M:%S").strftime("%d/%m/%Y")

print(data_ex)


import numpy as np
import matplotlib.pyplot as plt

np.random.seed(7)

## Params for 2 gaussians
mu1, sigma1 = ([0.2,0.8], [[0.01,0],[0,0.01]])
mu2, sigma2 = ([0.8,0.2], [[0.01,0],[0,0.01]])

samples = np.array([])
num_samples = 4000

for i in range(num_samples):
    p = np.random.uniform(0,1,1)

    if p < 0.5:
        val = np.random.multivariate_normal(mu1, sigma1, 1)
    else:
        val = np.random.multivariate_normal(mu2, sigma2, 1)

    if samples.shape[0] is 0:
        samples = val
        continue
    samples = np.append(samples, val, axis=0)

## Normalizing all samples in [0,1]
samples = (samples - np.min(samples, axis=0))/(np.max(samples, axis=0) - np.min(samples, axis=0))
## Saving samples to file
np.savetxt("mixgaussians.csv", samples, delimiter=",")

## Plotting
from mpl_toolkits.mplot3d import Axes3D
x = samples[:,0]
y = samples[:,1]
z = np.ones(samples.shape[0])
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x, y, z)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()


def find_cat(a):
    global N
    status = (a/(220-N))*100
    if status < 60: return 0
    elif status < 68: return 1
    elif status < 75: return 2
    elif status < 80: return 3
    elif status < 90: return 4
    return 5

N = int(input())
answers = [0 for _ in range(6)]

while True:
    try:
        x = input()
        answers[find_cat(int(x))]+=1
    except EOFError:
        break

for answer in reversed(answers):
    print(answer, end= ' ')


# -*- coding: utf-8 -*-
from odoo import api, models, fields, registry
import json
import ast
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
import odoo
import logging

_logger = logging.getLogger(__name__)

class pos_cache_database(models.Model):
    _name = "pos.cache.database"
    _description = "Management POS database"
    _rec_name = "res_id"

    res_id = fields.Char('Res Id')
    res_model = fields.Char('Res Model')
    deleted = fields.Boolean('Deleted', default=0)
    updated_date = fields.Datetime('Last updated date', readonly=1)

    @api.model
    def create(self, vals):
        vals['updated_date'] = fields.Datetime.now()
        return super(pos_cache_database, self).create(vals)

    @api.model
    def write(self, vals):
        vals['updated_date'] = fields.Datetime.now()
        return super(pos_cache_database, self).write(vals)

    @api.model
    def get_datas_backend_modified(self, updated_date):
        records = self.sudo().search([('updated_date', '>', updated_date)])
        results = []
        if records:
            for record in records:
                try:
                    val = self.env[record.res_model].browse(int(record.res_id)).get_data()
                    if record.deleted:
                        val['deleted'] = True
                        val['id'] = int(record.res_id)
                    val['write_date'] = record.updated_date
                    results.append(val)
                except:
                    val['deleted'] = True
                    val['id'] = int(record.res_id)
                    val['write_date'] = record.updated_date
                    results.append(val)
        return results

    @api.model
    def get_stock_datas(self, location_id, product_need_update_onhand=[]):
        values = {}
        product_object = self.env['product.product'].sudo()
        if not product_need_update_onhand:
            datas = product_object.with_context({'location' : location_id}).search_read(
                [('type', '=', 'product'), ('available_in_pos', '=', True)], ['qty_available'])
        else:
            datas = product_object.with_context({'location' : location_id}).search_read(
                [('id', 'in', product_need_update_onhand)],
                ['name', 'qty_available', 'default_code'])
        for data in datas:
            values[data['id']] = data['qty_available']
        return values

    @api.multi
    def get_fields_by_model(self, model_name):
        params = self.env['ir.config_parameter'].sudo().get_param(model_name)
        if not params:
            list_fields = self.env[model_name].fields_get()
            fields_load = []
            for k, v in list_fields.items():
                if v['type'] not in ['one2many', 'binary']:
                    fields_load.append(k)
            return fields_load
        else:
            params = ast.literal_eval(params)
            return params.get('fields', [])

    @api.multi
    def get_domain_by_model(self, model_name):
        params = self.env['ir.config_parameter'].sudo().get_param(model_name)
        if not params:
            return []
        else:
            params = ast.literal_eval(params)
            return params.get('domain', [])

    @api.model
    def insert_data(self, datas, model, first_install=False):
        if type(model) == list:
            return False
        all_fields = self.env[model].fields_get()
        version_info = odoo.release.version_info[0]
        if version_info == 12:
            if all_fields:
                for data in datas:
                    for field, value in data.items():
                        if field == 'model':
                            continue
                        if all_fields[field] and all_fields[field]['type'] in ['date', 'datetime'] and value:
                            data[field] = value.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        if first_install:
            for data in datas:
                self.create({
                    'res_id': str(data['id']),
                    'res_model': model,
                })
        else:
            for data in datas:
                last_caches = self.search([('res_id', '=', str(data['id'])), ('res_model', '=', model)])
                if last_caches:
                    last_caches.write({
                        'updated_date': fields.Datetime.now(),
                    })
                else:
                    self.create({
                        'res_id': str(data['id']),
                        'res_model': model,
                    })
        return True

    def sync_to_pos(self, data):
        if data['model'] == 'product.product':
            data['price'] = data['list_price']
        sessions = self.env['pos.session'].sudo().search([
            ('state', '=', 'opened')
        ])
        self.insert_data([data], data['model'])
        for session in sessions:
            self.env['bus.bus'].sendmany(
                [[(self.env.cr.dbname, 'pos.sync.data', session.user_id.id), data]])
        return True

    @api.model
    def remove_record(self, data):
        self.search([('res_id', '=', str(data['id'])), ('res_model', '=', data['model'])]).write({
            'deleted': True
        })
        sessions = self.env['pos.session'].sudo().search([
            ('state', '=', 'opened')
        ])
        data['deleted'] = True
        for session in sessions:
            self.env['bus.bus'].sendmany(
                [[(self.env.cr.dbname, 'pos.sync.data', session.user_id.id), data]])
        return True

    @api.model
    def save_parameter_models_load(self, model_datas):
        for model_name, value in model_datas.items():
            self.env['ir.config_parameter'].sudo().set_param(model_name, value)
        return True


from clickhouse_driver import Client
from make_table import make_table
from read_file import format_data

make_table('10.40.0.11')

data = format_data('event-data.json')

query = "INSERT INTO user.sessions FORMAT TabSeparated\n" + data

try:
    client = Client('10.40.0.11')
    result = client.execute(query)
    print(result)
except Client as e:
    print(e)
except Exception as e:
    print(e)


# -*- coding: utf-8 -*-
"""
Created on Tue Jul 24 19:38:34 2018

@author: jaidka
"""

#https://en.wikipedia.org/wiki/Category:Politics_of_the_United_States

#Code that uses pywikibot to download the edit history for a set of wikipedia articles
#the default version and language needs to be set in the user-config file.
#Please use and modify as needed. Good Luck!

#SEE THIS ONE https://doc.wikimedia.org/pywikibot/master/api_ref/pywikibot.html#module-pywikibot.page
#import page https://www.mediawiki.org/wiki/API:Revisions
#see https://stackoverflow.com/questions/34411896/how-to-get-full-wikipedia-revision-history-list-from-some-article
#maybe see http://paws-public.wmflabs.org/paws-public/47938337/02%20-%20Intro%20to%20pywikibot.ipynb
import pywikibot
#this is important: https://www.mediawiki.org/wiki/Manual:Pywikibot/user-config.py
import csv
with open('C:/Users/User/Dropbox/wikipedia_comments/page_content/congressmembers_pages.txt',encoding="utf-8") as wikipedia_pols:
    reader = csv.reader(wikipedia_pols)
    count = 0
    revsfile = open('C:/Users/User/Dropbox/wikipedia_comments/page_content/pol_revisions.csv','a',newline='',encoding="utf-8")
    f_revs = csv.writer(revsfile)
   # f_revs.writerow(["id","topic","rev_id","timestamp","parent_rev_id","user_id","user_is_anon","user_comment","article_len","article_diff","is_minor"])
    for row in reader:
#        count = count + 1
#        if(count<5):
            try:
                topic=row[0]
                start_date = "2017-01-01T00:00:00Z"
                end_date = "2018-04-01T00:00:00Z"
                print(topic, start_date,end_date)
                site = pywikibot.Site("en", "wikipedia")
                page = pywikibot.Page(site, topic)
                #revs = list(page.loadrevisions())
                revs = list(page.revisions(starttime=end_date,endtime=start_date,content=True))
#                revs = page.revisions(starttime=end_date,endtime=start_date,content=False)#reverse=False, total=None, content=False, rollback=False, starttime=end_date,endtime=start_date)
                prevrevlength = 0
                for rev in revs:
 #                   print(rev)
                    textlength = len(str(rev['text']))
                    textlengthdiff = textlength-prevrevlength
                    prevrevlength=textlength
                    f_revs.writerow([count,str(topic),str(rev['revid']),str(rev['timestamp']),str(rev['_parent_id']),str(rev['user']),str(rev['anon']),str(rev['comment']),textlength,textlengthdiff,str(rev['minor'])])
              #for talk pages: https://stackoverflow.com/questions/54527376/how-to-get-the-content-in-talk-pages-of-wikipedia-in-python
                talkpage = page.toggleTalkPage()
                talkfile = open('C:/Users/User/Dropbox/wikipedia_comments/talk_pages/'+topic+'.txt','w',newline='',encoding="utf-8")
                text = talkpage.get()
                #print(count, str(ob['text']))
                talkfile.write(text)
                talkfile.close()
#                print(text)
            except:
                pass
    revsfile.close()


import tensorflow as tf
import tensorflow.keras as keras
import numpy as np

class LinearDecay(keras.optimizers.schedules.LearningRateSchedule):
    # https://github.com/LynnHo/CycleGAN-Tensorflow-2/blob/master/module.py
    # if `step` < `step_decay`: use fixed learning rate
    # else: linearly decay the learning rate to zero

    def __init__(self, initial_learning_rate, total_steps, step_decay):
        super(LinearDecay, self).__init__()
        self._initial_learning_rate = initial_learning_rate
        self._steps = total_steps
        self._step_decay = step_decay
        self.current_learning_rate = tf.Variable(initial_value=initial_learning_rate, trainable=False, dtype=tf.float32)

    def __call__(self, step):
        self.current_learning_rate.assign(tf.cond(
            step >= self._step_decay,
            true_fn=lambda: self._initial_learning_rate *
                            (1 - 1 / (self._steps - self._step_decay) * (step - self._step_decay)),
            false_fn=lambda: self._initial_learning_rate
        ))
        return self.current_learning_rate

def build_optimizer(optimizer, learning_rate_fn, momentum=0.9):
    if optimizer == 'Adam':
        return keras.optimizers.Adam(learning_rate=learning_rate_fn)
    elif optimizer == 'SGD':
        return keras.optimizers.SGD(learning_rate=learning_rate_fn,
                                    momentum=momentum, nesterov=True)
    else:
        raise NotImplementedError

def build_lr_scheduler(scheduler,
                       steps_per_epoch,
                       n_epochs,
                       lr_start,
                       lr_decay_steps=None,
                       lr_end=None):
    decay_steps = lr_decay_steps if lr_decay_steps is not None else n_epochs * steps_per_epoch
    if scheduler == 'linear':
        lr_end = lr_end if lr_end is not None else 0.
        learning_rate_fn = keras.optimizers.schedules.PolynomialDecay(lr_start,
                                                                      decay_steps,
                                                                      lr_end,
                                                                      power=1.0)
    elif scheduler == 'linear_decay_0.5':
        # Used in CycleGAN
        learning_rate_fn = LinearDecay(lr_start, decay_steps, decay_steps//2)
    elif scheduler == 'constant':
        # assert lr_decay_steps is None and lr_end is None, 'No decay for constant learning rate.'
        learning_rate_fn = lr_start
    elif scheduler == 'cosine':
        learning_rate_fn = keras.experimental.CosineDecay(initial_learning_rate=lr_start,
                                                          decay_steps=decay_steps,
                                                          alpha=0.0)

    elif scheduler == 'piecewise_quarter':
        # Splits decay_steps into 4 equal phases, and reduces learning rate by 10. in each phase
        learning_rate_fn = keras.optimizers.schedules.\
            PiecewiseConstantDecay(boundaries=list(np.linspace(0, decay_steps, 5)[1:-1]),
                                   values=[lr_start / div for div in [1., 10., 100., 1000.]])

    elif scheduler == 'piecewise_custom_1':
        # Splits decay_steps into 3 phases (50%, 25%, 25%) and reduces learning rate by 10. in each phase
        learning_rate_fn = keras.optimizers.schedules.\
            PiecewiseConstantDecay(boundaries=[decay_steps//2, (decay_steps * 3)//4],
                                   values=[lr_start / div for div in [1., 10., 100.]])

    elif scheduler == 'piecewise_cifar10':
        # These are the numbers in the ResNet paper
        learning_rate_fn = keras.optimizers.schedules.PiecewiseConstantDecay(boundaries=[30000, 60000, 90000, 120000],
                                                                             values=[0.1, 0.01, 0.001, 0.0001, 0.00005])
    else:
        raise NotImplementedError

    return learning_rate_fn