# -*- coding: utf-8 -*-
#
# Bounding Box Editor and Exporter (BBoxEE)
# Author: Peter Ersts (ersts@amnh.org)
#
# --------------------------------------------------------------------------
#
# This file is part of Animal Detection Network's (Andenet)
# Bounding Box Editor and Exporter (BBoxEE)
#
# BBoxEE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BBoxEE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software.  If not, see <http://www.gnu.org/licenses/>.
#
# --------------------------------------------------------------------------
import os
import sys
import json
import glob
import pyodbc
import datetime
import numpy as np
from tqdm import tqdm
import tensorflow as tf
from PIL import Image
from PIL.ExifTags import TAGS

for key, value in TAGS.items():
    if value == "ExifOffset":
        break
EXIF_OFFSET = key

def build_label_map(file_name):
    # see if we can use this to eliminated the need for
    # label_map_util dependency
    a = open(file_name, 'r')
    string = a.read()
    a.close()
    lines = string.split("\n")
    parsed = ''
    comma = ''
    for line in lines:
        if line == '':
            pass
        elif line.find('item') != -1:
            parsed += '{'
        elif line.find('}') != -1:
            comma = ''
            parsed += '},'
        else:
            parts = line.replace('\\', '').replace('\'', '"').split(':')
            parsed += '{} "{}":{}'.format(comma, parts[0].lstrip(), parts[1])
            comma = ','

    string = "[{}]".format(parsed[0:-1])
    j = json.loads(string)
    label_map = {}
    for entry in j:
        if 'display_name' in entry:
            label_map[entry['id']] = entry['display_name']
        else:
            label_map[entry['id']] = entry['name']
    return label_map

if 'Microsoft Access Driver (*.mdb, *.accdb)' not in pyodbc.drivers():
    print('No Microsoft Access Driver found.')
    sys.exit(0)

print('----------------------------------------------------------------------------')
print('DO NOT RUN THIS SCRIPT ON YOUR MAIN DATABASE WITHOUT CREATING A BACKUP FIRST!')
print('----------------------------------------------------------------------------')
print()
print()
print('Example database path: c:\\database\\import-test.accdb')
print()
# Ask for database file and open
database = input("Enter the path and file name of your database: ")
try:
    conn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + database)
    cur = conn.cursor()
except pyodbc.Error:
    print('Unable to open database.')
    sys.exit(0)

# Load species list
SPECIES = {}
results = cur.execute('Select SpeciesID, CommonName from Species').fetchall()
for rec in results:
    SPECIES[rec[1].lower()] = rec[0]
if "none" not in SPECIES:
    print('"None" label is missing from the species list')
    sys.exit(0)

# Ask for labelmap file
label_map_file = input('Enter the path and file name of your label map: ')
label_map_file = os.path.abspath(label_map_file)
LABEL_MAP = build_label_map(label_map_file)

# Check species labels match
print('Verifing species names...')
for label in LABEL_MAP:
    if LABEL_MAP[label].lower() not in SPECIES:
        print("Species list in the database does not contain [{}]".format(LABEL_MAP[label]))
        sys.exit(0)
print()

# Ask for the saved model
model_dir = input('Enter the path and file name of your saved model: ')
print('Loading model...')
MODEL = tf.saved_model.load(model_dir)
print()

# Get detection threshold
value = input('Enter the confidence threshold (0.1 to 1.0): ')
THRESHOLD = float(value)
if THRESHOLD == 0.0:
    print('Invalid threshold value.')
    sys.exit(0)

# Ask for image folder
IMAGE_PATH = input('Enter the path and folder name with your images: ')
IMAGE_PATH = os.path.abspath(IMAGE_PATH) + os.sep
print()

# Load observers and ask for ID number
observers = {}
results = cur.execute('Select ObserverID, LastName, FirstName from Observers').fetchall()
print('{:<12}Last, First'.format('ObserverID'))
for rec in results:
    observers[str(rec[0])] = '{}, {}'.format(rec[1], rec[2])
    print('{:<12}{}, {}'.format(*rec))
OBSID = input('Which ObserverID should the data be associated with? ')
if OBSID not in observers:
    print('That ObserverID is not recognized')
    sys.exit(0)
print()

# Load VisitIDs
# en: converted to one SQL statement
visit_id_list = []
results = cur.execute(
    '''select Visits.VisitID,
        StudyAreas.StudyAreaName,  CameraLocations.LocationName,
        Format(Visits.VisitDate, 'short date') As VisitDate,
        lkupVisitTypes.VisitType
    from ((StudyAreas inner join
      CameraLocations on
        StudyAreas.StudyAreaID = CameraLocations.StudyAreaID) inner join
      Visits on
        CameraLocations.LocationID = Visits.LocationID) inner join
      lkupVisitTypes on
        Visits.VisitTypeID = lkupVisitTypes.ID
    where Visits.VisitTypeID < 3
    order by Visits.VisitDate, Visits.VisitID;''').fetchall()
print('{:<12}Description'.format('VisitID'))
for rec in results:
    visit_id_list.append(str(rec[0]))
    print('{:<12}{} - {} - {} ({})'.format(*rec))
VISITID = input('Which VisitID should the data be associated with? ')
if VISITID not in visit_id_list:
    print('That VisitID is not recognized')
    sys.exit(0)

# Get all image files
files = glob.glob(os.path.join(IMAGE_PATH, '*'))
image_format = [".jpg", ".jpeg", ".png"]
f = (lambda x: os.path.splitext(x)[1].lower() in image_format)
image_list = list(filter(f, files))
image_list = [os.path.basename(x) for x in image_list]
image_list = sorted(image_list)

# Import data
counter = 1
active_start = None
active_end = None
for name in tqdm(image_list):
    file_name = os.path.join(IMAGE_PATH, name)
    img = Image.open(file_name)
    image_np = np.array(img)
    exif = img.getexif()
    img.close()
    info = exif.get_ifd(EXIF_OFFSET)
    try:
        created = info[36867]
        timestamp = datetime.datetime.fromisoformat(created.replace(':', '-', 2))
    except KeyError:
        # en: default to date modified in case 36867 (date taken) is unavailable
        #   some makes/firmware versions don't include 36867 in the exif
        timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(file_name))
    # en: added Pending and ObsCount flags
    cur.execute(
        '''INSERT INTO Photos (ImageNum, FileName, ImageDate, FilePath, VisitID, Pending, ObsCount)
        VALUES (?, ?, ?, ?, ?, True, 1 )''', (counter, name, timestamp, IMAGE_PATH, VISITID))
    conn.commit()
    image_rec_id = float(cur.execute('SELECT @@Identity').fetchone()[0])
    # en: retain date of first photo for updating Visits table
    #   uses min/max in case filenames are not in chronological order
    if counter == 1:
        active_start = timestamp
        active_end = timestamp
    else:
        active_start = min(active_start, timestamp)
        active_end = max(active_end, timestamp)
    counter += 1

    # Expand dimensions since the model expects images
    # to have shape: [1, None, None, 3]
    image_np_expanded = np.expand_dims(image_np, axis=0)
    # Actual detection.
    dets = MODEL(image_np_expanded)
    scores = dets['detection_scores'][0].numpy()
    boxes = dets['detection_boxes'][0].numpy()
    classes = dets['detection_classes'][0].numpy()
    detection = False
    detections = {}
    for index, score in enumerate(scores):
        if score >= THRESHOLD:
            detection = True
            bbox = boxes[index]
            xmin = float(bbox[1])
            xmax = float(bbox[3])
            ymin = float(bbox[0])
            ymax = float(bbox[2])
            class_number = int(classes[index])
            label = LABEL_MAP[class_number]
            XLen = xmax - xmin
            YLen = ymax - ymin
            TagX = xmin + (XLen / 2.0)
            TagY = ymin + (YLen / 2.0)
            cur.execute(
                '''INSERT INTO PhotoTags (TagX, TagY, XLen, YLen, ImageID, ObsID)
                VALUES (?, ?, ?, ?, ?, ?)''', (TagX, TagY, XLen, YLen, image_rec_id, OBSID))
            if label not in detections:
                detections[label] = 1.0
            else:
                detections[label] += 1.0

    if detection:
        for d in detections.keys():
            cur.execute(
                '''INSERT INTO Detections (SpeciesID, Individuals, ObsID, ImageID)
                VALUES (?, ?, ?, ?)''', (SPECIES[d.lower()], detections[d], OBSID, image_rec_id))
    else:
        cur.execute(
            '''INSERT INTO Detections (SpeciesID, Individuals, ObsID, ImageID)
            VALUES (?, ?, ?, ?)''', (SPECIES['none'], 1.0, OBSID, image_rec_id))
    # en: update flags in photos table based on detection info
    cur.execute(
        '''UPDATE Photos
        SET MultiSp = ?, NotNone = ?
        WHERE ImageID = ?''', ((len(detections) > 1), detection, image_rec_id))
    conn.commit()

# en: Update active start and end fields
cur.execute('UPDATE Visits SET ActiveStart = ?, ActiveEnd = ? WHERE VisitID = ?', (active_start, active_end, VISITID))
conn.commit()

# en: alternate version - probably less efficient but it avoids extra lines in
#   the for loop
# results = cur.execute('Select Min(ImageDate) As ActiveStart, Max(ImageDate) As ActiveEnd from Visits where VisitID = ?', VISITID).fetchall()
# cur.execute('UPDATE Visits SET ActiveStart = ?, ActiveEnd = ? WHERE VisitID = ?', (results[0], results[1], VISITID))
# conn.commit()

# could be done in a single SQL statement in MS Access using DMin and DMax, but
#   those aren't available via the access ODBC driver


from tqdm import tqdm

import numpy as np
import matplotlib.pyplot as plt

import torch
import torch.nn as nn
from torch.optim import Adam, SGD

from utils.helper import int_R
from utils.data import load_data

def train(times, time_size=50, num_epoch=3000, metric='l2'):
    theta = nn.Parameter(torch.tensor(
        [1.0, 5.0, 1.0, 5.0], dtype=torch.float64))
    scaler = torch.tensor([1e-6, 1000, 1e-2, 1e-3])
    optimizer = Adam([theta], lr=0.02)
    if metric == 'l2':
        criterion = nn.MSELoss()
    else:
        criterion = nn.L1Loss(reduction='sum')
    # choice of criterion:
    # Gaussian: MSELoss
    # Laplacian: L1Loss
    pbar = tqdm(range(num_epoch), dynamic_ncols=True)
    for i in pbar:
        optimizer.zero_grad()
        torch_R = int_R(torch.tensor(yearly_Ds[:, :, -time_size:], dtype=torch.float64),
                        theta * scaler,
                        times[-time_size:],
                        backend='pytorch')
        loss = criterion(torch_R[-27:], truth)
        loss.backward()
        optimizer.step()
        pbar.set_description(
            (
                f'Epoch : {i}; loss: {loss.item()}'
            )
        )
    print('Approximated value of theta: r, t_a, Ds_c, Asigma')
    print((theta * scaler).detach().numpy())
    return torch_R.detach().numpy()

if __name__ == '__main__':
    datapath = 'data/Groningen_Data_Example.hdf5'
    catpath = 'data/catalog2.txt'
    y0, y1, dy = 1956, 2019, 12
    yearly_Ds, yearly_R = load_data(datapath, catpath)

    truth = torch.tensor(yearly_R, dtype=torch.float64)
    time_size = 50
    num_epoch = 3000

    times = np.arange(1956, 2019)
    pred_R = int_R(yearly_Ds[:, :, -time_size:],
                   [5e-6, 8700, 0.17, 0.006], times[-time_size:])
    pred_l2 = train(times, time_size, num_epoch, metric='l2')
    pred_l1 = train(times, time_size, num_epoch, metric='l1')
    line1, = plt.plot(range(1992, 2019), yearly_R, label='Ground truth')
    line2, = plt.plot(times[-time_size:], pred_l2,
                      label='Prediction - L2 distance')
    line3, = plt.plot(times[-time_size:], pred_l1,
                      label='Prediction - L1 distance')
    plt.legend()
    plt.ylabel('Number of cummulative events')
    plt.xlabel('Year')
    plt.title('Gradient-based optimimization methods')
    plt.savefig('figs/final_optim_pred.png', bbox_inches='tight', dpi=400)
    plt.show()


import shutil
import tempfile
from http import HTTPStatus

from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from posts.models import Follow, Group, Post, User

TEMP_MEDIA_ROOT = tempfile.mkdtemp(dir=settings.BASE_DIR)
User = get_user_model()

class PostsBaseTest(TestCase):
    """Базовый класс."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.guest_client = Client()

        cls.user = User.objects.create(username='Anna')
        cls.authorized_client = Client()
        cls.authorized_client.force_login(cls.user)

@override_settings(MEDIA_ROOT=TEMP_MEDIA_ROOT)
class PostPagesTests(TestCase):
    """Класс для проверки соответствия страниц."""

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        shutil.rmtree(TEMP_MEDIA_ROOT, ignore_errors=True)

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create(username='Anna')
        cls.authorized_client = Client()
        cls.authorized_client.force_login(cls.user)

        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test-slug',
            description='Тестовое описание',
        )
        cls.small_gif = (b'\x47\x49\x46\x38\x39\x61\x02\x00'
                         b'\x01\x00\x80\x00\x00\x00\x00\x00'
                         b'\xFF\xFF\xFF\x21\xF9\x04\x00\x00'
                         b'\x00\x00\x00\x2C\x00\x00\x00\x00'
                         b'\x02\x00\x01\x00\x00\x02\x02\x0C'
                         b'\x0A\x00\x3B')

        cls.uploaded = SimpleUploadedFile(
            name='small.gif',
            content=cls.small_gif,
            content_type='posts/'
        )

        cls.post = Post.objects.create(
            author=cls.user,
            text='Тестовый текст',
            group=cls.group,
            image=cls.uploaded)

    def setUp(self):
        self.guest_client = Client()

    def test_pages_uses_correct_template(self):
        """URL-адрес использует соответствующий шаблон."""
        templates_pages_names = {
            reverse('posts:index'): 'posts/index.html',
            reverse('posts:group_list', kwargs={'slug': self.group.slug}
                    ): 'posts/group_list.html',
            reverse('posts:profile', kwargs={'username': self.post.author}
                    ): 'posts/profile.html',
            reverse('posts:post_detail', kwargs={'post_id': self.post.pk}
                    ): 'posts/post_detail.html',
            reverse('posts:post_create'): 'posts/create_post.html',
            reverse('posts:post_edit', kwargs={'post_id': self.post.pk}
                    ): 'posts/create_post.html',
        }
        for reverse_name, template in templates_pages_names.items():
            with self.subTest(reverse_name=reverse_name):
                response = self.authorized_client.get(reverse_name)
                self.assertTemplateUsed(response, template)

    def test_post_detail_show_correct_image(self):
        """На странице post_detal отображается верная картинка."""
        url = reverse('posts:post_detail', kwargs={'post_id': self.post.pk})

        response = self.authorized_client.get(url)

        self.assertEqual(response.context.get('one_post').image,
                         'posts/small.gif')

    def test_pages_show_correct_image(self):
        """
        На страницах Index, group_list, profile отображается верная картинка.
        """
        urls_pages_names = [reverse('posts:index'),
                            reverse('posts:group_list',
                                    kwargs={'slug': self.post.group.slug}),
                            reverse('posts:profile',
                                    kwargs={'username': self.post.author})]
        for url in urls_pages_names:
            response = self.authorized_client.get(url)

            for post in response.context['page_obj'].object_list:
                self.assertEqual(post.image, 'posts/small.gif')

class IndexTestCase(TestCase):
    """Класс для проверки Index.view."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.guest_client = Client()
        cls.user = User.objects.create(username='Anna')

        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test-slug',
            description='Тестовое описание',
        )

    def setUp(self):
        for x in range(13):
            Post.objects.create(text=f'text{x}', author=self.user)
        self.last_post = Post.objects.create(text='last', author=self.user,
                                             group=self.group)
        self.latest_post = Post.objects.latest('id')
        self.url = reverse('posts:index')

    def test_get_success(self):
        r = self.guest_client.get(self.url)

        page_obj = r.context.get('page_obj')

        self.assertEqual(r.status_code, HTTPStatus.OK)
        self.assertEqual(len(page_obj), settings.COUNT_POSTS)

    def test_last_post_in_index(self):
        """Последний пост появляется на главной странице."""
        self.assertEqual(self.latest_post.pk, self.last_post.pk)

class PostEditTestCase(PostsBaseTest):
    """Класс для проверки Post_edit.view."""
    def setUp(self):
        self.post = Post.objects.create(author=self.user, text='text')
        self.url = reverse('posts:post_edit', kwargs={'post_id': self.post.pk})

    def test_get_success(self):
        """Тест позитивного GET-запроса."""
        response = self.authorized_client.get(self.url)

        form = response.context.get('form')

        self.assertEqual(response.status_code, HTTPStatus.OK)
        self.assertEqual(form.instance, self.post)

    def test_auth_get(self):
        """Тест неавторизованного пользователя."""
        response = self.guest_client.get(self.url)

        self.assertEqual(response.status_code, HTTPStatus.FOUND)

    def test_post_success(self):
        """Тест позитивного POST-сценария."""
        new_text = 'new'
        data = dict(
            text=new_text
        )

        response = self.authorized_client.post(self.url, data=data)

        self.assertEqual(response.status_code, HTTPStatus.FOUND)
        self.post.refresh_from_db()
        self.assertEqual(self.post.text, new_text)

    def test_post_auth(self):
        """Проверяем что пост недоступен без авторизации."""
        response = self.guest_client.post(self.url)

        self.assertEqual(response.status_code, HTTPStatus.FOUND)

    def test_post_error(self):
        """Отправляем несуществующую группу."""
        new_text = 'new_text'
        new_group = 'does_not_exist'
        data = dict(
            text=new_text,
            group=new_group,
        )

        response = self.authorized_client.post(self.url, data=data)

        self.assertEqual(response.status_code, HTTPStatus.OK)
        error = response.context.get('form').errors
        self.assertIn('Выберите корректный вариант', str(error))

class GroupListTestCase(TestCase):
    """Класс для проверки Group_post.view."""
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.guest_client = Client()
        cls.user = User.objects.create(username='Anna')

    def setUp(self):
        self.group = Group.objects.create(
            title='Тестовая группа',
            slug='test-slug',
            description='Тестовое описание')

        self.group2 = Group.objects.create(
            title='Тест группа 2',
            slug='test2',
            description='Тестовое описание',
        )
        for x in range(13):
            Post.objects.create(text=f'text{x}', author=self.user,
                                group=self.group)
        self.last_post = Post.objects.create(text='last', author=self.user,
                                             group=self.group)
        self.latest_post = Post.objects.latest('id')

    def test_get_success(self):
        url = reverse('posts:group_list', kwargs={'slug': self.group.slug})

        response = self.guest_client.get(url)

        page_obj = response.context.get('page_obj')

        self.assertEqual(len(page_obj), settings.COUNT_POSTS)
        self.assertEqual(self.group, response.context.get('group'))
        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_last_post_in_group(self):
        """Пост попал в нужную группу."""
        group_list = Post.objects.filter(group=self.latest_post.group)
        group_list2 = Post.objects.filter(group=self.group2)

        self.assertIn(self.last_post, group_list)
        self.assertNotIn(self.last_post, group_list2)

class ProfileTestCase(TestCase):
    """Класс для проверки Profile.view."""
    def setUp(self):
        self.guest_client = Client()

        self.authorized_client = Client()
        self.user = User.objects.create(username='Vadim')
        self.authorized_client.force_login(self.user)
        for x in range(13):
            Post.objects.create(text=f'text{x}', author=self.user)

        self.last_post = Post.objects.create(text='last', author=self.user)
        self.latest_post = Post.objects.latest('id')
        self.url = reverse('posts:profile',
                           kwargs={'username': self.user.username})

    def test_get_success(self):
        post_count = Post.objects.filter(author=self.user).count()

        response = self.guest_client.get(self.url)
        page_obj = response.context.get('page_obj')

        self.assertEqual(len(page_obj), settings.COUNT_POSTS)
        self.assertEqual(post_count, response.context.get('counter_posts'))
        self.assertEqual(self.user, response.context.get('author'))
        self.assertEqual(response.status_code, HTTPStatus.OK)
        self.assertTemplateUsed(response, 'posts/profile.html')

    def test_last_post_in_profile(self):
        """Пост попал в профайл пользователя."""
        profile_list = Post.objects.filter(author=self.latest_post.author)

        self.assertIn(self.last_post, profile_list)

class PostDetailTestCase(TestCase):
    """Класс для проверки Post_detail.view."""
    def setUp(self):
        self.guest_client = Client()
        self.user = User.objects.create(username='Anna')
        self.post = Post.objects.create(text='text', author=self.user)
        for x in range(13):
            Post.objects.create(text=f'text{x}', author=self.user)

    def test_get_success(self):
        url = reverse('posts:post_detail', kwargs={'post_id': self.post.pk})
        count_post = Post.objects.all().count()

        response = self.guest_client.get(url)

        self.assertEqual(count_post, response.context.get('posts_count'))
        self.assertEqual(self.post, response.context.get('one_post'))
        self.assertEqual(response.status_code, HTTPStatus.OK)
        self.assertTemplateUsed(response, 'posts/post_detail.html')

class PostCreateTestCase(PostsBaseTest):
    """Класс для проверки Post_create.view."""
    def setUp(self):
        self.url = reverse('posts:post_create')
        Post.objects.create(author=self.user, text='txt')
        self.group = Group.objects.create(title='test',
                                          slug='test-slug',
                                          description='Тестовое описание',
                                          )

    def test_auth_get(self):
        """Тест неавторизованного пользователя."""
        response = self.guest_client.get(self.url)

        self.assertEqual(response.status_code, HTTPStatus.FOUND)

    def test_post_success(self):
        """Позитивный пост запрос."""
        text = 'rex'
        data = dict(
            text=text,
            group=self.group.id
        )

        response = self.authorized_client.post(self.url, data=data,
                                               follow=True)

        self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_get_success(self):
        response = self.authorized_client.get(self.url)

        form_fields = {
            'text': forms.fields.CharField,
            'group': forms.fields.ChoiceField,
        }
        for value, expected in form_fields.items():
            with self.subTest(value=value):
                form_field = response.context.get('form').fields.get(value)

                self.assertIsInstance(form_field, expected)
                self.assertTemplateUsed(response, 'posts/create_post.html')
                self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_post_error(self):
        """Отправляем пустой текст."""
        new_text = ''
        data = dict(
            text=new_text)

        response = self.authorized_client.post(self.url, data=data)

        self.assertEqual(response.status_code, HTTPStatus.OK)
        error = response.context.get('form').errors
        self.assertIn('Обязательное поле', str(error))

class CacheTestCase(PostsBaseTest):
    """Класс для проверки работоспособности кэширования."""
    def setUp(self):
        self.url = reverse('posts:index')
        self.post = Post.objects.create(author=self.user, text='txt')

    def test_cache_index(self):
        response = self.authorized_client.get(self.url)
        self.post.delete()
        new_response = self.authorized_client.get(self.url)
        self.assertEqual(response.content, new_response.content)
        cache.clear()
        new_response2 = self.authorized_client.get(self.url)
        self.assertNotEqual(response.content, new_response2.content)

class FollowTestCase(TestCase):
    """Класс для проверки сервиса подписок."""

    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        cls.user = User.objects.create(username='Anna')
        cls.authorized_client1 = Client()
        cls.authorized_client1.force_login(cls.user)

        cls.user2 = User.objects.create(username='Vadim')
        cls.authorized_client2 = Client()
        cls.authorized_client2.force_login(cls.user2)

        cls.user3 = User.objects.create(username='Lena')
        cls.authorized_client3 = Client()
        cls.authorized_client3.force_login(cls.user3)

        for x in range(13):
            Post.objects.create(text=f'text{x}', author=cls.user)
            Post.objects.create(text=f'text{x}', author=cls.user2)

    def test_follow_profile(self):
        """Проверка подписки."""
        url = reverse('posts:profile_follow',
                      kwargs={'username': self.user.username})
        count = Follow.objects.count()
        self.authorized_client2.post(url)
        self.assertEqual(count + 1, Follow.objects.count())

    def test_unfollow_profile(self):
        """Проверка отписки."""
        count = Follow.objects.count()
        url = reverse('posts:profile_unfollow',
                      kwargs={'username': self.user.username})
        Follow.objects.create(user=self.user2, author=self.user)
        self.authorized_client2.post(url)

        self.assertEqual(count, Follow.objects.count())

    def test_follow_index(self):
        """Новая запись пользователя появляется в ленте тех,
        кто на него подписан.
        """
        url = reverse('posts:follow_index')
        Follow.objects.create(user=self.user2, author=self.user)
        post = Post.objects.create(text='text', author=self.user)

        response = self.authorized_client2.get(url)

        page_obj = response.context.get('page_obj')

        self.assertEqual(len(page_obj), settings.COUNT_POSTS)
        self.assertIn(post, page_obj.object_list)

    def test_not_follow_index(self):
        """Новая запись пользователя не появляется в ленте тех,
        кто не подписан.
        """
        url = reverse('posts:follow_index')
        post = Post.objects.create(text='text', author=self.user)

        response = self.authorized_client2.get(url)

        self.assertNotIn(post, response.context.get('page_obj').object_list)


#!/usr/bin/env python3
import numpy as np
import time
from fluidlab.daq.daqmx import read_analog
from zaber_motion import Units
from zaber_motion.ascii import Connection
from datetime import datetime
from pynput import keyboard
from pynput.keyboard import Key

def on_press(key):
    if key == keyboard.Key.up:
        try:
            axis.move_relative(+1, Units.LENGTH_MILLIMETRES)
        except:
            pass
    if key == keyboard.Key.down:
        try:
            axis.move_relative(-1, Units.LENGTH_MILLIMETRES)
        except:
            pass
    if key == keyboard.Key.esc:
        listener.stop()

class probe:
    def __init__(self,port,center,top,bot,X,Y):
        """
        port : connection port of the zaber, usually COM7
        center : center poistion of the tank.
        top : top position where you want the probe to start
        bot : bottom position where you want the probe to stop.
        X : X position for a moving prob on X axis. Usufull for radial compoenent.
        Y : Y position for a moving prob on X axis. Usufull for radial compoenent.
        """
        self.port = port
        self.center = center
        self.top = top
        self.bot = bot
        self.X = X
        self.Y = Y

    def centering(self,manual=False):
        """
        Center the prob according to the center value, if not centered, use .centering(manual=True) to do it yourself.
        """
        with Connection.open_serial_port(self.port) as connection:
            device_list = connection.detect_devices()
            print("Found {} devices".format(len(device_list)))
            device = device_list[0]
            axis = device.get_axis(1)
            try:
                axis.move_absolute(self.center, Units.LENGTH_MILLIMETRES)
            except:
                pass
            if manual == True:
                print("Use up and down arrow to move the prob. Press escape to exit.")
                with keyboard.Listener(on_press=on_press) as listener:
                    listener.join()
                self.center = axis.get_position(Units.LENGTH_MILLIMETRES)

    def sauvegarde(self,coils,parameters,Data):
        """
        saving function just to avoid writing it everytime.
        """
        np.savetxt(parameters.path + "_"+datetime.now().strftime("%Y-%m-%d_%H:%M")+".txt",Data,delimiter=",")
        np.save(parameters.path + "_"+datetime.now().strftime("%Y-%m-%d_%H:%M"),Data)
        with open(parameters.path + "_setup_"+datetime.now().strftime("%Y-%m-%d_%H:%M")+".txt", "w") as f:
            f.write("--- Calibration --- \n")
            f.write("Path to data : \n")
            f.write(parameters.path + "_"+datetime.now().strftime("%Y-%m-%d_%H:%M")+".txt \n")
            f.write(parameters.path + "_"+datetime.now().strftime("%Y-%m-%d_%H:%M")+".npy \n")
            f.write("--- Experimental setup ---\n")
            for k in range(len(coils.current)):
                f.write("Z_"+str(k+1)+" = "+str(coils.position[k])+" mm ;I_"+str(k+1)+" = "+str(coils.current[k])+"A \n")
                f.write("Probe position : X = "+str(self.X)+" Y ="+str(self.Y))

    def operate(self,coils,parameters):
        """
        Measure the field in x,y,z directions while moving on z.
        """
        Data = np.zeros((parameters.N,4))
        with Connection.open_serial_port(self) as connection:
            device_list = connection.detect_devices()
            print("Found {} devices".format(len(device_list)))
            device = device_list[0]
            axis = device.get_axis(1)
            try:
                axis.move_absolute(self.top, Units.LENGTH_MILLIMETRES)
            except:
                pass

            while axis.is_busy() == True:
                time.sleep(1)
                print("Waiting for the stage to be in position...")
            print("In position.")
            for k in range(parameters.N):
                print(k/parameters.N)
                Data[k,1], Data[k,2], Data[k,3] = parameters.rng*np.mean(read_analog(("Dev5/ai0", "Dev5/ai1", "Dev5/ai2"),
                    terminal_config="Diff", volt_min=-5, volt_max=5, samples_per_chan=int(parameters.fe*parameters.tau), sample_rate=parameters.fe),axis = 1)
                Data[k,0] = axis.get_position(Units.LENGTH_MILLIMETRES) #in mm
                time.sleep(parameters.tau)
                try:
                    axis.move_relative(-parameters.deltax, Units.LENGTH_MILLIMETRES)
                except:
                    pass
                while axis.is_busy() == True:
                    time.sleep(1)

            if parameters.save == True:
                self.sauvegarde(coils,parameters,Data)

class coils:
    def __init__(self,I,Z):
        """
        I : Array of the currents in the coils
        Z : Array of the positions of the coils
        """
        self.current = I
        self.position = Z

class parameters:
    def __init__(self, tau, fe, range, N, x, save, path):
        """
        tau : Acquisition time
        fe : Acquisition frequency
        range : range of the gaussmeter, in gauss per volt (usually 100 G/V)
        N : Number of point you want
        x : lenght in mm of the area to make measurements.
        save : Boolean, for saving value or not.
        path : path to folder where to save.
        """
        self.tau = tau
        self.fe = fe
        self.rng = range
        self.N = N
        self.x = x
        self.deltax = x/N
        self.save = save
        self.path = path

if __name__ == "__main__":
        prb = probe(port="COM7",
                    center=98,
                    top=250,
                    bot=30,
                    X=068.3,
                    Y=951.3)
        cls = coils(I=np.array([4.0,  0.5,  3.58,     -0.3,   -0.5,   -4.86]),
                    Z=np.array([26.5,   24.5,  12.0,   -12.0,  -24.5,  -26.5]))
        settings = parameters(tau=2,
                              fe=10000,
                              range=300/3,
                              N=100,
                              x=220,
                              save=True,
                              path="C:/Users/Gsu/Desktop/SDT_EXP/calibration"
        )


#!/usr/bin/env python3

def get_data(fname = "data.txt"):
    with open(f"year_2022/day_02/{fname}") as f:
        return [l.strip() for l in f]

me_int = {"X":1,"Y":2,"Z":3}
them_int = {"A":1,"B":2,"C":3}

def main_a(data):
    score = 0
    for game in data:
        them, me = game.split()

        me = me_int[me]
        them = them_int[them]

        score += me

        if me == them:
           score += 3
        elif (them % 3) + 1 == me:
            score += 6

    return score

def main_b(data):
    score = 0
    for game in data:
        them, result = game.split()
        them = them_int[them]
        if result == "Z": #win
            score += 6 + (them%3+1)
        if result == "Y": #draw
            score += 3 + them
        if result == "X": #loss
            score += them-1 if them > 1 else 3
    return score

if __name__ == "__main__":
    data = get_data()
    print(main_a(data))
    data = get_data()
    print(main_b(data))


from typing import Sequence, List, Union, AsyncGenerator

import pytest

from tests import MyTest

class FakeSchedulerMixin(MyTest):
    @pytest.fixture(autouse=True)
    async def FakeScheduler(self, load_pixivbot):
        from nonebot_plugin_pixivbot.global_context import context
        from nonebot_plugin_pixivbot.protocol_dep.post_dest import PostDestination
        from nonebot_plugin_pixivbot.model import PostIdentifier, Subscription, ScheduleType
        from nonebot_plugin_pixivbot.service.scheduler import Scheduler
        from nonebot_plugin_pixivbot.data.utils.shortuuid import gen_code

        @context.bind_singleton_to(Scheduler)
        class FakeScheduler:
            def __init__(self):
                self.subscriptions = {}

            async def schedule(self, type_: ScheduleType,
                               schedule: Union[str, Sequence[int]],
                               args: List[str],
                               post_dest: PostDestination[int, int]):
                from nonebot_plugin_pixivbot.service.scheduler import parse_schedule

                if isinstance(schedule, str):
                    schedule = parse_schedule(schedule)

                kwargs = {}
                for i, arg in enumerate(args):
                    kwargs[str(i)] = arg

                code = gen_code()
                self.subscriptions[code] = Subscription(code=code,
                                                        type=type_,
                                                        schedule=schedule,
                                                        kwargs=kwargs,
                                                        subscriber=post_dest.identifier)

            async def unschedule(self, subscriber: PostIdentifier[int, int], code: int):
                if code in self.subscriptions:
                    del self.subscriptions[code]
                    return True
                else:
                    return False

            async def unschedule_all_by_subscriber(self, subscriber: PostIdentifier[int, int]):
                keys = set()
                for k, v in self.subscriptions.items():
                    if v.subscriber == subscriber:
                        keys.add(k)

                for k in keys:
                    del self.subscriptions[k]

            async def get_by_subscriber(self, subscriber: PostIdentifier[int, int]) \
                    -> AsyncGenerator[Subscription, None]:
                for k, v in self.subscriptions.items():
                    if v.subscriber == subscriber:
                        yield v

        return FakeScheduler


from collections import Counter

def names_from_Tweet(tweets): #splitting Name from the list
	names=[]
	for pref_name in tweets:
		names.append(pref_name.split()[0])
	return names

Test_case=int(input("Enter the Test sample count to take : \n"))
Test_count=0
tweets=[]

while Test_count<Test_case:
	num=int(input("Enter the tweet counts : \n"))
	count=0
	while count<num:
		item=str(input("Enter the name and tweet_id : \n"))
		tweets.append(item)
		count+=1
	Test_count+=1

a=Counter(names_from_Tweet(tweets))
print(a)
value_set=a.values()
print(value_set)

list_1=[]
list_2=[]
for i in set(value_set):
	list_1 = ([(k, v) for k,v in sorted(a.items()) if v == i])

	if len(list_1) > 1:
		for (k, v) in list_1:
			print ("{} {}".format(k,v))

	max_value = max(a.values())

	list_2 = [(k, v) for k, v in sorted(a.items()) if v == max_value]

	if list_2 != list_1:
		for (k,v) in list_2:
			print("{} {}".format(k,v))


from django.urls import path, include
from . import views
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'product', views.ProductViewSet, basename='product')
router.register(r'productitem', views.ProductItemViewSet, basename='productitem')

urlpatterns = [
    path('product/<int:pk>/categories/', views.ProductViewSet.as_view({'get': 'get_categories_of_product'}), name='product-category-list'),
]

urlpatterns += router.urls


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

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        Dict={}
        curr=head

        while curr!=None:
            if Dict.get(curr):
                return True
            else:
                Dict[curr]=1
            curr=curr.next
        return False


import pygame
from animation import Animation, Frame
from time import time

class Character:

  def __init__(self, screen_w, screen_h, unit):
    self.unit = unit
    self.create_animations()
    image_rect = self.animation.get_current_frame().image.get_rect()
    self.center = image_rect.width/2
    self.position = [(screen_w - image_rect.width)/2, screen_h - image_rect.height]
    size_reduction = 10*unit
    self.collision_rect = pygame.Rect(image_rect.left + size_reduction,
      image_rect.top + size_reduction,
      image_rect.width - 2*size_reduction,
      image_rect.height - 4*size_reduction)
    self.screen_w = screen_w
    self.direction = [0, 0]

  def create_animations(self):
    image = pygame.image.load("assets/character.png")

    # create the frames for the "walking left" animation
    frames = [
      Frame(image = image, position = [0, 4*self.unit], duration = 4),
      Frame(image = image, position = [0, 0],           duration = 4),
    ]

    # and with that create the "walking left" animation
    self.animation = Animation(frames)

  def input(self, event):
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_LEFT:
        self.direction[0] = -1
      elif event.key == pygame.K_RIGHT:
        self.direction[0] = 1
    if event.type == pygame.KEYUP:
      if (event.key == pygame.K_LEFT and self.direction[0] == -1) or\
        (event.key == pygame.K_RIGHT and self.direction[0] == 1):
        self.direction[0] = 0

  def update(self):
    if self.direction[0] != 0:
      self.animation.update()
    self.position[0] = (self.position[0] + self.direction[0]*8*self.unit + self.center)\
      %self.screen_w - self.center

  def draw(self, on_surface):
    self.animation.draw(on_surface, self.position)

  def collides_with(self, other):
    return self.get_absolute_rect().colliderect(other.get_absolute_rect())

  def get_absolute_rect(self):
    return self.collision_rect.move(self.position)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Jul  5 17:23:13 2019

@author: annayu
There are n flights, and they are labeled from 1 to n.

We have a list of flight bookings.  The i-th booking bookings[i] = [i, j, k]
means that we booked k seats from flights labeled i to j inclusive.

Return an array answer of length n, representing the number of seats booked
on each flight in order of their label.

Input: bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
Output: [10,55,45,25,25]
"""

bookings = [[1,2,10],[2,3,20],[2,5,25]]
n = 5

class Solution:
    def corpFlightBookings(self, bookings, n):
        a = [0] * n
        for i, j, k in bookings:
            a[i - 1] += k
            if j < n:
                a[j] -= k
        seats = 0
        for i in range(n):
            seats += a[i]
            a[i] = seats
        return a

    # this solution cannot pass time complexity test. Max processing time exceeded
    def corpFlightBookings2(self, bookings, n):
        """
        :type bookings: List[List[int]]
        :type n: int
        :rtype: List[int]
        """
        result = [ 0 for _ in range(n)]

        for booking in bookings:
            result[booking[0]:booking[1]]
            first = booking[0]
            last = booking[1]
            num = booking[2]

            for i in range(first, last+1):
                result[i] += num

        return list(result.values())

S = Solution()
S.corpFlightBookings(bookings,n)


# -*- coding: utf-8 -*-
# @Time    : 2020/4/14 13:58
# @Author  : mandy
import pymysql
import conftest

class OperationMySQL:
    def __init__(self,):
        try:
            self.db = pymysql.connect(**conftest.config)
        except pymysql.Error as e:
            print(r'连接数据库失败|Mysql Error %d : %s' % (e.args[0], e.args[1]))
            conftest.get_logger().exception(e)
        else:
            self.cursor = self.db.cursor()

    def select(self, statement):
        sql = "select * from course"
        try:
            self.cursor.execute(statement)
        except AttributeError as e:
            print(r'SQL执行失败|Error : %s' % (e.args[0]))
            conftest.get_logger().exception(e)
        else:
            row_one = self.cursor.fetchone()
            rows = self.cursor.fetchall()
            # print(r'查询的单行数据为：%s' % str(row_one))
            self.close()
            return row_one

    def insert(self, statement):
        sql = "select * from course"
        effect_row = self.cursor.execute(statement)
        self.db.commit()  # 提交数据
        print(effect_row)
        row_one = self.cursor.fetchone()
        print(row_one)
        self.close()

    def update(self, statement):
        sql = "select * from course"
        effect_row = self.cursor.execute(statement)
        self.db.commit()  # 提交数据
        print(effect_row)
        row_one = self.cursor.fetchone()
        print(row_one)
        self.close()

    def delete_one_by_id(self, id, table_name):
        stmt = "DELETE FROM " + table_name + " WHERE id= " + id
        effect_row = self.cursor.execute(stmt)
        self.db.commit()  # 提交数据
        print(effect_row)
        self.close()

    def close(self):
        self.cursor.close()
        self.db.close()

if __name__ == '__main__':
    op = OperationMySQL()
    op.select()


import numpy as np
from numpy import ndarray
from Operation import Operation
from ParamOperation import ParamOperation
from Loss import Loss
from MeanSquaredErrorLoss import MeanSquaredError
from SigmoidOperation import Sigmoid
from WeightMultiplyOperation import WeightMultiply
from BiasAddOperation import BiasAdd

class NeuralNetwork(object):
    def __init__(self,input: ndarray, target: ndarray, operationsData: ndarray, loss: Loss) -> None:
        self.operationsData = operationsData
        self.lossOperation = loss
        self.input = input
        self.target = target
        self.param_grads = np.empty([1,1])
        super().__init__()

    def _forward(self) -> ndarray:
        #This function calculates the output of the model by calculating
        #the output of all of its constituent operations
        for operationData in self.operationsData:
            if(self._isParamOperation(operationData['operation'] == False)):
                self.input = operationData['operation']._forward(self.input)
                self.output = self.input
            else:
                self.input = operationData['operation']._forward(self.input, operationData['param'])
                self.output = self.input

        self.loss = self.lossOperation._forward(self.output,self.target)
        return self.output

    def _backward(self) -> ndarray:
        #This function calculates the gradient of the model by first calculating the loss_gradient
        #and then working back through the model and calculating the input gradient, alongside the param gradient for each of its operations
        #multiplying them at each step
        loss_grad = self.lossOperation._backward()

        for operationData in self.operationsData:

            if(operationData != self.operationsData[0]):
                if(self._isParamOperation(operationData['operation']) == False):
                    self.input_grad = operationData['operation']._backward(self.input_grad,operationData['param'])
                else:
                    self.input_grad = operationData['operation']._backward(self.input_grad)
                    operationData['param_grad'] = operationData['operation']._param_grad(self.input_grad)

            if(operationData == self.operationsData[0]):
                if(self._isParamOperation(operationData['operation']) == False):
                    self.input_grad == operationData['operation']._backward(loss_grad,operationData['param'])
                else:
                    self.input_grad = operationData['operation']._backward(loss_grad,operationData['param'])
                    operationData['param_grad'] = operationData['operation']._param_grad(loss_grad)

        return self.operationsData

    def _isParamOperation(self, operation: Operation) -> bool:
        #This function simply checks if a given operation is a parameter operation or not
        if issubclass(operation.__class__, ParamOperation):
            return True
        return False


import os
import sys
import threading
import time

import psutil
from PyQt5 import QtCore, QtWidgets, uic, QtGui
from PyQt5.QtCore import QUrl, QCoreApplication, QDateTime
from PyQt5.QtGui import QIcon, QDesktopServices, QPixmap
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QAction, QLabel, QMainWindow, QMessageBox

from gui.ui_main import Ui_MainWindow

# 适配高分屏
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)

class MainWindow(Ui_MainWindow, QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.icon_type = 'mario'

        self.ui = uic.loadUi("gui/ui_main.ui", self)
        self.ui.setupUi(self)
        self.ui.setWindowTitle("思源笔记git")

        self.logAction = QAction("日志", self)
        self.logAction.setIcon(QIcon.fromTheme("document-new"))
        self.aboutAction = QAction("关于", self)
        self.aboutAction.setIcon(QIcon.fromTheme("help-about"))
        self.openAction = QAction("打开", self)
        self.openAction.setIcon(QIcon.fromTheme("media-record"))
        self.quitAction = QAction("退出", self)
        self.quitAction.setIcon(QIcon.fromTheme("application-exit"))  # 从系统主题获取图标

        self.trayIconMenu = QMenu(self)
        self.trayIconMenu.addAction(self.aboutAction)
        self.trayIconMenu.addAction(self.logAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.openAction)
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = TrayIcon(self)
        # self.trayIcon.setContextMenu(self.trayIconMenu)
        self.icon_list = self.loadIcon()
        self.trayIcon.setIcon(self.icon_list[0])
        self.trayIcon.setToolTip("思源笔记git助手")
        # 左键双击打开主界面
        self.trayIcon.activated[QtWidgets.QSystemTrayIcon.ActivationReason].connect(self.openApp)
        self.trayIcon.show()

        self.initWidget()
        self.initConnect()
        self.initLog()

    def initWidget(self):
        # 居中
        desktop = QApplication.desktop()
        current_screen = desktop.screenNumber(self)  # 获取程序所在屏幕是第几个屏幕
        rect = desktop.screenGeometry(current_screen)  # 获取程序所在屏幕的尺寸
        self.move(int((rect.width() - self.width()) / 2), int((rect.height() - self.height()) / 2))

    def initConnect(self):
        self.quitAction.triggered.connect(self.quitApp)
        self.openAction.triggered.connect(self.openApp)
        self.aboutAction.triggered.connect(self.showAbout)
        self.logAction.triggered.connect(self.openLog)
        self.btnConnect.clicked.connect(self.showConnect)
        self.btnPower.clicked.connect(self.showPower)
        self.btnLogin.clicked.connect(self.showLogin)

    def initLog(self):
        currentDateTime = QDateTime.currentDateTime()
        time = currentDateTime.toString("yyyy/MM/dd HH:mm:ss")
        f = open("./log.txt", "a")
        f.write(time)
        f.close()

    def quitApp(self):
        QCoreApplication.quit()

    def openApp(self, reason):
        """
        双击任务栏时或显式调用方法时主窗口变为活动状态，防止右键任务栏图标也打开主界面
        :param reason:
        :return:
        """
        if reason == QtWidgets.QSystemTrayIcon.ActivationReason.DoubleClick or reason == False:
            self.ui.showNormal()
            self.ui.activateWindow()

    def showAbout(self):
        msg = QMessageBox(self)
        msg.setWindowTitle("关于")
        msg.setText("git helper for siyuan note\n \nCopyright © 2020-2020 JUN. \nAll Rights Reserved. ")
        msg.setIconPixmap(QPixmap(":/icon/icon.png"))
        msg.addButton("确定", QMessageBox.ActionRole)
        msg.exec()

    def openLog(self):
        QDesktopServices.openUrl(QUrl("./log.txt"))

    def closeEvent(self, event):
        """

        :param event:
        :return:
        """

    def showConnect(self):
        self.showMessage("连接", "已经连接机械手")

    def showPower(self):
        self.showMessage("上电", "机械手已上电")

    def showLogin(self):
        self.showMessage("权限", "切换权限USER1")

    def showMessage(self, title, content):
        self.trayIcon.showMessage(title, content, QSystemTrayIcon.Information, 1000)

    # 加载图标
    def loadIcon(self):
        if self.icon_type == 'mario':
            return [QIcon(f'icons/{self.icon_type}/{i}.png') for i in range(3)]
        return [QIcon(f'icons/{self.icon_type}/{i}.png') for i in range(5)]

class TrayIcon(QSystemTrayIcon):
    def __init__(self, parent=None):
        super(TrayIcon, self).__init__(parent)
        self.monitor = 'cpu'
        self.cpu_usage = 0.2  # 初始化
        self.mem_usage = 0.2  # 初始化
        self.gpu_usage = 0.2  # 初始化

        self.icon_type = 'runcat'  # 设定默认图标，并加载
        self.icon_list = self.loadIcon()
        self.setIcon(self.icon_list[0])

        self.setVisible(True)
        self.setMenu()  # 加载菜单
        self.updateIcon()  # 更新图标

    # 加载图标
    def loadIcon(self):
        if self.icon_type == 'mario':
            return [QIcon(f'icons/{self.icon_type}/{i}.png') for i in range(3)]
        return [QIcon(f'icons/{self.icon_type}/{i}.png') for i in range(5)]

    # 设置菜单
    def setMenu(self):
        self.menu = QMenu()
        self.action_1 = QAction(QIcon(f'icons/cat.png'),
                                'Cat', self, triggered=lambda: self.changeIconType('runcat'))
        self.action_2 = QAction(QIcon(f'icons/mario/0.png'),
                                'Mario', self, triggered=lambda: self.changeIconType('mario'))

        self.action_c = QAction(QIcon(f'icons/cpu.png'),
                                'CPU', self, triggered=lambda: self.changeMonitor('cpu'))
        self.action_m = QAction(QIcon(f'icons/mem.png'),
                                'Memory', self, triggered=lambda: self.changeMonitor('mem'))
        self.action_g = QAction(QIcon(f'icons/gpu.png'),
                                'GPU', self, triggered=lambda: self.changeMonitor('gpu'))

        self.action_q = QAction(QIcon(f'icons/quit.png'),
                                'Quit', self, triggered=self.quit)

        self.action_push = QAction(QIcon(f'icons/quit.png'),"push",self, triggered=self.push)

        self.action_pull = QAction(QIcon(f'icons/quit.png'),"pull",self, triggered=self.push)

        self.menu.addAction(self.action_pull)
        self.menu.addAction(self.action_c)
        self.menu.addAction(self.action_m)
        self.menu.addAction(self.action_g)
        self.menu.addSeparator()
        self.menu.addAction(self.action_1)
        self.menu.addAction(self.action_2)
        self.menu.addSeparator()
        self.menu.addAction(self.action_push)
        self.menu.addAction(self.action_q)
        self.setContextMenu(self.menu)

    # 根据使用率更新图标，
    # 创建两个 threading：一个获取使用率，一个更新图标
    def updateIcon(self):
        threading.Timer(0.1, self.thread_get_cpu_usage, []).start()
        threading.Timer(0.1, self.thread_update_icon, []).start()

    # get cpu usage
    def thread_get_cpu_usage(self):
        while True:
            self.cpu_usage = psutil.cpu_percent(interval=1) / 100
            self.mem_usage = psutil.virtual_memory().percent / 100
            # print(self.cpu_usage)
            time.sleep(0.5)

    # update icon
    def thread_update_icon(self):
        while True:
            mon = self.cpu_usage
            if self.monitor == 'mem':
                mon = self.mem_usage
            elif self.monitor == 'gpu':
                mon = self.gpu_usage

            t = 0.18 - mon * 0.15
            # print(mon, t)
            for i in self.icon_list:
                self.setIcon(i)
                tip = f'cpu: {self.cpu_usage:.2%} \nmem: {self.mem_usage:.2%} \ngpu: {self.gpu_usage:.2%}'
                self.setToolTip(tip)
                # print(i, self.cpu_usage)
                time.sleep(t)

    # Change icon type
    def changeIconType(self, type):
        print(type)
        if type != self.icon_type:
            self.icon_type = type
            self.icon_list = self.loadIcon()
            print(f'Load {self.icon_type}({len(self.icon_list)}) icons...')

    # change monitor type
    def changeMonitor(self, monitor_type):
        print(monitor_type)
        if monitor_type != self.monitor:
            self.monitor = monitor_type

    def windowsMessage(self):
        """
        配置显示 windows 系统消息通知
        :return:
        """
        print("example")
        if self.trayIcon.supportsMessages() == True and self.trayIcon.isSystemTrayAvailable() == True:
            self.trayIcon.showMessage("title", "message", QtGui.QIcon("../amber_logo.ico"), 10000)
        else:
            print("ERROR: windowsMessage()")

    def push(self):
        """git push

        :return:
        """

    def pull(self):
        """git pull

        :return:
        """

    # 退出程序
    def quit(self):
        self.setVisible(False)
        app.quit()
        os._exit(-1)  # 完全退出程序

if __name__ == "__main__":
    # 创建活跃 app 句柄
    app = QApplication(sys.argv)
    # 关闭全部窗口后程序不退出
    QApplication.setQuitOnLastWindowClosed(False)  # 关闭最后一个窗口不退出程序
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


def prime_generator(allprimes=[2,3], maxvalue=-1, maxprimenum=-1):
	"""Return primes, using a list of at least [2,3] as a starting point."""
	nextnum = 5
	yield 2
	yield 3
	i = 1

	while True:
		if maxprimenum > 0 and maxprimenum < allprimes[i]: break
		if maxvalue > 0 and maxvalue < i: break
		yield allprimes[i]
		allprimes.append(get_next_prime(allprimes))
		i = i + 1

def get_next_prime(allprimes):
	"""Find next prime number, assuming primes is a comprehensive list of sorted prime numbers up to a certain range."""
	import math
	found = -1
	nextnum = allprimes[-1]
	while found < 0:
		nextnum = nextnum + 2
		s = int(math.sqrt(nextnum))
		factored = False
		for prime in allprimes:
			if nextnum % prime == 0:
				factored = True
				break
			if prime > s:
				break
		if not factored:
			found = nextnum
	return found

def generate_primes_up_to(val, allprimes=[2,3]):
	"""Generates primes to >= val.  Returns list of generated primes.

	generate_primes_up_to(int[,list]) -> list

	"""
	if len(allprimes) > 1 and allprimes[-2] > val:
		stop = len(allprimes) - 1
		while stop >= 0 and allprimes[stop] > val:
			stop -= 1
		return allprimes[:stop+1]
	else:
		for p in prime_generator(allprimes):
			if allprimes[-1] >= val:
				break
		return allprimes[:-1]


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sbn
from sklearn.preprocessing import StandardScaler

"""
Pre-process the user_logs dataset
"""

filename = 'data\\user_logs.csv'
new_filename = "processed_data\processed_user_logs_new.csv"
new_filename_for_test = "processed_data\processed_user_logs_test.csv"
trainfile = 'data\\train.csv'
testfile = 'data\\sample_submission_zero.csv'

def readData():
    print("Reading User_log...")
    df_train = pd.read_csv(trainfile)
    train = pd.DataFrame(df_train['msno'])

    user_data = pd.DataFrame()
    for chunk in pd.read_csv(filename, chunksize=500000):
        merged = train.merge(chunk, on='msno', how='inner')
        user_data = pd.concat([user_data, merged])

    print(str(len(train['msno'].unique())) + 'unique members in Train')
    print(str(len(user_data['msno'].unique())) + "users have additional information")

    del train
    return user_data

def readDataForTest():
    print("Reading User_log...")
    df_test = pd.read_csv(testfile)
    test = pd.DataFrame(df_test['msno'])

    user_data = pd.DataFrame()
    for chunk in pd.read_csv(filename, chunksize=500000):
        merged = test.merge(chunk, on='msno', how='inner')
        user_data = pd.concat([user_data, merged])

    print(str(len(test['msno'].unique())) + 'unique members in Test')
    print(str(len(user_data['msno'].unique())) + "users have additional information")

    del test
    return user_data

def preprocessUserLogs(user_data):
    print("Started Preprocessing...")
    print(user_data.head())

    # checking number of outliers
    for col in user_data.columns[1:]:
        outliers = user_data['msno'][user_data[col]<0].count()
        print(str(outliers)+" outliers in " + col)

    # deleting column date
    del user_data['date']

    # checking correlation heatmap
    corrmat = user_data[user_data.columns[1:]].corr()
    f, ax = plt.subplots(figsize=(12,9))
    sbn.heatmap(corrmat, vmax=1, cbar=True, annot=True, square=True)
    plt.show()

    # Heavily correlated columns num_75, num_50 = 0.95
    # num_unq, num_100 = 0.92
    # Removing one column from each pair
    del user_data['num_75']
    del user_data['num_unq']

    # removing outliers from 'total_secs'
    user_data = user_data[user_data['total_secs'] >= 0]
    # print (user_data['msno'][user_data['total_secs'] < 0].count())

    # Grouping data by member id and summing up the columns corresponding to each member
    counts = user_data.groupby('msno')['total_secs'].count().reset_index()
    counts.columns = ['msno', 'days_listened']
    sums = user_data.groupby('msno').sum().reset_index()
    user_data = sums.merge(counts, how='inner', on='msno')

    # Updated shape of data
    # print (str(np.shape(user_data)) + " -- New size of data matches unique member count")

    # print(user_data.head())

    cols = user_data.columns[1:]

    # getting natural log of the data to make its distribution normal
    log_user_data = user_data.copy()
    log_user_data[cols] = np.log1p(user_data[cols])

    ss = StandardScaler()
    # Normalize (mean=0, std = 1)
    log_user_data[cols] = ss.fit_transform(log_user_data[cols])

    # check distribution of data, before and after normalization
    '''
    for col in cols:
        plt.figure(figsize=(15,7))
        plt.subplot(1,2,1)
        sbn.distplot(user_data[col].dropna())
        plt.subplot(1,2,2)
        sbn.distplot(log_user_data[col].dropna())
        plt.figure()
    '''
    return log_user_data

def getProcessedDataForTrain():
    user_log = pd.read_csv(new_filename)
    return user_log

def getProcessedDataForTest():
    user_log = pd.read_csv(new_filename_for_test)
    return user_log

def getUserLogForTrain():
    # Take the users that appear in both user_log data and Train file
    user_data = readData()
    df = preprocessUserLogs(user_data)
    df.to_csv(new_filename)

def getUserLogForTest():
    # Take the users that appear in both user_log data and Test file
    user_data = readDataForTest()
    df = preprocessUserLogs(user_data)
    df.to_csv(new_filename_for_test)

if __name__ == '__main__':
    getUserLogForTrain()
    getUserLogForTest()

Project (Churn Prediction)/Source Code/Preprocessing_user_logs.py


'''
알파벳 대문자와 숫자(0~9)로만 구성된 문자열이 입력으로 주어집니다.
이때 모든 알파벳을 오름차순으로 정렬하여 이어서 출력한 뒤에, 그 뒤에 모든 숫자를 더한 값을 이어서 출력

< 아이디어 >
1차원 배열을 두 개 만들어 이어서 각 배열을 오름차순 정렬 join을 이용하여 문자열을 합침
'''

import sys

input = sys.stdin.readline

number = []
alpha = []

data = input().rstrip()
len = len(data)

for i in range(len):
    if data[i].isdigit():
        number.append(data[i])
    else:
        alpha.append(data[i])

alpha.sort()

sum = 0
for j in number:
    sum += int(j)

print("".join(alpha)+str(sum))

이코테 기출문제/Q8_문자열 재정렬.py

Q8_문자열 재정렬.py


import requests, json
from pymongo import MongoClient

client = MongoClient()
database = client['cf_project']
users = database['users']
userRepos = database['userRepos']

response = None
globalCounter = 0

for document in users.find():
	count = 0
	print(document['repos_url'])
	response = requests.get(document['repos_url'] + "?page=1&per_page=100&client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX&client_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
	lastPage = 0
	if( globalCounter % 100 == 0 ):
		print("Ratelimit Left : {0}").format(response.headers.get("x-ratelimit-remaining", None))
		if( response.headers.get("x-ratelimit-remaining", None) == '0' ):
			print("Ratelimit reached!!!!")
			break
	while(response.ok):
		link = response.headers.get('link', None)
		if( link is not None ):
			values = link.split(",")
			if( 'rel="last"' in values[1] ):
				lastPage = int(values[1].split("?")[1].split("&")[0][5:])
		item = json.loads(response.text or response.content)
		for repo in item:
			repo['user_id'] = document['id']
			userRepos.update(repo, repo, upsert = True)
		if( link is not None and count < lastPage ):
			count += 1
			link = link.split(">")[0][1:]
			linkVal = link.split("?")
			newLink = linkVal[0] + "?" + linkVal[1].split("&")[0][:5] + str(count) + "&" + linkVal[1].split("&")[1] + "&" + linkVal[1].split("&")[2] + "&" + linkVal[1].split("&")[3]
			response = requests.get(newLink)
		else:
			break
	print(globalCounter)
	globalCounter += 1


from cpuinfo import get_cpu_info
import psutil
import time
import subprocess
import re
import os
import pandas as pd
import numpy as np
import warnings
import platform
from pkg_resources import resource_stream

CONSTANT_CONSUMPTION = 100.1
FROM_WATTs_TO_kWATTh = 1000*3600
NUM_CALCULATION = 200
CPU_TABLE_NAME = resource_stream('eco2ai', 'data/cpu_names.csv').name

class NoCPUinTableWarning(Warning):
    pass

class NoNeededLibrary(Warning):
    pass

class CPU():
    """
        This class is the interface for tracking CPU power consumption.
        All methods are done here on the assumption that all cpu devices are of equal model.
        The CPU class is not intended for separate usage, outside the Tracker class

    """
    def __init__(self, cpu_processes="current", ignore_warnings=False):
        """
            This class method initializes CPU object.
            Creates fields of class object. All the fields are private variables

            Parameters
            ----------
            cpu_processes: str
                if cpu_processes == "current", then calculates CPU utilization percent only for the current running process
                if cpu_processes == "all", then calculates full CPU utilization percent(sum of all running processes)
            ignore_warnings: bool
                If true, then user will be notified of all the warnings. If False, there won't be any warnings.

            Returns
            -------
            CPU: CPU
                Object of class CPU with specified parameters

        """
        self._ignore_warnings = ignore_warnings
        self._cpu_processes = cpu_processes
        self._cpu_dict = get_cpu_info()
        self._name = self._cpu_dict["brand_raw"]
        self._tdp = find_tdp_value(self._name, CPU_TABLE_NAME, self._ignore_warnings)
        self._consumption = 0
        self._cpu_num = number_of_cpu(self._ignore_warnings)
        self._start = time.time()
        self._operating_system = platform.system()

    def tdp(self):
        """
            This class method returns TDP value of process.

            Parameters
            ----------
            No parameters

            Returns
            -------
            self._tdp : float
                TDP value of the CPU

        """
        return self._tdp

    def set_consumption_zero(self):
        """
            This class method sets CPU consumtion to zero.

            Parameters
            ----------
            No parameters

            Returns
            -------
            No returns

        """
        self._consumption = 0

    def get_consumption(self):
        """
            This class method returns CPU power consupmtion amount.

            Parameters
            ----------
            No parameters

            Returns
            -------
            self._consumption: float
                CPU power consumption

        """
        self.calculate_consumption()
        return self._consumption

    def get_cpu_percent(self,):
        """
            This class method calculates CPU utilization
            taking into acount only python processes.
            Method of calculating CPU utilization depends on operating system:
            Windows, MacOS or Linux are only supported operating systems

            Parameters
            ----------
            No parameters

            Returns
            -------
            cpu_percent: float
                cpu utilization fraction. 'cpu_percent' in [0, 1].
                The current cpu utilization from python processes

        """
        os_dict = {
            'Linux': get_cpu_percent_linux,
            'Windows': get_cpu_percent_windows,
            'Darwin': get_cpu_percent_mac_os
        }
        cpu_percent = os_dict[self._operating_system](self._cpu_processes)
        return cpu_percent

    def calculate_consumption(self):
        """
            This class method calculates CPU power consumption.

            Parameters
            ----------
            No parameters

            Returns
            -------
            consumption: float
                CPU power consumption

        """
        time_period = time.time() - self._start
        self._start = time.time()
        consumption = self._tdp * self.get_cpu_percent() * self._cpu_num * time_period / FROM_WATTs_TO_kWATTh
        if consumption < 0:
            consumption = 0
        self._consumption += consumption
        return consumption

    def name(self,):
        return self._name

    def cpu_num(self,):
        return self._cpu_num

def all_available_cpu():
    """
        This function prints all seeable CPU devices
        All the CPU devices are intended to be of the same model

        Parameters
        ----------
        No parameters

        Returns
        -------
        No returns

    """
    try:
        cpu_dict = get_cpu_info()
        string = f"""Seeable cpu device(s):
        {cpu_dict["brand_raw"]}: {number_of_cpu()} device(s)"""
        print(string)
    except:
        print("There is no any available cpu device(s)")

def number_of_cpu(ignore_warnings=True):
    """
        This function returns number of CPU sockets(physical CPU processors)
        If the body of the function runs with error, number of available cpu devices will be set to 1

        Parameters
        ----------
        ignore_warnings: bool
            If true, then user will be notified of all the warnings. If False, there won't be any warnings.
            The default is True.

        Returns
        -------
        cpu_num: int
            Number of CPU sockets(physical CPU processors)

    """
    operating_system = platform.system()
    cpu_num = None

    if operating_system == "Linux":
        try:
            # running terminal command, getting output
            string = os.popen("lscpu")
            output = string.read()
            output
            # dictionary creation
            dictionary = dict()
            for i in output.split('\n'):
                tmp = i.split(':')
                if len(tmp) == 2:
                    dictionary[tmp[0]] = tmp[1]
            cpu_num = min(int(dictionary["Socket(s)"]), int(dictionary["NUMA node(s)"]))
        except:
            if not ignore_warnings:
                warnings.warn(
                    message="\nYou probably should have installed 'util-linux' to deretmine cpu number correctly\nFor now, number of cpu devices is set to 1\n\n",
                    category=NoNeededLibrary
                    )
            cpu_num = 1
    elif operating_system == "Windows":
        try:
            # running cmd command, getting output
            string = os.popen("systeminfo")
            output = string.read()
            output
            # dictionary creation
            dictionary = dict()
            for i in output.split('\n'):
                tmp = i.split(':')
                if len(tmp) == 2:
                    dictionary[tmp[0]] = tmp[1]
            processor_string = 'something'
            if 'Processor(s)' in dictionary:
                processor_string = dictionary['Processor(s)']
            if 'Џа®жҐбб®а(л)' in dictionary:
                processor_string = dictionary['Џа®жҐбб®а(л)']
            if 'Процессор(ы)' in dictionary:
                processor_string = dictionary['Процессор(ы)']
            cpu_num = int(re.findall('- (\d)\.', processor_string)[0])
        except:
            if not ignore_warnings:
                warnings.warn(
                    message="\nIt's impossible to deretmine cpu number correctly\nFor now, number of cpu devices is set to 1\n\n",
                    category=NoNeededLibrary
                    )
            cpu_num = 1
    elif operating_system == "Darwin":
        # try:
        #     # running terminal command, getting output
        #     string = os.popen("sysctl -a| sort | grep cpu")
        #     output = string.read()
        #     output
        #     # dictionary creation
        #     dictionary = dict()
        #     for i in output.split('\n'):
        #         tmp = i.split(':')
        #         if len(tmp) == 2:
        #             dictionary[tmp[0]] = tmp[1]
        #     processor_string = 'something'
        #     if 'hw.cpu64bit_capable' in dictionary:
        #         processor_string = dictionary['hw.cpu64bit_capable']
        #     else:
        #         pass
        #     cpu_num = int(re.findall('(\d)', processor_string)[0])
        # except:
        #     if not ignore_warnings:
        #         warnings.warn(
        #             message="\nIt's impossible to deretmine cpu number correctly\nFor now, number of cpu devices is set to 1\n\n",
        #             category=NoNeededLibrary
        #             )
        cpu_num = 1
    else:
        cpu_num = 1
    return cpu_num

def transform_cpu_name(cpu_name):
    """
        This function drops all the waste tokens, and words from a cpu name
        It finds patterns. Patterns include processor's family and
        some certain specifications like 9400F in Intel Core i5-9400F

        Parameters
        ----------
        cpu_name: str
            A string, containing CPU name, taken from psutil library

        Returns
        -------
        cpu_name: str
            Modified CPU name, containing patterns only
        patterns: list of str
            Array with all the patterns

    """
    # dropping all the waste tokens and patterns:
    cpu_name = re.sub('(\(R\))|(®)|(™)|(\(TM\))|(@.*)|(\S*GHz\S*)|(\[.*\])|( \d-Core)|(\(.*\))', '', cpu_name)

    # dropping all the waste words:
    array = re.split(" ", cpu_name)
    for i in array[::-1]:
        if ("CPU" in i) or ("Processor" in i) or (i == ''):
            array.remove(i)
    cpu_name = " ".join(array)
    patterns = re.findall("(\S*\d+\S*)", cpu_name)
    for i in re.findall(
        "(Ryzen Threadripper)|(Ryzen)|(EPYC)|(Athlon)|(Xeon Gold)|(Xeon Bronze)|(Xeon Silver)|(Xeon Platinum)|(Xeon)|(Core)|(Celeron)|(Atom)|(Pentium)",
        cpu_name
        ):
        patterns += i
    patterns = list(set(patterns))
    if '' in patterns:
        patterns.remove('')
    return cpu_name, patterns

def get_patterns(cpu_name):
    """
        This function finds patterns. Patterns include processor's family and
        some certain specifications like 9400F in Intel Core i5-9400F
        Returns modified cpu name with patterns

        Parameters
        ----------
        cpu_name: str
            A string, containing CPU name, taken from psutil library

        Returns
        -------
        patterns: list of strings
            Array with all the patterns

    """
    patterns = re.findall("(\S*\d+\S*)", cpu_name)
    for i in re.findall(
        "(Ryzen Threadripper)|(Ryzen)|(EPYC)|(Athlon)|(Xeon Gold)|(Xeon Bronze)|(Xeon Silver)|(Xeon Platinum)|(Xeon)|(Core)|(Celeron)|(Atom)|(Pentium)",
        cpu_name
        ):
        patterns += i
    patterns = list(set(patterns))
    if '' in patterns:
        patterns.remove('')
    return patterns

def find_max_tdp(elements):
    """
        This function finds and returns element with maximum TDP

        Parameters
        ----------
        elements: list
            Array of arrays of two strings.
            Where the first one is CPU name and the second one is CPU TDP

        Returns
        -------
        max_value: float
            The maximum TDP value

    """
    # finds and returns element with maximum TDP
    if len(elements) == 1:
        return float(elements[0][1])

    max_value = 0
    for index in range(len(elements)):
        if float(elements[index][1]) > max_value:
            max_value = float(elements[index][1])
    return max_value

# searching cpu name in cpu table
def find_tdp_value(cpu_name, f_table_name, constant_value=CONSTANT_CONSUMPTION, ignore_warnings=True):
    """
        This function finds and returns TDP of user CPU device.

        Parameters
        ----------
        cpu_name: str
            Name of user CPU device, taken from psutil library

        f_table_name: str
            A file name of CPU TDP values Database

        constant_value: constant_value
            The value, that is assigned to CPU TDP if
            user CPU device is not found in CPU TDP database
            The default is CONSTANT_CONSUMPTION(a global value, initialized in the beginning of the file)

        ignore_warnings: bool
            If true, then user will be notified of all the warnings. If False, there won't be any warnings.
            The default is True.

        Returns
        -------
        CPU TDP: float
            TDP of user CPU device

    """
    # firstly, we try to find transformed cpu name in the cpu table:
    f_table = pd.read_csv(f_table_name)
    cpu_name, patterns = transform_cpu_name(cpu_name)
    f_table = f_table[["Model", "TDP"]].values
    suitable_elements = f_table[f_table[:, 0] == cpu_name]
    if suitable_elements.shape[0] > 0:
        # if there are more than one suitable elements, return one with maximum TDP value
        return find_max_tdp(suitable_elements)
    # secondly, if needed element isn't found in the table,
    # then we try to find patterns in cpu names and return suitable values:
    # if there is no any patterns in cpu name, we simply return constant consumption value
    if len(patterns) == 0:
        if not ignore_warnings:
            warnings.warn(
                message="\n\nYour CPU device is not found in our database\nCPU TDP is set to constant value 100\n",
                category=NoCPUinTableWarning
                )
        return constant_value
    # appending to array all suitable for at least one of the patterns elements
    suitable_elements = []
    for element in f_table:
        flag = 0
        tmp_patterns = get_patterns(element[0])
        for pattern in patterns:
            if pattern in tmp_patterns:
                flag += 1
        if flag:
            # suitable_elements.append(element)
            suitable_elements.append((element, flag))

    # if there is only one suitable element, we return this element.
    # If there is no suitable elements, we return constant value
    # If there are more than one element, we check existence of elements suitable for all the patterns simultaneously.
    # If there are such elements(one or more), we return the value with maximum TDP among them.
    # If there is no, we return the value with maximum TDP among all the suitable elements
    if len(suitable_elements) == 0:
        if not ignore_warnings:
            warnings.warn(
                message="\n\nYour CPU device is not found in our database\nCPU TDP is set to constant value 100\n",
                category=NoCPUinTableWarning
                )
        return CONSTANT_CONSUMPTION
    elif len(suitable_elements) == 1:
        return float(suitable_elements[0][0][1])
    else:
        suitable_elements.sort(key=lambda x: x[1], reverse=True)
        max_coincidence = suitable_elements[0][1]

        tmp_elements = []
        for element in suitable_elements:
            if element[1] == max_coincidence:
                tmp_elements.append(element[0])
        return find_max_tdp(tmp_elements)

def get_cpu_percent_mac_os(cpu_processes="current"):
    """
        This function calculates CPU utilization on MacOS.

        Parameters
        ----------
        cpu_processes: str
            if cpu_processes == "current", then calculates CPU utilization percent only for the current running process
            if cpu_processes == "all", then calculates full CPU utilization percent(sum of all running processes)

        Returns
        -------
        cpu_percent: float
            CPU utilization fraction. 'cpu_percent' is in [0, 1].

    """
    if cpu_processes == "current":
        strings = os.popen('top -stats "command,cpu,pgrp" -l 2| grep -E "(python)|(%CPU)"').read().split('\n')
        strings.pop()
        # number of cpu cores
        cpu_num = psutil.cpu_count()
        current_pid = os.getpid()
        cpu_percent = 0
        strings = strings[int(len(strings) / 2) + 1:]
        for index in range(len(strings)):
            if int(strings[index].split()[-1]) == current_pid:
                cpu_percent = float(strings[index].split()[1]) / cpu_num
                break
    elif cpu_processes == "all":
        strings = os.popen('top -stats "command,cpu,pgrp" -l 2| grep -E "(CPU usage:)"').read().split("\n")
        strings.pop()
        strings = strings[-1].split()
        cpu_percent = float(strings[2][:-1]) + float(strings[4][:-1])
    return cpu_percent / 100

def get_cpu_percent_linux(cpu_processes="current"):
    """
        This function calculates CPU utilization on Linux.

        Parameters
        ----------
        cpu_processes: str
            if cpu_processes == "current", then calculates CPU utilization percent only for the current running process
            if cpu_processes == "all", then calculates full CPU utilization percent(sum of all running processes)

        Returns
        -------
        cpu_percent: float
            CPU utilization fraction. 'cpu_percent' is in [0, 1].

    """
    # number of cpu cores
    if cpu_processes == "current":
        pid = os.getpid()
        # execute the top command with the pid filter
        output = subprocess.run(["top", "-b", "-n1", "-p", str(pid)], capture_output=True, text=True)
    elif cpu_processes == "all":
        # execute the top command with the grep command to filter the output
        output = subprocess.run(["top", "-b", "-n1"], capture_output=True, text=True)
    else:
        raise ValueError(f"'cpu_processes' parameter can be only 'current' or 'all', now it is '{cpu_processes}'")
    cpu_num = psutil.cpu_count()
    # check if the output is empty
    if not output.stdout:
        return 0
    else:
        # split the output into lines
        lines = output.stdout.split('\n')
        # display(lines)
        # variable to store the sum of all process CPU usage
        sum_cpu = 0
        # flag to check if we are at the processes section
        process_section = False
        # iterate through the lines
        for line in lines:
            # check if we are at the processes section
            if 'PID' in line:
                process_section = True
            elif process_section:
                # check if we reached the end of the processes section
                if not line:
                    break
                # split the line into words
                words = line.split()
                # check if the line contains a process
                if len(words) > 0:
                    # the CPU usage percentage is the 8th word
                    sum_cpu += float(words[8].replace(',','.'))
    return sum_cpu / (cpu_num * 100)

def get_cpu_percent_windows(cpu_processes="current"):
    """
        This function calculates CPU utilization on Windows.

        Parameters
        ----------
        cpu_processes: str
            if cpu_processes == "current", then calculates CPU utilization percent only for the current running process
            if cpu_processes == "all", then calculates full CPU utilization percent(sum of all running processes)

        Returns
        -------
        cpu_percent: float
            CPU utilization fraction. 'cpu_percent' is in [0, 1].

    """
    cpu_percent = 0
    if cpu_processes == "current":
        current_pid = os.getpid()
        sum_all = 0
        #Iterate over the all running processes
        for proc in psutil.process_iter():
            try:
                pinfo = proc.as_dict(attrs=['name', 'cpu_percent', 'pid'])
            # Check if process pid equals to the current one.
                if pinfo['cpu_percent'] is not None:
                    sum_all += pinfo['cpu_percent']
                    if pinfo['pid'] == current_pid:
                        cpu_percent = pinfo['cpu_percent']
            except (psutil.NoSuchProcess, psutil.AccessDenied , psutil.ZombieProcess) :
                pass
        if sum_all != 0:
            cpu_percent /= sum_all
        else:
            cpu_percent = 0
    elif cpu_processes == "all":
        cpu_percent = psutil.cpu_percent()/100
    return cpu_percent


import streamlit as st

import functions as f

import params.files as p

import params.lists as l

####################### Interface ##########################
# [] Título
# [] Formulário que contenha a uma input_text
# [] Botão de salvar
# [] Lista de atividades
############################################################

activities_df = f.load_or_create_df(p.activities_csv, l.activities_columns)

with st.container():
    st.title("Lista de Atividades")

with st.container():
    with st.form(key="Nova Atividade", clear_on_submit=True):
        new_activity_name = st.text_input(label="Nova Atividade")
        new_activity_values = [new_activity_name.strip()]
        new_activity_submmited = st.form_submit_button(label="Salvar", use_container_width=True)
        if new_activity_submmited:
            f.new_row_to_csv(p.activities_csv, activities_df, l.activities_columns, new_activity_values)
            st.rerun()

with st.container():
    st.table(activities_df)


the_count = [1, 2, 3, 4, 5]
fruits = ['apples', 'oranges', 'pears', 'apricots']
change = [1, 'pennies', 2, 'dimes', 3, 'quarters']

# this firt kind of loop goes through a list
for number in the_count:
    print(f"This is count {number}")

# same is this one
for fruit in fruits:
    print(f"The fruit is {fruit}")

# also we can go through mixed list too
# notice we have to use {} since we don't know what it is
for i in change:
    print(f"I got {i}")

# we can also build lists. First initialize it:
elements = []

# then use the range function
for i in range(0,6):
    print(f"Adding {i} to list")
    # append is a function that lists can understand
    elements.append(i)

# now we can print it out
for i in elements:
    print(f"Element is {i}")

myelements = range(0, 6)

for i in myelements:
    print(f"New element is {i}")


from itertools import product

def calc(s, opes) -> int:
    ret = []
    now = S[0]
    for i in range(len(opes)):
        if opes[i]:
            ret.append(now)
            now = S[i + 1]
        else:
           now += S[i + 1]
    if now:
        ret.append(now)

    return sum(map(int, ret))

S = input()

ans = 0
for opes in product([False, True], repeat=len(S) - 1):
    ans += calc(S, opes)

print(ans)


import os
import glob
import shutil
import subprocess
from openpyxl import *
from copy import copy
del open
path = os.getcwd()
combining_path = path + "/combining/"
os.chdir(combining_path)
from combining import combining
from combining import catcher
os.chdir(path)
import recode_finder as rf

tmp = os.getcwd()
if os.name == "nt":
    sep = "\\"
    pre = "python3"
else:
    sep = "/"
    pre = "py"
input_path = path + "/INPUT/"
output_path = path + "/OUTPUT/"
combined_file = glob.glob(os.path.join(input_path, "*.xlsx"))[0].split(sep)[-1]
os.chdir(output_path)

wb = load_workbook("reconciling.xlsx")
wb2 = load_workbook(combined_file)
for i in range(0, 2):
    if i == 0:
        col = "E"
        cols = ["E", "F", "G"]
    else:
        col = "I"
        cols = ["I", "J", "K"]
    # finds the B's and S's in the combined file
    sheet2 = wb2.worksheets[i]
    coder = sheet2.title
    locations = {}
    trial_num = 1
    for j in range(1, sheet2.max_row+1):
        cell = sheet2["A" + str(j)]
        if cell.value == "B":
            locations[trial_num] = {}
            locations[trial_num]["B"] = j
        if cell.value == "S":
            try:
                locations[trial_num]["S"] = j
            except:
                print("ERROR: There's probably missing B in " + coder)
                exit(1)
            trial_num += 1
    # handles the reconciling file
    for sheet in wb:
        trial = int(sheet.title.split()[1])
        coder = sheet[col+"1"].value
        b_loc = locations[trial]["B"]
        s_loc = locations[trial]["S"]
        old_length = s_loc - b_loc + 1
        index = 1
        while sheet[col+str(index)].value:
            index += 1
        new_length = index-2
        diff = new_length - old_length
        if diff < 0:
            wb2[coder].delete_rows(b_loc, -diff)
        if diff > 0:
            wb2[coder].insert_rows(b_loc, diff)
        for key in locations:
            if key > trial:
                locations[key]["B"] += diff
                locations[key]["S"] += diff
        index = 2
        for j in range(b_loc, b_loc + new_length):
            for k in [["A", 0], ["B", 1], ["C", 2]]:
                wb2[coder][k[0]+str(j)].value = sheet[cols[k[1]]+str(index)].value
                wb2[coder][k[0]+str(j)].fill = copy(sheet[cols[k[1]]+str(index)].fill)
                wb2[coder][k[0]+str(j)].font = copy(sheet[cols[k[1]]+str(index)].font)
            index += 1
    wb2.save(combined_file)

print("Data added successfully")

# run the combining
shutil.copyfile(combined_file, combining_path + "/input/" + combined_file)
os.chdir(combining_path)
catcher.main
combining.main()
os.chdir(combining_path + "/input/")
shutil.copyfile(combined_file, output_path + combined_file)

# check for bad trials
path = tmp
os.chdir(path)
rf.main(combined_file)


import os
from flask import Blueprint, jsonify, request
from flask_login import login_required, current_user
import requests
from .aws_s3 import upload_file_to_s3, get_unique_filename, ALLOWED_EXTENSIONS, remove_file_from_s3

from app.models import db, Review, ReviewImage, Vote

review_routes = Blueprint('reviews', __name__)

# ------------------------ GET REVIEW BY ID ------------------------
@review_routes.route('/<int:review_id>', methods=['GET'])
@login_required
def get_review(review_id):
    review = Review.query.get(review_id)
    if not review:
        return jsonify({'error': 'Review not found'}), 404

    return jsonify(review.to_dict()), 200

# ------------------------ EDIT REVIEW ------------------------
@review_routes.route('/<int:review_id>', methods=['PUT'])
@login_required
def edit_review(review_id):
    review = Review.query.get(review_id)
    if review:
        if review.user_id != current_user.id:
            return jsonify({'error': 'You are not authorized to edit this review'}), 403

        description = request.form.get('description', review.description)
        wifi = request.form.get('wifi', review.wifi)
        if wifi == '':
            wifi = review.wifi

        pet_friendliness = request.form.get('pet_friendliness', review.pet_friendliness)
        if pet_friendliness == '':
            pet_friendliness = review.pet_friendliness

        noise_level = request.form.get('noise_level', review.noise_level)
        if noise_level == '':
            noise_level = review.noise_level

        review.description = description
        review.wifi = wifi
        review.pet_friendliness = pet_friendliness
        review.noise_level = noise_level

        db.session.commit()

        return jsonify(review.to_dict()), 200

    return jsonify({'error': 'Review not found'}), 404

# ------------------------ DELETE REVIEW ------------------------
@review_routes.route('/<int:review_id>', methods=['DELETE'])
@login_required
def delete_review(review_id):
    review = Review.query.get(review_id)
    if review:
        if review.user_id != current_user.id:
            return jsonify({'error': 'You are not authorized to delete this review'}), 403

        db.session.delete(review)
        db.session.commit()
        return jsonify({'message': 'Review deleted successfully'}), 200

    return jsonify({'error': 'Review not found'}), 404

# ------------------------ ADD REVIEW IMAGES ------------------------
@review_routes.route('/<int:review_id>/images', methods=['POST'])
@login_required
def add_review_images(review_id):
    review = Review.query.get(review_id)
    if not review:
        return jsonify({'error': 'Review not found'}), 404

    if review.user_id != current_user.id:
        return jsonify({'error': 'You are not authorized to add images to this review'}), 403

    images = request.files.getlist('images')
    if not images:
        return jsonify({'error': 'No images provided'}), 400

    if len(images) > 3:
        return jsonify({'error': 'You can only upload a maximum of 3 images'}), 400

    uploaded_image_urls = []
    for image in images:
        if image and '.' in image.filename:
            extension = image.filename.rsplit('.', 1)[1].lower()
            if extension not in ALLOWED_EXTENSIONS:
                return jsonify({'error': 'Invalid file extension. Only images with extensions: {} are allowed.'.format(', '.join(ALLOWED_EXTENSIONS))}), 400

            image.filename = get_unique_filename(image.filename)
            upload = upload_file_to_s3(image)
            print(upload)

            if 'url' in upload:
                uploaded_image_urls.append(upload['url'])
            else:
                return {'errors': [upload]}, 400
        else:
            return jsonify({'error': 'Invalid file'}), 400

    review_images = []
    for image_url in uploaded_image_urls:
        review_image = ReviewImage(url=image_url, review_id=review.id)
        db.session.add(review_image)
        review_images.append(review_image)

    db.session.commit()
    return jsonify({image.id : image.to_dict() for image in review_images}), 200

# ------------------------ ADD VOTE TO REVIEW ------------------------
@review_routes.route('/<int:review_id>/votes', methods=['POST'])
@login_required
def add_review_vote(review_id):

    vote_type = request.json.get('vote_type')

    review = Review.query.get(review_id)
    if not review:
        return jsonify({'error': 'Review not found'}), 404

    if review.user_id == current_user.id:
        return jsonify({'error': 'You cannot vote for your own review'}), 403

    if vote_type not in [-1, 1]:
        return jsonify({'error': 'Invalid vote type. Vote type should be either 1 or -1'}), 400

    # Check if the user has already voted for this review
    existing_vote = Vote.query.filter_by(user_id=current_user.id, review_id=review.id).first()
    if existing_vote:
        return jsonify({'error': 'You have already voted for this review'}), 400

    # Create a new vote
    vote = Vote(user_id=current_user.id, review_id=review.id, vote_type=vote_type)
    db.session.add(vote)
    db.session.commit()

    return vote.to_dict(), 201


def tinhluong(giolam, luonggio):
    tongluong = giolam * luonggio
    return tongluong

def inthongtin(ten, giolam, luonggio, tongluong):
    print("Thông tin nhân viên:")
    print("Tên:", ten)
    print("Số giờ làm:", giolam)
    print("Mức lương giờ:", luonggio)
    print("Tổng tiền lương:", tongluong)

# Nhập thông tin từ người dùng
ten = input("Nhập tên nhân viên: ")
giolam = float(input("Nhập số giờ làm: "))
luonggio = float(input("Nhập mức lương giờ: "))

# Tính tổng tiền lương
tongluong = tinhluong(giolam, luonggio)

# In thông tin nhân viên
inthongtin(ten, giolam, luonggio, tongluong)


# Convert Jupyter notebook into a Python script that will execute all of your scraping code and return one Python dictionary
# Next, create a route called /scrape that will import your scrape_mars.py script and call your scrape function.
# Store the return value in Mongo as a Python dictionary.
# Create a root route / that will query your Mongo database and pass the mars data into an HTML template to display the data.
# Create a template HTML file called index.html that will take the mars data dictionary and display all of the data in the appropriate HTML elements.

from flask import Flask, render_template, redirect
from flask_pymongo import PyMongo
import scrape_mars

app = Flask(__name__)

# Use flask_pymongo to set up mongo connection
app.config["MONGO_URI"] = "mongodb://localhost:27017/mars_app"
mongo = PyMongo(app)

# Route to render index.html template using data from Mongo
@app.route("/")
def index():
    # Find one record of data from the mongo database
    mars= mongo.db.mars.find_one()

    # Return template and data
    return render_template("index.html", mars=mars)

# Create a route called /scrape that will import your scrape_mars.py script and call your scrape function
@app.route("/scrape")
def scrape():
    mars=mongo.db.mars
    # Run the scrape function
    mars_data= scrape_mars.scrape_info()

    # Return value in Mongo as a Python dictionary
    mars.update({}, mars_data, upsert=True)

    return redirect('/')

if __name__ == "__main__":
    app.run(port=5001)